From 552658f967936c64aad067c8654fcdbf1203ed98 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 16 Mar 2018 00:19:49 -0700 Subject: [PATCH 001/378] Variant of clangd fuzzy matcher --- src/fuzzy_match.cc | 194 +++++++++++++++---------------- src/fuzzy_match.h | 34 ++++-- src/messages/workspace_symbol.cc | 11 +- 3 files changed, 122 insertions(+), 117 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index bda1a6883..fbd67dc85 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -1,120 +1,116 @@ #include "fuzzy_match.h" #include -#include #include -// Penalty of dropping a leading character in str -constexpr int kLeadingGapScore = -4; -// Penalty of dropping a non-leading character in str -constexpr int kGapScore = -5; -// Bonus of aligning with an initial character of a word in pattern. Must be -// greater than 1 -constexpr int kPatternStartMultiplier = 2; +enum FuzzyMatcher::CharClass : int { Other, Lower, Upper }; +enum FuzzyMatcher::CharRole : int { None, Tail, Head }; -constexpr int kWordStartScore = 50; -constexpr int kNonWordScore = 40; -constexpr int kCaseMatchScore = 2; - -// Less than kWordStartScore -constexpr int kConsecutiveScore = kWordStartScore + kGapScore; -// Slightly less than kConsecutiveScore -constexpr int kCamelScore = kWordStartScore + kGapScore - 1; - -enum class CharClass { Lower, Upper, Digit, NonWord }; - -static CharClass GetCharClass(int c) { +namespace { +FuzzyMatcher::CharClass GetCharClass(int c) { if (islower(c)) - return CharClass::Lower; + return Lower; if (isupper(c)) - return CharClass::Upper; - if (isdigit(c)) - return CharClass::Digit; - return CharClass::NonWord; + return Upper; + return Other; } -static int GetScoreFor(CharClass prev, CharClass curr) { - if (prev == CharClass::NonWord && curr != CharClass::NonWord) - return kWordStartScore; - if ((prev == CharClass::Lower && curr == CharClass::Upper) || - (prev != CharClass::Digit && curr == CharClass::Digit)) - return kCamelScore; - if (curr == CharClass::NonWord) - return kNonWordScore; - return 0; +void CalculateRoles(std::string_view s, + FuzzyMatcher::CharRole roles[], + int* class_set) { + if (s.empty()) { + *class_set = 0; + return; + } + FuzzyMatcher::CharClass pre = Other, cur = GetCharClass(s[0]), suc; + *class_set = 1 << cur; + auto fn = [&]() { + if (cur == Other) + return None; + // U(U)L is Head while U(U)U is Tail + return pre == Other || (cur == Upper && (pre == Lower || suc != Upper)) + ? Head + : Tail; + }; + for (size_t i = 0; i < s.size() - 1; i++) { + suc = GetCharClass(s[i + 1]); + *class_set |= 1 << suc; + roles[i] = fn(); + pre = cur; + cur = suc; + } + roles[s.size() - 1] = fn(); +} } -/* -fuzzyEvaluate implements a global sequence alignment algorithm to find the -maximum accumulated score by aligning `pattern` to `str`. It applies when -`pattern` is a subsequence of `str`. +int FuzzyMatcher::MissScore(int j, bool last) { + int s = last ? -20 : 0; + if (text_role[j] == Head) + s -= 10; + return s; +} -Scoring criteria -- Prefer matches at the start of a word, or the start of subwords in -CamelCase/camelCase/camel123 words. See kWordStartScore/kCamelScore -- Non-word characters matter. See kNonWordScore -- The first characters of words of `pattern` receive bonus because they usually -have more significance than the rest. See kPatternStartMultiplier -- Superfluous characters in `str` will reduce the score (gap penalty). See -kGapScore -- Prefer early occurrence of the first character. See kLeadingGapScore/kGapScore +int FuzzyMatcher::MatchScore(int i, int j, bool last) { + int s = 40; + if ((pat[i] == text[j] && ((pat_set & 1 << Upper) || i == j))) + s += 20; + if (pat_role[i] == Head && text_role[j] == Head) + s += 50; + if (text_role[j] == Tail && i && !last) + s -= 50; + if (pat_role[i] == Head && text_role[j] == Tail) + s -= 30; + if (i == 0 && text_role[j] == Tail) + s -= 70; + return s; +} -The recurrence of the dynamic programming: -dp[i][j]: maximum accumulated score by aligning pattern[0..i] to str[0..j] -dp[0][j] = leading_gap_penalty(0, j) + score[j] -dp[i][j] = max(dp[i-1][j-1] + CONSECUTIVE_SCORE, max(dp[i-1][k] + -gap_penalty(k+1, j) + score[j] : k < j)) -The first dimension can be suppressed since we do not need a matching scheme, -which reduces the space complexity from O(N*M) to O(M) -*/ -int FuzzyEvaluate(std::string_view pattern, - std::string_view str, - std::vector& score, - std::vector& dp) { - bool pfirst = true, // aligning the first character of pattern - pstart = true; // whether we are aligning the start of a word in pattern - int uleft = 0, // value of the upper left cell - ulefts = 0, // maximum value of uleft and cells on the left - left, lefts; // similar to uleft/ulefts, but for the next row +FuzzyMatcher::FuzzyMatcher(std::string_view pattern) { + CalculateRoles(pattern, pat_role, &pat_set); + size_t n = 0; + for (size_t i = 0; i < pattern.size(); i++) + if (pattern[i] != ' ') { + pat += pattern[i]; + low_pat[n] = ::tolower(pattern[i]); + pat_role[n] = pat_role[i]; + n++; + } +} - // Calculate position score for each character in str. - CharClass prev = CharClass::NonWord; - for (int i = 0; i < int(str.size()); i++) { - CharClass cur = GetCharClass(str[i]); - score[i] = GetScoreFor(prev, cur); - prev = cur; +int FuzzyMatcher::Match(std::string_view text) { + int n = int(text.size()); + if (n > kMaxText) + return kMinScore + 1; + this->text = text; + for (int i = 0; i < n; i++) + low_text[i] = ::tolower(text[i]); + CalculateRoles(text, text_role, &text_set); + dp[0][0][0] = 0; + dp[0][0][1] = kMinScore; + for (int j = 0; j < n; j++) { + dp[0][j + 1][0] = dp[0][j][0] + MissScore(j, false); + dp[0][j + 1][1] = kMinScore; } - std::fill_n(dp.begin(), str.size(), kMinScore); - - // Align each character of pattern. - for (unsigned char pc : pattern) { - if (isspace(pc)) { - pstart = true; - continue; - } - lefts = kMinScore; - // Enumerate the character in str to be aligned with pc. - for (int i = 0; i < int(str.size()); i++) { - left = dp[i]; - lefts = std::max(lefts + kGapScore, left); - // Use lower() if case-insensitive - if (tolower(pc) == tolower(str[i])) { - int t = score[i] * (pstart ? kPatternStartMultiplier : 1); - dp[i] = (pfirst ? kLeadingGapScore * i + t - : std::max(uleft + kConsecutiveScore, ulefts + t)) + - (pc == str[i] ? kCaseMatchScore : 0); - } else - dp[i] = kMinScore; - uleft = left; - ulefts = lefts; + for (int i = 0; i < int(pat.size()); i++) { + int(*pre)[2] = dp[i & 1]; + int(*cur)[2] = dp[i + 1 & 1]; + cur[0][0] = cur[0][1] = kMinScore; + for (int j = 0; j < n; j++) { + cur[j + 1][0] = std::max(cur[j][0] + MissScore(j, false), + cur[j][1] + MissScore(j, true)); + if (low_pat[i] != low_text[j]) + cur[j + 1][1] = kMinScore; + else { + cur[j + 1][1] = std::max(pre[j][0] + MatchScore(i, j, false), + pre[j][1] + MatchScore(i, j, true)); + } } - pfirst = pstart = false; } // Enumerate the end position of the match in str. Each removed trailing - // character has a penulty of kGapScore. - lefts = kMinScore; - for (int i = 0; i < int(str.size()); i++) - lefts = std::max(lefts + kGapScore, dp[i]); - return lefts; + // character has a penulty. + int ret = kMinScore; + for (int j = 1; j <= n; j++) + ret = std::max(ret, dp[pat.size() & 1][j][1] - 3 * (n - j)); + return ret; } diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 3e38a5a76..26bb59ee7 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -3,15 +3,29 @@ #include #include -#include -// Negative but far from INT_MIN so that intermediate results are hard to -// overflow -constexpr int kMinScore = INT_MIN / 2; +class FuzzyMatcher { +public: + constexpr static int kMaxPat = 100; + constexpr static int kMaxText = 200; + // Negative but far from INT_MIN so that intermediate results are hard to + // overflow. + constexpr static int kMinScore = INT_MIN / 2; -// Evaluate the score matching |pattern| against |str|, the larger the better. -// |score| and |dp| must be at least as long as |str|. -int FuzzyEvaluate(std::string_view pattern, - std::string_view str, - std::vector& score, - std::vector& dp); + FuzzyMatcher(std::string_view pattern); + int Match(std::string_view text); + + enum CharClass : int; + enum CharRole : int; + +private: + std::string pat; + std::string_view text; + int pat_set, text_set; + char low_pat[kMaxPat], low_text[kMaxText]; + CharRole pat_role[kMaxPat], text_role[kMaxText]; + int dp[2][kMaxText + 1][2]; + + int MatchScore(int i, int j, bool last); + int MissScore(int j, bool last); +}; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 0f66e7c17..f6a00f27e 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -122,21 +122,16 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { } } - if (config->workspaceSymbol.sort) { + if (config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { // Sort results with a fuzzy matching algorithm. int longest = 0; for (int i : result_indices) longest = std::max(longest, int(db->GetSymbolDetailedName(i).size())); - - std::vector score(longest); // score for each position - std::vector dp( - longest); // dp[i]: maximum value by aligning pattern to str[0..i] + FuzzyMatcher fuzzy(query); std::vector> 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), - i}; + fuzzy.Match(db->GetSymbolDetailedName(result_indices[i])), i}; } std::sort(permutation.begin(), permutation.end(), std::greater>()); From 4e8d21e30610800883282f2a006ebc8edb3151fc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 16 Mar 2018 08:28:37 -0700 Subject: [PATCH 002/378] Fix g++ build --- src/fuzzy_match.cc | 21 +++++++++++---------- src/fuzzy_match.h | 6 ++---- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index fbd67dc85..269b2a942 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -3,11 +3,11 @@ #include #include -enum FuzzyMatcher::CharClass : int { Other, Lower, Upper }; -enum FuzzyMatcher::CharRole : int { None, Tail, Head }; +enum CharClass { Other, Lower, Upper }; +enum CharRole { None, Tail, Head }; namespace { -FuzzyMatcher::CharClass GetCharClass(int c) { +CharClass GetCharClass(int c) { if (islower(c)) return Lower; if (isupper(c)) @@ -15,14 +15,12 @@ FuzzyMatcher::CharClass GetCharClass(int c) { return Other; } -void CalculateRoles(std::string_view s, - FuzzyMatcher::CharRole roles[], - int* class_set) { +void CalculateRoles(std::string_view s, int roles[], int* class_set) { if (s.empty()) { *class_set = 0; return; } - FuzzyMatcher::CharClass pre = Other, cur = GetCharClass(s[0]), suc; + CharClass pre = Other, cur = GetCharClass(s[0]), suc; *class_set = 1 << cur; auto fn = [&]() { if (cur == Other) @@ -52,8 +50,11 @@ int FuzzyMatcher::MissScore(int j, bool last) { int FuzzyMatcher::MatchScore(int i, int j, bool last) { int s = 40; - if ((pat[i] == text[j] && ((pat_set & 1 << Upper) || i == j))) - s += 20; + if (pat[i] == text[j]) { + s++; + if ((pat_set & 1 << Upper) || i == j) + s += 20; + } if (pat_role[i] == Head && text_role[j] == Head) s += 50; if (text_role[j] == Tail && i && !last) @@ -93,7 +94,7 @@ int FuzzyMatcher::Match(std::string_view text) { } for (int i = 0; i < int(pat.size()); i++) { int(*pre)[2] = dp[i & 1]; - int(*cur)[2] = dp[i + 1 & 1]; + int(*cur)[2] = dp[(i + 1) & 1]; cur[0][0] = cur[0][1] = kMinScore; for (int j = 0; j < n; j++) { cur[j + 1][0] = std::max(cur[j][0] + MissScore(j, false), diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 26bb59ee7..a3b5191ce 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -3,6 +3,7 @@ #include #include +#include class FuzzyMatcher { public: @@ -15,15 +16,12 @@ class FuzzyMatcher { FuzzyMatcher(std::string_view pattern); int Match(std::string_view text); - enum CharClass : int; - enum CharRole : int; - private: std::string pat; std::string_view text; int pat_set, text_set; char low_pat[kMaxPat], low_text[kMaxText]; - CharRole pat_role[kMaxPat], text_role[kMaxText]; + int pat_role[kMaxPat], text_role[kMaxText]; int dp[2][kMaxText + 1][2]; int MatchScore(int i, int j, bool last); From 1d6c718bae2c4ebefe1fe81f473a9e1215315ac7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 17 Mar 2018 10:04:12 -0700 Subject: [PATCH 003/378] Fix skipped region in clang 6.0.0; add repology badge; remove -latomic --- README.md | 17 ++++++++++------- src/clang_indexer.cc | 2 ++ wscript | 1 - 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 22648ec2e..2aca86c1b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# cquery - [![Join the chat at https://gitter.im/cquery-project/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cquery-project/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# cquery + cquery is a highly-scalable, low-latency language server for C/C++/Objective-C. It is tested and designed for large code bases like [Chromium](https://chromium.googlesource.com/chromium/src/). cquery provides @@ -14,14 +14,13 @@ some extra features to boot: * code completion (with both signature help and snippets) * finding definition/references - * type hierarchy (parent type, derived types, expandable tree view) - * finding base/derived methods/classes, call tree + * call (caller/callee) hierarchy, inheritance (base/derived) hierarchy, member hierarchy * symbol rename - * document and global symbol search - * hover tooltips showing symbol type + * [document symbols](src/messages/text_document_document_symbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) + * [hover information](src/messages/text_document_hover.cc) * diagnostics * code actions (clang FixIts) - * darken/fade code disabled by preprocessor + * preprocessor skipped regions * #include auto-complete, undefined type include insertion, include quick-jump (goto definition, document links) * auto-implement functions without a definition @@ -29,6 +28,10 @@ some extra features to boot: # >>> [Getting started](https://github.com/jacobdufault/cquery/wiki/Getting-started) (CLICK HERE) <<< + + Packaging status + + # Limitations cquery is able to respond to queries quickly because it caches a huge amount of diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index df82f2426..e4596639b 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -361,9 +361,11 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { CXSourceRangeList* skipped = clang_getSkippedRanges(param->tu->cx_tu, file); for (unsigned i = 0; i < skipped->count; ++i) { Range range = ResolveCXSourceRange(skipped->ranges[i]); +#if CINDEX_VERSION < 45 // Before clang 6.0.0 // clang_getSkippedRanges reports start one token after the '#', move it // back so it starts at the '#' range.start.column -= 1; +#endif db->skipped_by_preprocessor.push_back(range); } clang_disposeSourceRangeList(skipped); diff --git a/wscript b/wscript index fa6c0f761..9be6c600b 100644 --- a/wscript +++ b/wscript @@ -339,7 +339,6 @@ def build(bld): if sys.platform.startswith('linux'): # For __atomic_* when lock free instructions are unavailable # (either through hardware or OS support) - lib.append('atomic') lib.append('pthread') # loguru calls dladdr lib.append('dl') From 38f71952800d3576a88bbb1d018ebd25485e5852 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 17 Mar 2018 10:10:26 -0700 Subject: [PATCH 004/378] Update tests and README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2aca86c1b..5a0668147 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ cquery implements almost the entire language server protocol and provides some extra features to boot: * code completion (with both signature help and snippets) - * finding definition/references - * call (caller/callee) hierarchy, inheritance (base/derived) hierarchy, member hierarchy - * symbol rename + * finding [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc) + * [call (caller/callee) hierarchy](src/messages/cquery_call_hierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/cquery_inheritance_hierarchy.cc), [member hierarchy](src/messages/cquery_member_hierarchy.cc) + * [symbol rename](src/messages/text_document_rename.cc) * [document symbols](src/messages/text_document_document_symbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) * [hover information](src/messages/text_document_hover.cc) * diagnostics From 1882bd02564946e94cdb4f073e722410fa9f2153 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Sat, 17 Mar 2018 20:03:41 +0100 Subject: [PATCH 005/378] Add CMake as alternative build system (#526) --- CMakeLists.txt | 254 +++++++++++++++++++++++++++++ cmake/DefaultCMakeBuildType.cmake | 18 ++ cmake/DownloadAndExtract7zip.cmake | 51 ++++++ cmake/DownloadAndExtractLLVM.cmake | 107 ++++++++++++ cmake/FindClang.cmake | 143 ++++++++++++++++ 5 files changed, 573 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/DefaultCMakeBuildType.cmake create mode 100644 cmake/DownloadAndExtract7zip.cmake create mode 100644 cmake/DownloadAndExtractLLVM.cmake create mode 100644 cmake/FindClang.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..c779f5bf4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,254 @@ +cmake_minimum_required(VERSION 3.1) +project(cquery LANGUAGES CXX) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) +include(DefaultCMakeBuildType) +include(DownloadAndExtractLLVM) + +set(CLANG_VERSION 6.0.0 CACHE STRING "Downloaded Clang version (6.0.0)") +option(SYSTEM_CLANG "Use system Clang instead of downloading Clang" OFF) +option(ASAN "Compile with address sanitizers" OFF) +option(CLANG_CXX "Build with Clang C++ api required by some cquery \ +features (warning: not available in LLVM Windows downloads)" OFF) + +# Sources for the executable are specified at end of CMakeLists.txt +add_executable(cquery "") + +### Compile options + +# CMake default compile flags: +# MSVC + Clang(Windows): +# debug: /MDd /Zi /Ob0 /Od /RTC1 +# release: /MD /O2 /Ob2 /DNDEBUG +# GCC + Clang(Linux): +# debug: -g +# release: -O3 -DNDEBUG + +# Enable C++14 (Required) +set_property(TARGET cquery PROPERTY CXX_STANDARD 14) +set_property(TARGET cquery PROPERTY CXX_STANDARD_REQUIRED ON) +# Disable gcc extensions +set_property(TARGET cquery PROPERTY CXX_EXTENSIONS OFF) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) + # Common MSVC/Clang(Windows) options + target_compile_options(cquery PRIVATE + /nologo + /EHsc + /W3 # roughly -Wall + /wd4996 # disable loguru unsafe warnings + /wd4722 # ignores warning C4722 + # (destructor never returns) in loguru + /wd4267 # ignores warning C4267 + # (conversion from 'size_t' to 'type'), + # roughly -Wno-sign-compare + /wd4800 + $<$:/FS> + ) +else() + # Common GCC/Clang(Linux) options + target_compile_options(cquery PRIVATE + -Wall + -Wno-sign-compare + ) + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) + target_compile_options(cquery PRIVATE -Wno-return-type -Wno-unused-result) + endif() + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) + target_compile_options(cquery PRIVATE + $<$:-fno-limit-debug-info>) + endif() + + if(CLANG_CXX) + # -Wno-comment: include/clang/Format/Format.h error: multi-line comment + # -fno-rtti: # Without -fno-rtti, some Clang C++ functions may report + # `undefined references to typeinfo` + target_compile_options(cquery PRIVATE -Wno-comment -fno-rtti) + endif() + + if(ASAN) + target_compile_options(cquery PRIVATE -fsanitize=address,undefined) + # target_link_libraries also takes linker flags + target_link_libraries(cquery PRIVATE -fsanitize=address,undefined) + endif() +endif() + +### Download Clang if required + +if(NOT SYSTEM_CLANG) + download_and_extract_llvm(${CLANG_VERSION}) + # Used by FindClang + set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) +endif() + +### Libraries + +# See cmake/FindClang.cmake +find_package(Clang REQUIRED) +target_link_libraries(cquery PRIVATE Clang::Clang) + +# Enable threading support +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(cquery PRIVATE Threads::Threads) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + # (either through hardware or OS support) + # loguru calls dladdr + target_link_libraries(cquery PRIVATE ${CMAKE_DL_LIBS}) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) + # loguru::stacktrace_as_stdstring calls backtrace_symbols + # sparsepp/spp_memory.h uses libkvm + # src/platform_posix.cc uses libthr + find_package(Backtrace REQUIRED) + target_link_libraries(cquery PRIVATE ${Backtrace_LIBRARIES} kvm thr) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) + # sparsepp/spp_memory.h uses LibPsapi + target_link_libraries(cquery PRIVATE Psapi) +endif() + +if(CLANG_CXX) + # Clang C++ api uses ncurses + find_package(Curses REQUIRED) + target_link_libraries(cquery PRIVATE ${CURSES_LIBRARIES}) +endif() + +### Definitions + +target_compile_definitions(cquery PRIVATE + LOGURU_WITH_STREAMS=1 + LOGURU_FILENAME_WIDTH=18 + LOGURU_THREADNAME_WIDTH=13 + DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}") + +if(CLANG_CXX) + target_compile_definitions(cquery PRIVATE USE_CLANG_CXX=1 LOGURU_RTTI=0) +endif() + +### Includes + +target_include_directories(cquery PRIVATE + src + third_party + third_party/rapidjson/include + third_party/sparsepp + third_party/loguru + third_party/doctest + third_party/msgpack-c/include) + +### Install + +install(TARGETS cquery RUNTIME DESTINATION bin) + +# We don't need to install libclang on Windows if we are using downloaded LLVM +# since libclang is distributed as a static library on Windows +if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) + + if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) + set_property(TARGET cquery APPEND PROPERTY + INSTALL_RPATH $ORIGIN/../lib) + elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + set_property(TARGET cquery APPEND PROPERTY + INSTALL_RPATH @loader_path/../lib) + endif() + + file(GLOB LIBCLANG_PLUS_SYMLINKS + ${DOWNLOADED_CLANG_DIR}/lib/libclang.[so,dylib]*) + install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib) +endif() + +### Sources + +target_sources(cquery PRIVATE third_party/siphash.cc) + +target_sources(cquery PRIVATE + src/cache_manager.cc + src/clang_complete.cc + src/clang_cursor.cc + src/clang_format.cc + src/clang_index.cc + src/clang_indexer.cc + src/clang_translation_unit.cc + src/clang_utils.cc + src/code_complete_cache.cc + src/command_line.cc + src/diagnostics_engine.cc + src/file_consumer.cc + src/file_contents.cc + src/fuzzy_match.cc + src/iindexer.cc + src/import_manager.cc + src/import_pipeline.cc + src/include_complete.cc + src/ipc.cc + src/lex_utils.cc + src/lsp_diagnostic.cc + src/lsp.cc + src/match.cc + src/message_handler.cc + src/options.cc + src/platform_posix.cc + src/platform_win.cc + src/platform.cc + src/port.cc + src/position.cc + src/project.cc + src/query_utils.cc + src/query.cc + src/queue_manager.cc + src/recorder.cc + src/semantic_highlight_symbol_cache.cc + src/serializer.cc + src/standard_includes.cc + src/task.cc + src/test.cc + src/third_party_impl.cc + src/timer.cc + src/timestamp_manager.cc + src/type_printer.cc + src/utils.cc + src/work_thread.cc + src/working_files.cc) + +target_sources(cquery PRIVATE + src/messages/cquery_base.cc + src/messages/cquery_call_hierarchy.cc + src/messages/cquery_callers.cc + src/messages/cquery_derived.cc + src/messages/cquery_did_view.cc + src/messages/cquery_file_info.cc + src/messages/cquery_freshen_index.cc + src/messages/cquery_index_file.cc + src/messages/cquery_inheritance_hierarchy.cc + src/messages/cquery_member_hierarchy.cc + src/messages/cquery_random.cc + src/messages/cquery_vars.cc + src/messages/cquery_wait.cc + src/messages/exit.cc + src/messages/initialize.cc + src/messages/shutdown.cc + src/messages/text_document_code_action.cc + src/messages/text_document_code_lens.cc + src/messages/text_document_completion.cc + src/messages/text_document_definition.cc + src/messages/text_document_did_change.cc + src/messages/text_document_did_close.cc + src/messages/text_document_did_open.cc + src/messages/text_document_did_save.cc + src/messages/text_document_document_highlight.cc + src/messages/text_document_document_link.cc + src/messages/text_document_document_symbol.cc + src/messages/text_document_formatting.cc + src/messages/text_document_hover.cc + src/messages/text_document_range_formatting.cc + src/messages/text_document_references.cc + src/messages/text_document_rename.cc + src/messages/text_document_signature_help.cc + src/messages/text_document_type_definition.cc + src/messages/workspace_did_change_configuration.cc + src/messages/workspace_did_change_watched_files.cc + src/messages/workspace_symbol.cc) \ No newline at end of file diff --git a/cmake/DefaultCMakeBuildType.cmake b/cmake/DefaultCMakeBuildType.cmake new file mode 100644 index 000000000..fa86f4333 --- /dev/null +++ b/cmake/DefaultCMakeBuildType.cmake @@ -0,0 +1,18 @@ +# Set a default build type if none was specified +set(DEFAULT_CMAKE_BUILD_TYPE Release) +if(EXISTS ${CMAKE_SOURCE_DIR}/.git) + set(DEFAULT_CMAKE_BUILD_TYPE Debug) +endif() + +# CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used +# (eg Visual Studio generators) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ +was specified.") + set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} + CACHE STRING "Choose the type of build." FORCE) + + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) +endif() \ No newline at end of file diff --git a/cmake/DownloadAndExtract7zip.cmake b/cmake/DownloadAndExtract7zip.cmake new file mode 100644 index 000000000..f3257e6b0 --- /dev/null +++ b/cmake/DownloadAndExtract7zip.cmake @@ -0,0 +1,51 @@ +# Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/. +# +# Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR +# +# Downloads 7-Zip to extract LLVM if it isn't available in the PATH +function(download_and_extract_7zip) + +set(7ZIP_VERSION 1801) +set(7ZIP_EXT .msi) +set(7ZIP_NAME 7z${7ZIP_VERSION}-x64) +set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT}) + +set(7ZIP_FILE ${CMAKE_BINARY_DIR}/${7ZIP_FULL_NAME}) +set(7ZIP_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${7ZIP_NAME}) +set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME}) + +# msiexec requires Windows path separators (\) +file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE) +file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) + +if(NOT EXISTS ${7ZIP_FILE}) + message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...") + file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE}) +endif() + +if(NOT EXISTS ${7ZIP_EXTRACT_DIR}) + + find_program(MSIEXEC_EXECUTABLE msiexec) + if(NOT MSIEXEC_EXECUTABLE) + message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \ +installer). Install 7-Zip yourself and make sure it is available in the path") + endif() + + message(STATUS "Extracting downloaded 7-Zip ...") + + # msiexec with /a option allows extraction of msi installers without requiring + # admin privileges. We use this to extract the 7-Zip installer without + # requiring any actions from the user + execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn + TARGETDIR=${7ZIP_EXTRACT_DIR} + OUTPUT_QUIET) +endif() + +# Convert back to CMake separators (/) before returning +file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) + +# Actual directory is nested inside the extract directory. We return the nested +# directory instead of the extract directory +set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE) + +endfunction() \ No newline at end of file diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake new file mode 100644 index 000000000..8fcdda647 --- /dev/null +++ b/cmake/DownloadAndExtractLLVM.cmake @@ -0,0 +1,107 @@ +# Downloads and extracts the LLVM archive for the current system from +# https://releases.llvm.org +# +# Returns the extracted LLVM archive directory in DOWNLOADED_CLANG_DIR +# +# Downloads 7-Zip to extract LLVM if it isn't available in the PATH +function(download_and_extract_llvm CLANG_VERSION) + +include(DownloadAndExtract7zip) + +set(CLANG_ARCHIVE_EXT .tar.xz) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + + set(CLANG_ARCHIVE_NAME + clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) + + set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64) + set(CLANG_ARCHIVE_EXT .exe) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) + + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) + +endif() + +set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) +set(CLANG_ARCHIVE_FILE ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_FULL_NAME}) +set(CLANG_ARCHIVE_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_NAME}) +set(CLANG_ARCHIVE_URL + https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME}) + +if(NOT EXISTS ${CLANG_ARCHIVE_FILE}) + message(STATUS "Downloading LLVM ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...") + file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE}) +endif() + +if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) + if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) + find_program(7ZIP_EXECUTABLE 7z) + + if(NOT 7ZIP_EXECUTABLE) + message(STATUS "7-Zip not found in PATH") + download_and_extract_7zip() + find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH + PATHS ${DOWNLOADED_7ZIP_DIR}) + else() + message(STATUS "7-Zip found in PATH") + endif() + + message(STATUS "Extracting downloaded LLVM with 7-Zip ...") + + # Avoid running the LLVM installer by extracting the exe with 7-Zip + execute_process(COMMAND ${7ZIP_EXECUTABLE} x + -o${CLANG_ARCHIVE_EXTRACT_DIR} + -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} + OUTPUT_QUIET) + elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz) + message(STATUS "Extracting downloaded LLVM with CMake built-in tar ...") + # CMake has builtin support for tar via the -E flag + execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} + OUTPUT_QUIET) + endif() + + # There is a null pointer dereference issue in + # tools/libclang/CXIndexDataConsumer.cpp handleReference. + # https://github.com/cquery-project/cquery/issues/219 + if(${CMAKE_SYSTEM_NAME} STREQUAL Linux AND + ${CLANG_VERSION} MATCHES 4.0.0|5.0.1) + message(STATUS "Patching downloaded LLVM (see \ +https://github.com/cquery-project/cquery/issues/219)") + + if(${CLANG_VERSION} STREQUAL 4.0.0) + # 4289205 = $[0x4172b5] (we use decimals for seek since execute_process + # does not evaluate $[] bash syntax) + execute_process(COMMAND printf \\x4d + COMMAND dd + of=${CLANG_ARCHIVE_EXTRACT_DIR}/lib/libclang.so.4.0 + obs=1 seek=4289205 conv=notrunc + OUTPUT_QUIET) + + elseif(${CLANG_VERSION} STREQUAL 5.0.1) + # 4697806 = $[0x47aece] + execute_process(COMMAND printf \\x4d + COMMAND dd + of=${CLANG_ARCHIVE_EXTRACT_DIR}/lib/libclang.so.5.0 + obs=1 seek=4697806 conv=notrunc + OUTPUT_QUIET) + endif() + endif() +endif() + +# CMake functions have no return values so we just lift our return variable to +# the parent scope +set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) + +endfunction() + + + + diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake new file mode 100644 index 000000000..57524aca2 --- /dev/null +++ b/cmake/FindClang.cmake @@ -0,0 +1,143 @@ +#.rst +# FindClang +# --------- +# +# Find Clang and LLVM libraries required by cquery +# +# Results are reported in the following variables:: +# +# Clang_FOUND - True if headers and requested libraries were found +# Clang_EXECUTABLE - Clang executable +# Clang_RESOURCE_DIR - Clang resource directory +# Clang_VERSION - Clang version as reported by Clang executable +# +# The following :prop_tgt:`IMPORTED` targets are also defined:: +# +# Clang::Clang - Target for all required Clang libraries and headers +# +# This module reads hints about which libraries to look for and where to find +# them from the following variables:: +# +# CLANG_CXX - Search for and add Clang C++ libraries +# CLANG_ROOT - If set, only look for Clang components in CLANG_ROOT +# +# Example to link against Clang target:: +# +# target_link_libraries( PRIVATE Clang::Clang) + +### Definitions + +# Wrapper macro's around the find_* macro's from CMake that only search in +# CLANG_ROOT if it is defined + +macro(_Clang_find_library VAR NAME) + # Windows needs lib prefix + if (CLANG_ROOT) + find_library(${VAR} NAMES ${NAME} lib${NAME} + NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES lib) + else() + find_library(${VAR} NAMES ${NAME} lib${NAME}) + endif() +endmacro() + +macro(_Clang_find_path VAR INCLUDE_FILE) + if (CLANG_ROOT) + find_path(${VAR} ${INCLUDE_FILE} + NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES include) + else() + find_path(${VAR} ${INCLUDE_FILE}) + endif() +endmacro() + +macro(_Clang_find_program VAR NAME) + if (CLANG_ROOT) + find_program(${VAR} ${NAME} + NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES bin) + else() + find_program(${VAR} ${NAME}) + endif() +endmacro() + +# Macro to avoid duplicating logic for each Clang C++ library +macro(_Clang_find_and_add_cxx_lib NAME INCLUDE_FILE) + # Find library + _Clang_find_library(Clang_${NAME}_LIBRARY ${NAME}) + list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_LIBRARY) + list(APPEND _Clang_CXX_LIBRARIES ${Clang_${NAME}_LIBRARY}) + + # Find corresponding include directory + _Clang_find_path(Clang_${NAME}_INCLUDE_DIR ${INCLUDE_FILE}) + list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_INCLUDE_DIR) + list(APPEND _Clang_CXX_INCLUDE_DIRS ${Clang_${NAME}_INCLUDE_DIR}) +endmacro() + +### Start + +set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE + Clang_RESOURCE_DIR Clang_VERSION) + +_Clang_find_library(Clang_LIBRARY clang) +_Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) + +if(CLANG_CXX) + # The order is derived by topological sorting LINK_LIBS in + # clang/lib/*/CMakeLists.txt + _Clang_find_and_add_cxx_lib(clangFormat clang/Format/Format.h) + _Clang_find_and_add_cxx_lib(clangToolingCore clang/Tooling/Core/Diagnostic.h) + _Clang_find_and_add_cxx_lib(clangRewrite clang/Rewrite/Core/Rewriter.h) + _Clang_find_and_add_cxx_lib(clangAST clang/AST/AST.h) + _Clang_find_and_add_cxx_lib(clangLex clang/Lex/Lexer.h) + _Clang_find_and_add_cxx_lib(clangBasic clang/Basic/ABI.h) + + # The order is derived from llvm-config --libs core + _Clang_find_and_add_cxx_lib(LLVMCore llvm/Pass.h) + _Clang_find_and_add_cxx_lib(LLVMBinaryFormat llvm/BinaryFormat/Dwarf.h) + _Clang_find_and_add_cxx_lib(LLVMSupport llvm/Support/Error.h) + _Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h) +endif() + +_Clang_find_program(Clang_EXECUTABLE clang) +if(Clang_EXECUTABLE) + # Find Clang resource directory with Clang executable + # TODO: simplify by using -print-resource-dir once Clang 4 support is dropped + if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) + set(_DEV_NULL NUL) + else() + set(_DEV_NULL /dev/null) + endif() + + # clang "-###" -xc /dev/null + execute_process(COMMAND ${Clang_EXECUTABLE} "-###" -xc ${_DEV_NULL} + ERROR_VARIABLE Clang_RESOURCE_DIR OUTPUT_QUIET) + # Strip everything except '"-resource-dir" ""' + string(REGEX MATCH "\"-resource-dir\" \"([^\"]*)\"" + Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) + # Strip quotes + string(REPLACE "\"" "" Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) + # Strip '-resource-dir ' + string(REPLACE "-resource-dir " "" Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) + + # Find Clang version + set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") + execute_process(COMMAND ${Clang_EXECUTABLE} --version + OUTPUT_VARIABLE Clang_VERSION) + string(REGEX MATCH ${_Clang_VERSION_REGEX} Clang_VERSION ${Clang_VERSION}) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Clang + FOUND_VAR Clang_FOUND + REQUIRED_VARS ${_Clang_REQUIRED_VARS} + VERSION_VAR Clang_VERSION +) + +if(Clang_FOUND AND NOT TARGET Clang::Clang) + set(_Clang_LIBRARIES ${Clang_LIBRARY} ${_Clang_CXX_LIBRARIES}) + set(_Clang_INCLUDE_DIRS ${Clang_INCLUDE_DIR} ${_Clang_CXX_INCLUDE_DIRS}) + + add_library(Clang::Clang INTERFACE IMPORTED) + set_property(TARGET Clang::Clang PROPERTY + INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES}) + set_property(TARGET Clang::Clang PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${_Clang_INCLUDE_DIRS}) +endif() From 55bfe58feaf3ca12e24a5eb49fd5bd8c62712dd2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 17 Mar 2018 13:24:01 -0700 Subject: [PATCH 006/378] textDocument/didOpen: add args to override project entry --- src/messages/text_document_did_open.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index a16c0fb74..0bd4f9901 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -14,10 +14,15 @@ struct Ipc_TextDocumentDidOpen const static IpcId kIpcId = IpcId::TextDocumentDidOpen; struct Params { lsTextDocumentItem textDocument; + + // cquery extension + // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project + // entry (e.g. loaded from compile_commands.json or .cquery). + std::vector args; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen::Params, textDocument); +MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen::Params, textDocument, args); MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen, params); REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidOpen); @@ -26,15 +31,14 @@ struct TextDocumentDidOpenHandler void Run(Ipc_TextDocumentDidOpen* request) override { // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. - + const auto& params = request->params; Timer time; - std::string path = request->params.textDocument.uri.GetPath(); + std::string path = params.textDocument.uri.GetPath(); if (ShouldIgnoreFileForIndexing(path)) return; std::shared_ptr cache_manager = ICacheManager::Make(config); - WorkingFile* working_file = - working_files->OnOpen(request->params.textDocument); + WorkingFile* working_file = working_files->OnOpen(params.textDocument); optional cached_file_contents = cache_manager->LoadCachedFileContents(path); if (cached_file_contents) @@ -57,8 +61,9 @@ struct TextDocumentDidOpenHandler // Submit new index request. const Project::Entry& entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/, - request->params.textDocument.text, cache_manager), + Index_Request( + entry.filename, params.args.size() ? params.args : entry.args, + true /*is_interactive*/, params.textDocument.text, cache_manager), true /* priority */); } }; From 9ad268af29ea39d412daf556b94cc05daba2c014 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 17 Mar 2018 23:41:04 -0700 Subject: [PATCH 007/378] Use clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz before 6.0.0 it was named freebsd10 --- cmake/DefaultCMakeBuildType.cmake | 8 ++++---- cmake/DownloadAndExtractLLVM.cmake | 9 +++------ wscript | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cmake/DefaultCMakeBuildType.cmake b/cmake/DefaultCMakeBuildType.cmake index fa86f4333..89ea3ede5 100644 --- a/cmake/DefaultCMakeBuildType.cmake +++ b/cmake/DefaultCMakeBuildType.cmake @@ -9,10 +9,10 @@ endif() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ was specified.") - set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} + set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} CACHE STRING "Choose the type of build." FORCE) - + # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) -endif() \ No newline at end of file +endif() diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake index 8fcdda647..abbdf9a94 100644 --- a/cmake/DownloadAndExtractLLVM.cmake +++ b/cmake/DownloadAndExtractLLVM.cmake @@ -26,7 +26,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) + # 6.0.0 uses freebsd-10 while 5.0.1 uses freebsd10 + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) endif() @@ -99,9 +100,5 @@ endif() # CMake functions have no return values so we just lift our return variable to # the parent scope set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) - -endfunction() - - - +endfunction() diff --git a/wscript b/wscript index 9be6c600b..d090ab41e 100644 --- a/wscript +++ b/wscript @@ -25,7 +25,7 @@ CLANG_TARBALL_EXT = '.tar.xz' if sys.platform == 'darwin': CLANG_TARBALL_NAME = 'clang+llvm-$version-x86_64-apple-darwin' elif sys.platform.startswith('freebsd'): - CLANG_TARBALL_NAME = 'clang+llvm-$version-amd64-unknown-freebsd10' + CLANG_TARBALL_NAME = 'clang+llvm-$version-amd64-unknown-freebsd-10' # It is either 'linux2' or 'linux3' before Python 3.3 elif sys.platform.startswith('linux'): # These executable depend on libtinfo.so.5 From 42b47ae77b20764de107d404b25a042bf56d7bd9 Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Sun, 18 Mar 2018 17:15:32 +0100 Subject: [PATCH 008/378] Add -idirafter ot kPathArgs (#529) --- src/project.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/project.cc b/src/project.cc index 35d86aab8..a95efdf83 100644 --- a/src/project.cc +++ b/src/project.cc @@ -86,7 +86,9 @@ std::vector kBlacklist = { std::vector kPathArgs = { "-I", "-iquote", "-isystem", "--sysroot=", "-isysroot", "-gcc-toolchain", "-include-pch", "-iframework", - "-F", "-imacros", "-include", "/I"}; + "-F", "-imacros", "-include", "/I", + "-idirafter" +}; // Arguments which always require an absolute path, ie, clang -working-directory // does not work as expected. Argument processing assumes that this is a subset From 639f587e01312ac23500a31b51d29c34010c3518 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 18 Mar 2018 12:17:40 -0700 Subject: [PATCH 009/378] Optimize FuzzyMatcher and add tests. --- src/fuzzy_match.cc | 76 +++++++++++++++++++++++++------- src/fuzzy_match.h | 2 +- src/messages/workspace_symbol.cc | 5 ++- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 269b2a942..79b0727b6 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -1,7 +1,11 @@ #include "fuzzy_match.h" +#include + #include +#include #include +#include enum CharClass { Other, Lower, Upper }; enum CharRole { None, Tail, Head }; @@ -49,20 +53,20 @@ int FuzzyMatcher::MissScore(int j, bool last) { } int FuzzyMatcher::MatchScore(int i, int j, bool last) { - int s = 40; + int s = 0; if (pat[i] == text[j]) { s++; if ((pat_set & 1 << Upper) || i == j) - s += 20; + s += 10; } if (pat_role[i] == Head && text_role[j] == Head) - s += 50; + s += 30; if (text_role[j] == Tail && i && !last) - s -= 50; - if (pat_role[i] == Head && text_role[j] == Tail) s -= 30; + if (pat_role[i] == Head && text_role[j] == Tail) + s -= 10; if (i == 0 && text_role[j] == Tail) - s -= 70; + s -= 40; return s; } @@ -87,31 +91,73 @@ int FuzzyMatcher::Match(std::string_view text) { low_text[i] = ::tolower(text[i]); CalculateRoles(text, text_role, &text_set); dp[0][0][0] = 0; - dp[0][0][1] = kMinScore; + dp[0][0][1] = kMinScore * 2; for (int j = 0; j < n; j++) { dp[0][j + 1][0] = dp[0][j][0] + MissScore(j, false); - dp[0][j + 1][1] = kMinScore; + dp[0][j + 1][1] = kMinScore * 2; } for (int i = 0; i < int(pat.size()); i++) { int(*pre)[2] = dp[i & 1]; int(*cur)[2] = dp[(i + 1) & 1]; - cur[0][0] = cur[0][1] = kMinScore; - for (int j = 0; j < n; j++) { + cur[i][0] = cur[i][1] = kMinScore; + for (int j = i; j < n; j++) { cur[j + 1][0] = std::max(cur[j][0] + MissScore(j, false), cur[j][1] + MissScore(j, true)); - if (low_pat[i] != low_text[j]) - cur[j + 1][1] = kMinScore; - else { + // For the first char of pattern, apply extra restriction to filter bad + // candidates (e.g. |int| in |PRINT|) + if (low_pat[i] == low_text[j] && + (i || text_role[j] != Tail || pat[i] == text[j])) { cur[j + 1][1] = std::max(pre[j][0] + MatchScore(i, j, false), pre[j][1] + MatchScore(i, j, true)); - } + } else + cur[j + 1][1] = kMinScore * 2; } } // Enumerate the end position of the match in str. Each removed trailing // character has a penulty. int ret = kMinScore; - for (int j = 1; j <= n; j++) + for (int j = pat.size(); j <= n; j++) ret = std::max(ret, dp[pat.size() & 1][j][1] - 3 * (n - j)); return ret; } + +TEST_SUITE("fuzzy_match") { + bool Ranks(std::string_view pat, std::vector texts) { + FuzzyMatcher fuzzy(pat); + std::vector scores; + for (auto text : texts) + scores.push_back(fuzzy.Match(text)); + bool ret = true; + for (size_t i = 0; i < texts.size() - 1; i++) + if (scores[i] < scores[i + 1]) { + ret = false; + break; + } + if (1 || !ret) { + for (size_t i = 0; i < texts.size(); i++) + printf("%s %d ", texts[i], scores[i]); + puts(""); + } + return ret; + } + + TEST_CASE("test") { + // case + Ranks("monad", {"monad", "Monad", "mONAD"}); + // initials + Ranks("ab", {"ab", "aoo_boo", "acb"}); + Ranks("CC", {"CamelCase", "camelCase", "camelcase"}); + Ranks("cC", {"camelCase", "CamelCase", "camelcase"}); + Ranks("Da.Te", {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"}); + // prefix + Ranks("is", {"isIEEE", "inSuf"}); + // shorter + Ranks("ma", {"map", "many", "maximum"}); + Ranks("print", {"printf", "sprintf"}); + // score(PRINT) = kMinScore + Ranks("int", {"int", "INT", "PRINT"}); + // score(PRINT) > kMinScore + Ranks("Int", {"int", "INT", "PRINT"}); + } +} diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index a3b5191ce..79599857c 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -11,7 +11,7 @@ class FuzzyMatcher { constexpr static int kMaxText = 200; // Negative but far from INT_MIN so that intermediate results are hard to // overflow. - constexpr static int kMinScore = INT_MIN / 2; + constexpr static int kMinScore = INT_MIN / 4; FuzzyMatcher(std::string_view pattern); int Match(std::string_view text); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index f6a00f27e..e02b2212a 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -136,7 +136,10 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { std::sort(permutation.begin(), permutation.end(), std::greater>()); out.result.reserve(result_indices.size()); - for (int i = 0; i < int(result_indices.size()); i++) + // Discard awful candidates. + for (int i = 0; i < int(result_indices.size()) && + permutation[i].first > FuzzyMatcher::kMinScore; + i++) out.result.push_back( std::move(unsorted_results[permutation[i].second])); } else { From 1e019f49849a167fbdeb6b56abe4d87c8d9ea21a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 18 Mar 2018 13:04:59 -0700 Subject: [PATCH 010/378] Simplify and optimize completion. --- src/fuzzy_match.cc | 2 +- src/lex_utils.cc | 70 ++++++------------------ src/lex_utils.h | 7 +-- src/lsp_completion.h | 3 +- src/messages/text_document_completion.cc | 68 ++++++++--------------- src/messages/workspace_symbol.cc | 2 +- 6 files changed, 44 insertions(+), 108 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 79b0727b6..2ddb02c61 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -156,7 +156,7 @@ TEST_SUITE("fuzzy_match") { Ranks("ma", {"map", "many", "maximum"}); Ranks("print", {"printf", "sprintf"}); // score(PRINT) = kMinScore - Ranks("int", {"int", "INT", "PRINT"}); + Ranks("ast", {"ast", "AST", "INT_FAST16_MAX"}); // score(PRINT) > kMinScore Ranks("Int", {"int", "INT", "PRINT"}); } diff --git a/src/lex_utils.cc b/src/lex_utils.cc index 9ab0ef4b9..c7e5700f7 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -180,23 +180,10 @@ std::string_view LexIdentifierAroundPos(lsPosition position, return content.substr(start, end - start); } -bool SubsequenceMatchIgnoreCase(std::string_view search, std::string_view content) { - size_t j = 0; - for (size_t i = 0; i < search.size(); i++) { - char search_char = tolower(search[i]); - while (j < content.size() && tolower(content[j]) != search_char) - j++; - if (j == content.size()) - return false; - j++; - } - return true; -} - // Find discontinous |search| in |content|. // Return |found| and the count of skipped chars before found. -std::tuple SubsequenceCountSkip(std::string_view search, - std::string_view content) { +std::pair CaseFoldingSubsequenceMatch(std::string_view search, + std::string_view content) { bool hasUppercaseLetter = std::any_of(search.begin(), search.end(), isupper); int skip = 0; size_t j = 0; @@ -206,10 +193,10 @@ std::tuple SubsequenceCountSkip(std::string_view search, : tolower(content[j]) != tolower(c))) ++j, ++skip; if (j == content.size()) - return std::make_tuple(false, skip); + return {false, skip}; ++j; } - return std::make_tuple(true, skip); + return {true, skip}; } TEST_SUITE("Offset") { @@ -234,43 +221,20 @@ TEST_SUITE("Offset") { } TEST_SUITE("Substring") { - TEST_CASE("match") { - // Empty string matches anything. - REQUIRE(SubsequenceMatchIgnoreCase("", "")); - REQUIRE(SubsequenceMatchIgnoreCase("", "aa")); - - // Match in start/middle/end. - REQUIRE(SubsequenceMatchIgnoreCase("a", "abbbb")); - REQUIRE(SubsequenceMatchIgnoreCase("a", "bbabb")); - REQUIRE(SubsequenceMatchIgnoreCase("a", "bbbba")); - REQUIRE(SubsequenceMatchIgnoreCase("aa", "aabbb")); - REQUIRE(SubsequenceMatchIgnoreCase("aa", "bbaab")); - REQUIRE(SubsequenceMatchIgnoreCase("aa", "bbbaa")); - - // Capitalization. - REQUIRE(SubsequenceMatchIgnoreCase("aa", "aA")); - REQUIRE(SubsequenceMatchIgnoreCase("aa", "Aa")); - REQUIRE(SubsequenceMatchIgnoreCase("aa", "AA")); - - // Token skipping. - REQUIRE(SubsequenceMatchIgnoreCase("ad", "abcd")); - REQUIRE(SubsequenceMatchIgnoreCase("ad", "ABCD")); - - // Ordering. - REQUIRE(!SubsequenceMatchIgnoreCase("ad", "dcba")); - } - TEST_CASE("skip") { - REQUIRE(SubsequenceCountSkip("a", "a") == std::make_tuple(true, 0)); - REQUIRE(SubsequenceCountSkip("b", "a") == std::make_tuple(false, 1)); - REQUIRE(SubsequenceCountSkip("", "") == std::make_tuple(true, 0)); - REQUIRE(SubsequenceCountSkip("a", "ba") == std::make_tuple(true, 1)); - REQUIRE(SubsequenceCountSkip("aa", "aba") == std::make_tuple(true, 1)); - 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 ") == - std::make_tuple(true, 7)); + REQUIRE(CaseFoldingSubsequenceMatch("a", "a") == std::make_pair(true, 0)); + REQUIRE(CaseFoldingSubsequenceMatch("b", "a") == std::make_pair(false, 1)); + REQUIRE(CaseFoldingSubsequenceMatch("", "") == std::make_pair(true, 0)); + REQUIRE(CaseFoldingSubsequenceMatch("a", "ba") == std::make_pair(true, 1)); + REQUIRE(CaseFoldingSubsequenceMatch("aa", "aba") == + std::make_pair(true, 1)); + REQUIRE(CaseFoldingSubsequenceMatch("aa", "baa") == + std::make_pair(true, 1)); + REQUIRE(CaseFoldingSubsequenceMatch("aA", "aA") == std::make_pair(true, 0)); + REQUIRE(CaseFoldingSubsequenceMatch("aA", "aa") == + std::make_pair(false, 1)); + REQUIRE(CaseFoldingSubsequenceMatch("incstdioh", "include ") == + std::make_pair(true, 7)); } } diff --git a/src/lex_utils.h b/src/lex_utils.h index f95035e67..7d860aced 100644 --- a/src/lex_utils.h +++ b/src/lex_utils.h @@ -26,8 +26,5 @@ void LexFunctionDeclaration(const std::string& buffer_content, std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content); -// Case-insensitive subsequence matching. -bool SubsequenceMatchIgnoreCase(std::string_view search, std::string_view content); - -std::tuple SubsequenceCountSkip(std::string_view search, - std::string_view content); +std::pair CaseFoldingSubsequenceMatch(std::string_view search, + std::string_view content); diff --git a/src/lsp_completion.h b/src/lsp_completion.h index e06b4bd91..04105f2c2 100644 --- a/src/lsp_completion.h +++ b/src/lsp_completion.h @@ -72,8 +72,7 @@ struct lsCompletionItem { optional documentation; // Internal information to order candidates. - bool found_; - std::string::size_type skip_; + int score_; unsigned priority_; // Use <> or "" by default as include path. diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index ba1a305d6..17e0c5016 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -1,5 +1,6 @@ #include "clang_complete.h" #include "code_complete_cache.h" +#include "fuzzy_match.h" #include "include_complete.h" #include "message_handler.h" #include "queue_manager.h" @@ -70,19 +71,6 @@ struct Out_TextDocumentComplete }; MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result); -bool CompareLsCompletionItem(const lsCompletionItem& lhs, - const lsCompletionItem& rhs) { - if (lhs.found_ != rhs.found_) - return !lhs.found_ < !rhs.found_; - if (lhs.skip_ != rhs.skip_) - return lhs.skip_ < rhs.skip_; - if (lhs.priority_ != rhs.priority_) - return lhs.priority_ < rhs.priority_; - if (lhs.filterText->length() != rhs.filterText->length()) - return lhs.filterText->length() < rhs.filterText->length(); - return *lhs.filterText < *rhs.filterText; -} - void DecorateIncludePaths(const std::smatch& match, std::vector* items) { std::string spaces_after_include = " "; @@ -200,41 +188,29 @@ void FilterAndSortCompletionResponse( item.filterText = item.label; } - // If the text doesn't start with underscore, remove all candidates that - // start with underscore. - if (complete_text[0] != '_') { - auto filter = [](const lsCompletionItem& item) { - return (*item.filterText)[0] == '_'; - }; - items.erase(std::remove_if(items.begin(), items.end(), filter), - items.end()); - } - - // Fuzzy match. Remove any candidates that do not match. - bool found = false; + // Fuzzy match and remove awful candidates. + FuzzyMatcher fuzzy(complete_text); for (auto& item : items) { - std::tie(item.found_, item.skip_) = - SubsequenceCountSkip(complete_text, *item.filterText); - found = found || item.found_; - } - if (found) { - auto filter = [](const lsCompletionItem& item) { return !item.found_; }; - items.erase(std::remove_if(items.begin(), items.end(), filter), - items.end()); - - // Order all items and set |sortText|. - const size_t kMaxSortSize = 200u; - if (items.size() <= kMaxSortSize) { - std::sort(items.begin(), items.end(), CompareLsCompletionItem); - } else { - // Just place items that found the text before those not. - std::vector items_found, items_notfound; - for (auto& item : items) - (item.found_ ? items_found : items_notfound).push_back(item); - items = items_found; - items.insert(items.end(), items_notfound.begin(), items_notfound.end()); - } + item.score_ = + CaseFoldingSubsequenceMatch(complete_text, *item.filterText).first + ? fuzzy.Match(*item.filterText) + : FuzzyMatcher::kMinScore; } + items.erase(std::remove_if(items.begin(), items.end(), + [](const lsCompletionItem& item) { + return item.score_ <= FuzzyMatcher::kMinScore; + }), + items.end()); + std::sort(items.begin(), items.end(), + [](const lsCompletionItem& lhs, const lsCompletionItem& rhs) { + if (lhs.score_ != rhs.score_) + return lhs.score_ > rhs.score_; + if (lhs.priority_ != rhs.priority_) + return lhs.priority_ < rhs.priority_; + if (lhs.filterText->size() != rhs.filterText->size()) + return lhs.filterText->size() < rhs.filterText->size(); + return *lhs.filterText < *rhs.filterText; + }); // Trim result. finalize(); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index e02b2212a..9595baf8e 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -107,7 +107,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { for (int i = 0; i < (int)db->symbols.size(); ++i) { std::string_view detailed_name = db->GetSymbolDetailedName(i); - if (SubsequenceMatchIgnoreCase(query_without_space, detailed_name)) { + if (CaseFoldingSubsequenceMatch(query_without_space, detailed_name).first) { // Do not show the same entry twice. if (!inserted_results.insert(std::string(detailed_name)).second) continue; From 4d23e9fa1088fc65a689eb0e047d73719fdf3fc1 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Sun, 18 Mar 2018 21:16:42 +0100 Subject: [PATCH 011/378] [CMake] Remove byte hacks + add correct url's for different clang versions + abort for unsupported combinations (#532) --- cmake/DownloadAndExtractLLVM.cmake | 47 ++++++++++-------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake index abbdf9a94..ad285641d 100644 --- a/cmake/DownloadAndExtractLLVM.cmake +++ b/cmake/DownloadAndExtractLLVM.cmake @@ -12,8 +12,13 @@ set(CLANG_ARCHIVE_EXT .tar.xz) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) + if(${CLANG_VERSION} STREQUAL 5.0.0) + set(CLANG_ARCHIVE_NAME + clang+llvm-${CLANG_VERSION}-linux-x86_64-ubuntu14.04) + else() + set(CLANG_ARCHIVE_NAME + clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) + endif() elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) @@ -26,9 +31,16 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - # 6.0.0 uses freebsd-10 while 5.0.1 uses freebsd10 - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) + if(${CLANG_VERSION} STREQUAL 6.0.0) + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) + else() + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) + endif() +endif() +if(NOT CLANG_ARCHIVE_NAME) + message(FATAL_ERROR "No download available for ${CMAKE_SYSTEM_NAME} + \ +${CLANG_VERSION}") endif() set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) @@ -68,33 +80,6 @@ if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} OUTPUT_QUIET) endif() - - # There is a null pointer dereference issue in - # tools/libclang/CXIndexDataConsumer.cpp handleReference. - # https://github.com/cquery-project/cquery/issues/219 - if(${CMAKE_SYSTEM_NAME} STREQUAL Linux AND - ${CLANG_VERSION} MATCHES 4.0.0|5.0.1) - message(STATUS "Patching downloaded LLVM (see \ -https://github.com/cquery-project/cquery/issues/219)") - - if(${CLANG_VERSION} STREQUAL 4.0.0) - # 4289205 = $[0x4172b5] (we use decimals for seek since execute_process - # does not evaluate $[] bash syntax) - execute_process(COMMAND printf \\x4d - COMMAND dd - of=${CLANG_ARCHIVE_EXTRACT_DIR}/lib/libclang.so.4.0 - obs=1 seek=4289205 conv=notrunc - OUTPUT_QUIET) - - elseif(${CLANG_VERSION} STREQUAL 5.0.1) - # 4697806 = $[0x47aece] - execute_process(COMMAND printf \\x4d - COMMAND dd - of=${CLANG_ARCHIVE_EXTRACT_DIR}/lib/libclang.so.5.0 - obs=1 seek=4697806 conv=notrunc - OUTPUT_QUIET) - endif() - endif() endif() # CMake functions have no return values so we just lift our return variable to From b9c3af0be95463a2f01ae4ca33024e876a8a9e35 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 18 Mar 2018 14:26:15 -0700 Subject: [PATCH 012/378] Don't include system header files for `#include "` (`#i"`) completion --- src/fuzzy_match.cc | 7 +++- src/messages/text_document_completion.cc | 53 +++++++++++++----------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 2ddb02c61..7a76ca0dc 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -90,8 +90,7 @@ int FuzzyMatcher::Match(std::string_view text) { for (int i = 0; i < n; i++) low_text[i] = ::tolower(text[i]); CalculateRoles(text, text_role, &text_set); - dp[0][0][0] = 0; - dp[0][0][1] = kMinScore * 2; + dp[0][0][0] = dp[0][0][1] = 0; for (int j = 0; j < n; j++) { dp[0][j + 1][0] = dp[0][j][0] + MissScore(j, false); dp[0][j + 1][1] = kMinScore * 2; @@ -143,6 +142,10 @@ TEST_SUITE("fuzzy_match") { } TEST_CASE("test") { + FuzzyMatcher fuzzy(""); + CHECK(fuzzy.Match("") == 0); + CHECK(fuzzy.Match("aaa") < 0); + // case Ranks("monad", {"monad", "Monad", "mONAD"}); // initials diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 17e0c5016..cf4300057 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -98,7 +98,7 @@ void DecorateIncludePaths(const std::smatch& match, struct ParseIncludeLineResult { bool ok; - std::string text; // include the "include" part + std::string pattern; std::smatch match; }; @@ -115,7 +115,7 @@ ParseIncludeLineResult ParseIncludeLine(const std::string& line) { "(.*)"); // [7]: suffix after quote char std::smatch match; bool ok = std::regex_match(line, match, pattern); - std::string text = match[3].str() + match[6].str(); + std::string text = match[6].str(); return {ok, text, match}; } @@ -298,30 +298,33 @@ struct TextDocumentCompletionHandler : MessageHandler { Out_TextDocumentComplete out; out.id = request->id; - { - std::unique_lock lock( + std::string text = result.match[3]; + if (std::string_view("include").compare(0, text.size(), text) == 0) { + { + std::unique_lock lock( include_complete->completion_items_mutex, std::defer_lock); - if (include_complete->is_scanning) - lock.lock(); - out.result.items.assign(include_complete->completion_items.begin(), - include_complete->completion_items.end()); - if (lock) - lock.unlock(); - } - - // Needed by |FilterAndSortCompletionResponse|. - for (lsCompletionItem& item : out.result.items) - item.filterText = "include" + item.label; - - FilterAndSortCompletionResponse(&out, result.text, - config->completion.filterAndSort); - DecorateIncludePaths(result.match, &out.result.items); - - for (lsCompletionItem& item : out.result.items) { - item.textEdit->range.start.line = request->params.position.line; - item.textEdit->range.start.character = 0; - item.textEdit->range.end.line = request->params.position.line; - item.textEdit->range.end.character = (int)buffer_line.size(); + if (include_complete->is_scanning) + lock.lock(); + std::string quote = result.match[5]; + for (auto& item : include_complete->completion_items) + if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + out.result.items.push_back(item); + } + + // Needed by |FilterAndSortCompletionResponse|. + for (lsCompletionItem& item : out.result.items) + item.filterText = item.label; + + FilterAndSortCompletionResponse(&out, result.pattern, + config->completion.filterAndSort); + DecorateIncludePaths(result.match, &out.result.items); + + for (lsCompletionItem& item : out.result.items) { + item.textEdit->range.start.line = request->params.position.line; + item.textEdit->range.start.character = 0; + item.textEdit->range.end.line = request->params.position.line; + item.textEdit->range.end.character = (int)buffer_line.size(); + } } QueueManager::WriteStdout(IpcId::TextDocumentCompletion, out); From 0b087421a732199fca4bde9ac08ee185730db22f Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Sun, 18 Mar 2018 22:52:01 +0000 Subject: [PATCH 013/378] Make CL mode detection fool-proof (#528) --- src/project.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/project.cc b/src/project.cc index a95efdf83..f8c21ccbe 100644 --- a/src/project.cc +++ b/src/project.cc @@ -160,9 +160,22 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (args.empty()) return result; - bool clang_cl = strstr(args[0].c_str(), "clang-cl") || - strstr(args[0].c_str(), "cl.exe") || - AnyStartsWith(args, "--driver-mode=cl"); + std::string first_arg = args[0]; + // Windows' filesystem is not case sensitive, so we compare only + // the lower case variant. + std::transform(first_arg.begin(), first_arg.end(), first_arg.begin(), + tolower); + bool clang_cl = strstr(first_arg.c_str(), "clang-cl") || + strstr(first_arg.c_str(), "cl.exe"); + // Clang only cares about the last --driver-mode flag, so the loop + // iterates in reverse to find the last one as soon as possible + // in case of multiple --driver-mode flags. + for (int i = args.size() - 1; i >= 0; --i) { + if (strstr(args[i].c_str(), "--dirver-mode=")) { + clang_cl = clang_cl || strstr(args[i].c_str(), "--driver-mode=cl"); + break; + } + } size_t i = 1; // If |compilationDatabaseCommand| is specified, the external command provides From fb795d02f96ec3620aa34f016d4b210c39d05029 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sun, 18 Mar 2018 23:57:26 +0100 Subject: [PATCH 014/378] Add SHA256 hashes of LLVM downloads and check them when downloading LLVM --- .../LLVM-5.0.1-win64.exe.SHA256 | 1 + .../LLVM-6.0.0-win64.exe.SHA256 | 1 + ....0.1-amd64-unknown-freebsd10.tar.xz.SHA256 | 1 + ...vm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 | 1 + ...86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 + ...0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 | 1 + ...vm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 | 1 + ...86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 + cmake/DownloadAndExtractLLVM.cmake | 49 +++++++++++++------ 9 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 create mode 100644 clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 diff --git a/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 b/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 new file mode 100644 index 000000000..ed1e6cf3f --- /dev/null +++ b/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 @@ -0,0 +1 @@ +981543611d719624acb29a2cffd6a479cff36e8ab5ee8a57d8eca4f9c4c6956f diff --git a/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 b/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 new file mode 100644 index 000000000..ce28c29ad --- /dev/null +++ b/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 @@ -0,0 +1 @@ +2501887b2f638d3f65b0336f354b96f8108b563522d81e841d5c88c34af283dd diff --git a/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 new file mode 100644 index 000000000..4586d17ff --- /dev/null +++ b/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 @@ -0,0 +1 @@ +86148b850e78aff743e7aaac337a3a94e9ad16d59ee6629a5ff699c31a73c55b diff --git a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 new file mode 100644 index 000000000..b61fe5202 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 @@ -0,0 +1 @@ +c5b105c4960619feb32641ef051fa39ecb913cc0feb6bacebdfa71f8d3cae277 diff --git a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 new file mode 100644 index 000000000..5ea09845f --- /dev/null +++ b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 @@ -0,0 +1 @@ +9e61c6669991e2f0d065348c95917b2c6b697d75098b60ec1c2e9f17093ce012 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 new file mode 100644 index 000000000..0cbc9d405 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 @@ -0,0 +1 @@ +fee8352f5dee2e38fa2bb80ab0b5ef9efef578cbc6892e5c724a1187498119b7 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 new file mode 100644 index 000000000..1d30f273d --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 @@ -0,0 +1 @@ +0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 new file mode 100644 index 000000000..e58383173 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 @@ -0,0 +1 @@ +114e78b2f6db61aaee314c572e07b0d635f653adc5d31bd1cd0bf31a3db4a6e5 diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake index ad285641d..83f82b96a 100644 --- a/cmake/DownloadAndExtractLLVM.cmake +++ b/cmake/DownloadAndExtractLLVM.cmake @@ -1,6 +1,6 @@ # Downloads and extracts the LLVM archive for the current system from # https://releases.llvm.org -# +# # Returns the extracted LLVM archive directory in DOWNLOADED_CLANG_DIR # # Downloads 7-Zip to extract LLVM if it isn't available in the PATH @@ -12,13 +12,8 @@ set(CLANG_ARCHIVE_EXT .tar.xz) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - if(${CLANG_VERSION} STREQUAL 5.0.0) - set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-linux-x86_64-ubuntu14.04) - else() - set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) - endif() + set(CLANG_ARCHIVE_NAME + clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) @@ -39,19 +34,45 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) endif() if(NOT CLANG_ARCHIVE_NAME) - message(FATAL_ERROR "No download available for ${CMAKE_SYSTEM_NAME} + \ -${CLANG_VERSION}") + message(FATAL_ERROR "No LLVM archive url specified for current platform \ +(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.") endif() set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) set(CLANG_ARCHIVE_FILE ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_FULL_NAME}) set(CLANG_ARCHIVE_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_NAME}) -set(CLANG_ARCHIVE_URL +set(CLANG_ARCHIVE_URL https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME}) +set(CLANG_ARCHIVE_HASH_FILE + ${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256) + +if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE}) + message(FATAL_ERROR "No SHA256 hash available for the current platform \ +(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \ +file an issue to get it added.") +endif() + +file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH) +# Strip newline +string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH) if(NOT EXISTS ${CLANG_ARCHIVE_FILE}) message(STATUS "Downloading LLVM ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...") - file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE}) + file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE} + STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT) + + list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE) + if(${ERROR_CODE}) + list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING) + message(FATAL_ERROR ${ERROR_STRING}) + endif() +endif() + +file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH) +if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH}) + message(FATAL_ERROR "SHA256 hash of downloaded LLVM does not match \ +expected hash. Remove the build directory and try running CMake again. If this \ +keeps happening, file an issue to report the problem.") endif() if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) @@ -61,7 +82,7 @@ if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) if(NOT 7ZIP_EXECUTABLE) message(STATUS "7-Zip not found in PATH") download_and_extract_7zip() - find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH + find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH PATHS ${DOWNLOADED_7ZIP_DIR}) else() message(STATUS "7-Zip found in PATH") @@ -70,7 +91,7 @@ if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) message(STATUS "Extracting downloaded LLVM with 7-Zip ...") # Avoid running the LLVM installer by extracting the exe with 7-Zip - execute_process(COMMAND ${7ZIP_EXECUTABLE} x + execute_process(COMMAND ${7ZIP_EXECUTABLE} x -o${CLANG_ARCHIVE_EXTRACT_DIR} -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} OUTPUT_QUIET) From a3f66468ab9f17aadb172236b03b7923118c775b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 19 Mar 2018 00:39:22 -0700 Subject: [PATCH 015/378] Simplify ComputeGuessScore --- src/fuzzy_match.cc | 1 + src/project.cc | 36 +++++++----------------------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 7a76ca0dc..968b5ab5a 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -152,6 +152,7 @@ TEST_SUITE("fuzzy_match") { Ranks("ab", {"ab", "aoo_boo", "acb"}); Ranks("CC", {"CamelCase", "camelCase", "camelcase"}); Ranks("cC", {"camelCase", "CamelCase", "camelcase"}); + Ranks("c c", {"camel case", "camelCase", "CamelCase", "camelcase", "camel ace"}); Ranks("Da.Te", {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"}); // prefix Ranks("is", {"isIEEE", "inSuf"}); diff --git a/src/project.cc b/src/project.cc index f8c21ccbe..6411d1ae6 100644 --- a/src/project.cc +++ b/src/project.cc @@ -496,37 +496,15 @@ std::vector LoadCompilationEntriesFromDirectory( // Computes a score based on how well |a| and |b| match. This is used for // argument guessing. int ComputeGuessScore(const std::string& a, const std::string& b) { - const int kMatchPrefixWeight = 100; - const int kMismatchDirectoryWeight = 100; - const int kMatchPostfixWeight = 1; - - int score = 0; - size_t i = 0; - - // Increase score based on matching prefix. - for (i = 0; i < a.size() && i < b.size(); ++i) { - if (a[i] != b[i]) - break; - score += kMatchPrefixWeight; - } + // Increase score based on common prefix and suffix. Prefixes are prioritized. + size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); + size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); + int score = 10 * i + j; // Reduce score based on mismatched directory distance. - for (size_t j = i; j < a.size(); ++j) { - if (a[j] == '/') - score -= kMismatchDirectoryWeight; - } - for (size_t j = i; j < b.size(); ++j) { - if (b[j] == '/') - score -= kMismatchDirectoryWeight; - } - - // Increase score based on common ending. Don't increase as much as matching - // prefix or directory distance. - for (size_t offset = 1; offset <= a.size() && offset <= b.size(); ++offset) { - if (a[a.size() - offset] != b[b.size() - offset]) - break; - score += kMatchPostfixWeight; - } + if (i + j < std::min(a.size(), b.size())) + score -= 100 * (std::count(a.begin() + i, a.end() - j, '/') + + std::count(b.begin() + i, b.end() - j, '/')); return score; } From 0365e447f03a5aca4e067bfde751afadae5c9adf Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Mon, 19 Mar 2018 17:55:01 +0100 Subject: [PATCH 016/378] Remove leftover comment --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c779f5bf4..0244908c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,6 @@ find_package(Threads REQUIRED) target_link_libraries(cquery PRIVATE Threads::Threads) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - # (either through hardware or OS support) # loguru calls dladdr target_link_libraries(cquery PRIVATE ${CMAKE_DL_LIBS}) @@ -251,4 +250,4 @@ target_sources(cquery PRIVATE src/messages/text_document_type_definition.cc src/messages/workspace_did_change_configuration.cc src/messages/workspace_did_change_watched_files.cc - src/messages/workspace_symbol.cc) \ No newline at end of file + src/messages/workspace_symbol.cc) From b5bd29b7021e87d7de2500d4e373d1a30159f777 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 16:25:35 -0700 Subject: [PATCH 017/378] Restore platform arguments --- src/platform_posix.cc | 4 ++++ src/platform_win.cc | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 18a110746..12cb4a371 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -259,6 +259,10 @@ bool IsSymLink(const std::string& path) { return lstat(path.c_str(), &buf) == 0 && S_ISLNK(buf.st_mode); } +std::vector GetPlatformClangArguments() { + return {}; +} + void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); diff --git a/src/platform_win.cc b/src/platform_win.cc index 726f964ad..027b61506 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -129,6 +129,25 @@ bool IsSymLink(const std::string& path) { return false; } +std::vector GetPlatformClangArguments() { + // + // Found by executing + // + // $ clang++ -E -x c++ - -v + // + // https://clang.llvm.org/docs/MSVCCompatibility.html + // + // + // These options are only needed if clang is targeting the msvc triple, + // which depends on how clang was build for windows. clang downloaded from + // releases.llvm.org defaults to msvc, so cquery does as well. + // + // https://github.com/cquery-project/cquery/issues/509 has more context. + // + return {"-fms-extensions", "-fms-compatibility", + "-fdelayed-template-parsing"}; +} + void FreeUnusedMemory() {} bool RunObjectiveCIndexTests() { From b272fc427cf02cc6f4afa4ca03b8cfe476e5b981 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 16:48:07 -0700 Subject: [PATCH 018/378] Restore call to GetPlatformClangArguments --- src/project.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/project.cc b/src/project.cc index 6411d1ae6..541df6868 100644 --- a/src/project.cc +++ b/src/project.cc @@ -27,6 +27,8 @@ #include #include +extern bool gTestOutputMode; + struct CompileCommandsEntry { std::string directory; std::string file; @@ -208,6 +210,12 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (!AnyStartsWith(args, "-working-directory")) result.args.emplace_back("-working-directory=" + entry.directory); + if (!gTestOutputMode) { + std::vector platform = GetPlatformClangArguments(); + for (auto arg : platform) + result.args.push_back(arg); + } + bool next_flag_is_path = false; bool add_next_flag_to_quote_dirs = false; bool add_next_flag_to_angle_dirs = false; @@ -622,6 +630,7 @@ TEST_SUITE("Project") { std::vector raw, std::vector expected) { g_disable_normalize_path_for_test = true; + gTestOutputMode = true; Config config; ProjectConfig project; From 0dbe8a9171471005ad94886059d5737910818400 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 17:25:00 -0700 Subject: [PATCH 019/378] Don't use std::mismatch. Unit tests crash on Windows. --- src/project.cc | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/project.cc b/src/project.cc index 541df6868..2568ab93c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -504,15 +504,37 @@ std::vector LoadCompilationEntriesFromDirectory( // Computes a score based on how well |a| and |b| match. This is used for // argument guessing. int ComputeGuessScore(const std::string& a, const std::string& b) { - // Increase score based on common prefix and suffix. Prefixes are prioritized. - size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); - size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); - int score = 10 * i + j; + const int kMatchPrefixWeight = 100; + const int kMismatchDirectoryWeight = 100; + const int kMatchPostfixWeight = 1; + + int score = 0; + size_t i = 0; + + // Increase score based on matching prefix. + for (i = 0; i < a.size() && i < b.size(); ++i) { + if (a[i] != b[i]) + break; + score += kMatchPrefixWeight; + } // Reduce score based on mismatched directory distance. - if (i + j < std::min(a.size(), b.size())) - score -= 100 * (std::count(a.begin() + i, a.end() - j, '/') + - std::count(b.begin() + i, b.end() - j, '/')); + for (size_t j = i; j < a.size(); ++j) { + if (a[j] == '/') + score -= kMismatchDirectoryWeight; + } + for (size_t j = i; j < b.size(); ++j) { + if (b[j] == '/') + score -= kMismatchDirectoryWeight; + } + + // Increase score based on common ending. Don't increase as much as matching + // prefix or directory distance. + for (size_t offset = 1; offset <= a.size() && offset <= b.size(); ++offset) { + if (a[a.size() - offset] != b[b.size() - offset]) + break; + score += kMatchPostfixWeight; + } return score; } From 6d42b40319388d7113dd40a42f5827c18ac9ffa5 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 17:30:21 -0700 Subject: [PATCH 020/378] Fix crash when dynamically adding completion item --- src/include_complete.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include_complete.cc b/src/include_complete.cc index 9f4476c02..18d3e8f12 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -139,8 +139,9 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, // insert if not found or with shorter include path auto it = absolute_path_to_completion_item.find(absolute_path); if (it == absolute_path_to_completion_item.end() || - completion_items[it->second].detail.length() > item.detail.length()) - absolute_path_to_completion_item[absolute_path] = completion_items.size(); + completion_items[it->second].detail.length() > item.detail.length()) { + absolute_path_to_completion_item[absolute_path] = completion_items.size() - 1; + } } else { lsCompletionItem& inserted_item = completion_items[inserted_paths[item.detail]]; From 3f5e34ef20ec059ad19265bb4c47d908806e7c93 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 19:50:22 -0700 Subject: [PATCH 021/378] Restore include completion on # --- src/messages/text_document_completion.cc | 53 +++++++++++------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index cf4300057..c14e360fd 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -115,7 +115,7 @@ ParseIncludeLineResult ParseIncludeLine(const std::string& line) { "(.*)"); // [7]: suffix after quote char std::smatch match; bool ok = std::regex_match(line, match, pattern); - std::string text = match[6].str(); + std::string text = match[3].str() + match[6].str(); return {ok, text, match}; } @@ -298,33 +298,30 @@ struct TextDocumentCompletionHandler : MessageHandler { Out_TextDocumentComplete out; out.id = request->id; - std::string text = result.match[3]; - if (std::string_view("include").compare(0, text.size(), text) == 0) { - { - std::unique_lock lock( - include_complete->completion_items_mutex, std::defer_lock); - if (include_complete->is_scanning) - lock.lock(); - std::string quote = result.match[5]; - for (auto& item : include_complete->completion_items) - if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) - out.result.items.push_back(item); - } - - // Needed by |FilterAndSortCompletionResponse|. - for (lsCompletionItem& item : out.result.items) - item.filterText = item.label; - - FilterAndSortCompletionResponse(&out, result.pattern, - config->completion.filterAndSort); - DecorateIncludePaths(result.match, &out.result.items); - - for (lsCompletionItem& item : out.result.items) { - item.textEdit->range.start.line = request->params.position.line; - item.textEdit->range.start.character = 0; - item.textEdit->range.end.line = request->params.position.line; - item.textEdit->range.end.character = (int)buffer_line.size(); - } + { + std::unique_lock lock( + include_complete->completion_items_mutex, std::defer_lock); + if (include_complete->is_scanning) + lock.lock(); + std::string quote = result.match[5]; + for (auto& item : include_complete->completion_items) + if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + out.result.items.push_back(item); + } + + // Needed by |FilterAndSortCompletionResponse|. + for (lsCompletionItem& item : out.result.items) + item.filterText = item.label; + + FilterAndSortCompletionResponse(&out, result.pattern, + config->completion.filterAndSort); + DecorateIncludePaths(result.match, &out.result.items); + + for (lsCompletionItem& item : out.result.items) { + item.textEdit->range.start.line = request->params.position.line; + item.textEdit->range.start.character = 0; + item.textEdit->range.end.line = request->params.position.line; + item.textEdit->range.end.character = (int)buffer_line.size(); } QueueManager::WriteStdout(IpcId::TextDocumentCompletion, out); From c7e5299bee604044a4194c938f539e0afda45696 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 19:51:42 -0700 Subject: [PATCH 022/378] Reformat --- src/clang_complete.cc | 4 +- src/clang_complete.h | 2 +- src/clang_cursor.h | 2 +- src/clang_indexer.cc | 26 +++++------ src/clang_utils.cc | 2 +- src/command_line.cc | 5 ++- src/config.h | 4 +- src/diagnostics_engine.cc | 14 +++--- src/fuzzy_match.cc | 5 ++- src/fuzzy_match.h | 4 +- src/import_pipeline.cc | 2 +- src/include_complete.cc | 5 ++- src/indexer.h | 11 ++--- src/ipc.cc | 6 ++- src/ipc.h | 2 +- src/lex_utils.cc | 3 +- src/lsp.cc | 2 +- src/message_handler.cc | 2 +- src/messages/cquery_base.cc | 12 ++--- src/messages/cquery_call_hierarchy.cc | 16 ++++--- src/messages/cquery_derived.cc | 12 ++--- src/messages/cquery_inheritance_hierarchy.cc | 8 ++-- src/messages/cquery_member_hierarchy.cc | 44 +++++++++---------- src/messages/text_document_code_action.cc | 4 +- src/messages/text_document_code_lens.cc | 15 ++++--- src/messages/text_document_completion.cc | 12 ++--- src/messages/text_document_definition.cc | 3 +- src/messages/text_document_document_symbol.cc | 3 +- src/messages/text_document_type_definition.cc | 32 +++++++------- .../workspace_did_change_configuration.cc | 4 +- src/messages/workspace_symbol.cc | 3 +- src/project.cc | 5 +-- src/project.h | 8 ++-- src/query_utils.cc | 3 +- src/query_utils.h | 17 ++++--- src/queue_manager.h | 2 +- src/semantic_highlight_symbol_cache.cc | 2 +- src/test.cc | 2 +- src/threaded_queue.h | 8 +--- 39 files changed, 165 insertions(+), 151 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 0eec9a710..734dcf304 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -94,7 +94,7 @@ lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { return lsCompletionItemKind::Method; case CXCursor_FunctionTemplate: - return lsCompletionItemKind::Function; + return lsCompletionItemKind::Function; case CXCursor_Constructor: case CXCursor_Destructor: @@ -186,7 +186,7 @@ void BuildCompletionItemTexts(std::vector& out, case CXCompletionChunk_Equal: text = '='; break; case CXCompletionChunk_HorizontalSpace: text = ' '; break; case CXCompletionChunk_VerticalSpace: text = ' '; break; - // clang-format on + // clang-format on case CXCompletionChunk_ResultType: result_type = diff --git a/src/clang_complete.h b/src/clang_complete.h index cf7524178..ef5060057 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -2,9 +2,9 @@ #include "clang_index.h" #include "clang_translation_unit.h" +#include "lru_cache.h" #include "lsp_completion.h" #include "lsp_diagnostic.h" -#include "lru_cache.h" #include "project.h" #include "threaded_queue.h" #include "working_files.h" diff --git a/src/clang_cursor.h b/src/clang_cursor.h index f7129b9de..23eed1bb1 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -29,7 +29,7 @@ class ClangType { // NOTE: This will return false for pointed types. Should we call // strip_qualifiers for the user? return cx_type.kind >= CXType_FirstBuiltin && - cx_type.kind <= CXType_LastBuiltin; + cx_type.kind <= CXType_LastBuiltin; } ClangCursor get_declaration() const; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index e4596639b..4e2b571b8 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -493,16 +493,16 @@ Use SetUse(IndexFile* db, Range range, ClangCursor parent, Role role) { const char* GetAnonName(CXCursorKind kind) { switch (kind) { - case CXCursor_ClassDecl: - return "(anon class)"; - case CXCursor_EnumDecl: - return "(anon enum)"; - case CXCursor_StructDecl: - return "(anon struct)"; - case CXCursor_UnionDecl: - return "(anon union)"; - default: - return "(anon)"; + case CXCursor_ClassDecl: + return "(anon class)"; + case CXCursor_EnumDecl: + return "(anon enum)"; + case CXCursor_StructDecl: + return "(anon struct)"; + case CXCursor_UnionDecl: + return "(anon union)"; + default: + return "(anon)"; } } @@ -779,7 +779,7 @@ void Uniquify(std::vector& uses) { } // FIXME Reference: set id in call sites and remove this -//void AddUse(std::vector& values, Range value) { +// void AddUse(std::vector& values, Range value) { // values.push_back( // Use(value, Id(), SymbolKind::File, Role::Reference, {})); //} @@ -1811,8 +1811,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // TODO: For type section, verify if this ever runs for non definitions? // if (!decl->isRedeclaration) { - SetTypeName(type, cursor, decl->semanticContainer, - decl->entityInfo->name, param); + SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, + param); type->def.kind = GetSymbolKind(decl->entityInfo->kind); if (param->config->index.comments) type->def.comments = cursor.get_comments(); diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 8be4a15ca..03a35d754 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -177,7 +177,7 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { #endif case CXType_NullPtr: return "nullptr"; default: return ""; - // clang-format on + // clang-format on } } diff --git a/src/command_line.cc b/src/command_line.cc index 717ba3af8..8a58da027 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -8,9 +8,9 @@ #include "import_pipeline.h" #include "include_complete.h" #include "indexer.h" -#include "lsp_diagnostic.h" #include "lex_utils.h" #include "lru_cache.h" +#include "lsp_diagnostic.h" #include "match.h" #include "message_handler.h" #include "options.h" @@ -196,7 +196,8 @@ void RunQueryDbThread(const std::string& bin_name, Out_Error out; out.id = id; out.error.code = lsErrorCodes::InternalError; - out.error.message = "Dropping completion request; a newer request " + out.error.message = + "Dropping completion request; a newer request " "has come in that will be serviced instead."; QueueManager::WriteStdout(IpcId::Unknown, out); } diff --git a/src/config.h b/src/config.h index f06397a5c..9ca7ab5b4 100644 --- a/src/config.h +++ b/src/config.h @@ -238,9 +238,7 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, frequencyMs, onParse, whitelist) -MAKE_REFLECT_STRUCT(Config::Highlight, - blacklist, - whitelist) +MAKE_REFLECT_STRUCT(Config::Highlight, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist, diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 8d66325f0..36453ea27 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -7,7 +7,7 @@ void DiagnosticsEngine::Init(Config* config) { frequencyMs_ = config->diagnostics.frequencyMs; match_ = std::make_unique(config->diagnostics.whitelist, - config->diagnostics.blacklist); + config->diagnostics.blacklist); } void DiagnosticsEngine::Publish(WorkingFiles* working_files, @@ -15,12 +15,14 @@ void DiagnosticsEngine::Publish(WorkingFiles* working_files, std::vector diagnostics) { // Cache diagnostics so we can show fixits. working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { - if (working_file) - working_file->diagnostics_ = diagnostics; - }); + if (working_file) + working_file->diagnostics_ = diagnostics; + }); - int64_t now = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + int64_t now = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); if (frequencyMs_ >= 0 && (nextPublish_ <= now || diagnostics.empty()) && match_->IsMatch(path)) { nextPublish_ = now + frequencyMs_; diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 968b5ab5a..859307422 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -43,7 +43,7 @@ void CalculateRoles(std::string_view s, int roles[], int* class_set) { } roles[s.size() - 1] = fn(); } -} +} // namespace int FuzzyMatcher::MissScore(int j, bool last) { int s = last ? -20 : 0; @@ -152,7 +152,8 @@ TEST_SUITE("fuzzy_match") { Ranks("ab", {"ab", "aoo_boo", "acb"}); Ranks("CC", {"CamelCase", "camelCase", "camelcase"}); Ranks("cC", {"camelCase", "CamelCase", "camelcase"}); - Ranks("c c", {"camel case", "camelCase", "CamelCase", "camelcase", "camel ace"}); + Ranks("c c", + {"camel case", "camelCase", "CamelCase", "camelcase", "camel ace"}); Ranks("Da.Te", {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"}); // prefix Ranks("is", {"isIEEE", "inSuf"}); diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 79599857c..336815b72 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -6,7 +6,7 @@ #include class FuzzyMatcher { -public: + public: constexpr static int kMaxPat = 100; constexpr static int kMaxText = 200; // Negative but far from INT_MIN so that intermediate results are hard to @@ -16,7 +16,7 @@ class FuzzyMatcher { FuzzyMatcher(std::string_view pattern); int Match(std::string_view text); -private: + private: std::string pat; std::string_view text; int pat_set, text_set; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index dc84f642a..8052083fa 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -679,7 +679,7 @@ void QueryDb_DoIdMap(QueueManager* queue, auto id_map = std::make_unique(db, file->id_cache); return std::make_unique(std::move(file), - std::move(id_map)); + std::move(id_map)); }; response.current = make_map(std::move(request->current)); response.previous = make_map(std::move(request->previous)); diff --git a/src/include_complete.cc b/src/include_complete.cc index 18d3e8f12..f063d6d6e 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -113,7 +113,7 @@ void IncludeComplete::Rescan() { if (!match_ && (!config_->completion.includeWhitelist.empty() || !config_->completion.includeBlacklist.empty())) match_ = std::make_unique(config_->completion.includeWhitelist, - config_->completion.includeBlacklist); + config_->completion.includeBlacklist); is_scanning = true; WorkThread::StartThread("scan_includes", [this]() { @@ -140,7 +140,8 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, auto it = absolute_path_to_completion_item.find(absolute_path); if (it == absolute_path_to_completion_item.end() || completion_items[it->second].detail.length() > item.detail.length()) { - absolute_path_to_completion_item[absolute_path] = completion_items.size() - 1; + absolute_path_to_completion_item[absolute_path] = + completion_items.size() - 1; } } else { lsCompletionItem& inserted_item = diff --git a/src/indexer.h b/src/indexer.h index c671fca37..922e75249 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -180,10 +180,9 @@ struct TypeDefDefinitionData { bool operator==(const TypeDefDefinitionData& o) const { return detailed_name == o.detailed_name && spell == o.spell && - extent == o.extent && alias_of == o.alias_of && - bases == o.bases && types == o.types && funcs == o.funcs && - vars == o.vars && kind == o.kind && hover == o.hover && - comments == o.comments; + extent == o.extent && alias_of == o.alias_of && bases == o.bases && + types == o.types && funcs == o.funcs && vars == o.vars && + kind == o.kind && hover == o.hover && comments == o.comments; } bool operator!=(const TypeDefDefinitionData& o) const { return !(*this == o); @@ -194,9 +193,7 @@ struct TypeDefDefinitionData { short_name_size); } // Used by cquery_inheritance_hierarchy.cc:Expand generic lambda - std::string_view DetailedName(bool) const { - return detailed_name; - } + std::string_view DetailedName(bool) const { return detailed_name; } }; template void Reflect(TVisitor& visitor, TypeDefDefinitionData& value) { diff --git a/src/ipc.cc b/src/ipc.cc index 27598672d..90c75f9b1 100644 --- a/src/ipc.cc +++ b/src/ipc.cc @@ -11,8 +11,10 @@ const char* IpcIdToString(IpcId id) { case IpcId::Exit: return "exit"; -#define CASE(name, method) case IpcId::name: return method; - #include "methods.inc" +#define CASE(name, method) \ + case IpcId::name: \ + return method; +#include "methods.inc" #undef CASE case IpcId::Unknown: diff --git a/src/ipc.h b/src/ipc.h index 55a1139a8..3992e0589 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -14,7 +14,7 @@ enum class IpcId : int { Exit, #define CASE(x, _) x, - #include "methods.inc" +#include "methods.inc" #undef CASE // Internal implementation detail. diff --git a/src/lex_utils.cc b/src/lex_utils.cc index c7e5700f7..ebbe496a6 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -355,7 +355,8 @@ TEST_SUITE("LexWordAroundPos") { std::string content = " file:ns::_my_t5ype7 "; REQUIRE(LexIdentifierAroundPos(CharPos(content, 'f'), content) == "file"); REQUIRE(LexIdentifierAroundPos(CharPos(content, 's'), content) == "ns"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'y'), content) == "ns::_my_t5ype7"); + REQUIRE(LexIdentifierAroundPos(CharPos(content, 'y'), content) == + "ns::_my_t5ype7"); } TEST_CASE("dot, dash, colon are skipped") { diff --git a/src/lsp.cc b/src/lsp.cc index 47d869eab..38fdee6fe 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -4,8 +4,8 @@ #include "serializers/json.h" #include -#include #include +#include #include #include diff --git a/src/message_handler.cc b/src/message_handler.cc index 35ceae777..a00bc8593 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -145,7 +145,7 @@ void EmitSemanticHighlighting(QueryDatabase* db, if (def->spell) parent_kind = GetSymbolKind(db, *def->spell); if (parent_kind == lsSymbolKind::Unknown) { - for (Use use: func.declarations) { + for (Use use : func.declarations) { parent_kind = GetSymbolKind(db, use); break; } diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index 3c970e124..6a11a0644 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -27,15 +27,15 @@ struct CqueryBaseHandler : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { if (const auto* def = db->GetType(sym).AnyDef()) - out.result = - GetLsLocationExs(db, working_files, GetDeclarations(db, def->bases), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db, def->bases), + config->xref.container, config->xref.maxNum); break; } else if (sym.kind == SymbolKind::Func) { if (const auto* def = db->GetFunc(sym).AnyDef()) - out.result = - GetLsLocationExs(db, working_files, GetDeclarations(db, def->bases), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db, def->bases), + config->xref.container, config->xref.maxNum); break; } } diff --git a/src/messages/cquery_call_hierarchy.cc b/src/messages/cquery_call_hierarchy.cc index aadac31b6..594ce931d 100644 --- a/src/messages/cquery_call_hierarchy.cc +++ b/src/messages/cquery_call_hierarchy.cc @@ -5,7 +5,12 @@ #include namespace { -enum class CallType : uint8_t { Direct = 0, Base = 1, Derived = 2, All = 1 | 2 }; +enum class CallType : uint8_t { + Direct = 0, + Base = 1, + Derived = 2, + All = 1 | 2 +}; MAKE_REFLECT_TYPE_PROXY(CallType); bool operator&(CallType lhs, CallType rhs) { @@ -96,7 +101,8 @@ bool Expand(MessageHandler* m, if (const auto* def = func.AnyDef()) for (SymbolRef ref : def->callees) if (ref.kind == SymbolKind::Func) - handle(Use(ref.range, ref.id, ref.kind, ref.role, def->file), call_type); + handle(Use(ref.range, ref.id, ref.kind, ref.role, def->file), + call_type); } else { for (Use use : func.uses) if (use.kind == SymbolKind::Func) @@ -165,7 +171,7 @@ struct CqueryCallHierarchyHandler entry.callType = CallType::Direct; if (def->spell) { if (optional loc = - GetLsLocation(db, working_files, *def->spell)) + GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } Expand(this, &entry, callee, call_type, detailed_name, levels); @@ -193,11 +199,11 @@ struct CqueryCallHierarchyHandler WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { + FindSymbolsAtLocation(working_file, file, params.position)) { if (sym.kind == SymbolKind::Func) { out.result = BuildInitial(QueryFuncId(sym.id), params.callee, params.callType, - params.detailedName, params.levels); + params.detailedName, params.levels); break; } } diff --git a/src/messages/cquery_derived.cc b/src/messages/cquery_derived.cc index 6e0565848..08e7033f1 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/cquery_derived.cc @@ -27,15 +27,15 @@ struct CqueryDerivedHandler : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { QueryType& type = db->GetType(sym); - out.result = - GetLsLocationExs(db, working_files, GetDeclarations(db, type.derived), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db, type.derived), + config->xref.container, config->xref.maxNum); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); - out.result = - GetLsLocationExs(db, working_files, GetDeclarations(db, func.derived), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db, func.derived), + config->xref.container, config->xref.maxNum); break; } } diff --git a/src/messages/cquery_inheritance_hierarchy.cc b/src/messages/cquery_inheritance_hierarchy.cc index 1d702a9cc..d81df3434 100644 --- a/src/messages/cquery_inheritance_hierarchy.cc +++ b/src/messages/cquery_inheritance_hierarchy.cc @@ -7,8 +7,8 @@ struct Ipc_CqueryInheritanceHierarchy : public RequestMessage { const static IpcId kIpcId = IpcId::CqueryInheritanceHierarchy; struct Params { - // If id+kind are specified, expand a node; otherwise textDocument+position should - // be specified for building the root and |levels| of nodes below. + // If id+kind are specified, expand a node; otherwise textDocument+position + // should be specified for building the root and |levels| of nodes below. lsTextDocumentIdentifier textDocument; lsPosition position; @@ -161,8 +161,8 @@ struct CqueryInheritanceHierarchyHandler WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, + request->params.position)) { if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { out.result = BuildInitial(sym, params.derived, params.detailedName, params.levels); diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/cquery_member_hierarchy.cc index 0314a425d..8245c8571 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/cquery_member_hierarchy.cc @@ -75,7 +75,7 @@ void DoField(MessageHandler* m, entry1.fieldName = std::string(def1->ShortName()); if (def1->spell) { if (optional loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->working_files, *def1->spell)) entry1.location = *loc; } if (def1->type) { @@ -128,7 +128,7 @@ bool Expand(MessageHandler* m, if (def1 && def1->spell) { // The declaration of target type. if (optional loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->working_files, *def1->spell)) entry1.location = *loc; } else if (def->spell) { // Builtin types have no declaration but the typedef declaration @@ -175,7 +175,7 @@ struct CqueryMemberHierarchyHandler entry.name = std::string(def->ShortName()); if (def->spell) { if (optional loc = - GetLsLocation(db, working_files, *def->spell)) + GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } EachDefinedEntity(db->vars, def->vars, [&](QueryVar& var) { @@ -195,7 +195,7 @@ struct CqueryMemberHierarchyHandler entry.id = root_id; if (def->spell) { if (optional loc = - GetLsLocation(db, working_files, *def->spell)) + GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } Expand(this, &entry, detailed_name, levels); @@ -220,27 +220,27 @@ struct CqueryMemberHierarchyHandler params.textDocument.uri.GetPath(), &file)) return; WorkingFile* working_file = - working_files->GetFileByFilename(file->def->path); + working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { + FindSymbolsAtLocation(working_file, file, params.position)) { switch (sym.kind) { - case SymbolKind::Func: - out.result = BuildInitial(QueryFuncId(sym.id), params.detailedName, - params.levels); - break; - case SymbolKind::Type: - out.result = BuildInitial(QueryTypeId(sym.id), params.detailedName, - params.levels); - break; - case SymbolKind::Var: { - const QueryVar::Def* def = db->GetVar(sym).AnyDef(); - if (def && def->type) - out.result = BuildInitial(QueryTypeId(*def->type), params.detailedName, + case SymbolKind::Func: + out.result = BuildInitial(QueryFuncId(sym.id), params.detailedName, params.levels); - break; - } - default: - continue; + break; + case SymbolKind::Type: + out.result = BuildInitial(QueryTypeId(sym.id), params.detailedName, + params.levels); + break; + case SymbolKind::Var: { + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def && def->type) + out.result = BuildInitial(QueryTypeId(*def->type), + params.detailedName, params.levels); + break; + } + default: + continue; } break; } diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index df569e5c3..559cae308 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -441,8 +441,8 @@ struct TextDocumentCodeActionHandler // For error diagnostics, provide an action to resolve an include. // TODO: find a way to index diagnostic contents so line numbers // don't get mismatched when actively editing a file. - std::string_view include_query = - LexIdentifierAroundPos(diag.range.start, working_file->buffer_content); + std::string_view include_query = LexIdentifierAroundPos( + diag.range.start, working_file->buffer_content); if (diag.severity == lsDiagnosticSeverity::Error && !include_query.empty()) { const size_t kMaxResults = 20; diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 792c84264..239a543a2 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -118,9 +118,11 @@ struct TextDocumentCodeLensHandler AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), type.uses, true /*force_display*/); AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), - GetDeclarations(db, type.derived), false /*force_display*/); + GetDeclarations(db, type.derived), + false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetDeclarations(db, type.instances), false /*force_display*/); + GetDeclarations(db, type.instances), + false /*force_display*/); break; } case SymbolKind::Func: { @@ -164,9 +166,9 @@ struct TextDocumentCodeLensHandler false /*force_display*/); } - AddCodeLens("derived", "derived", &common, - OffsetStartColumn(use, offset++), - GetDeclarations(db, func.derived), false /*force_display*/); + AddCodeLens( + "derived", "derived", &common, OffsetStartColumn(use, offset++), + GetDeclarations(db, func.derived), false /*force_display*/); // "Base" if (def->bases.size() == 1) { @@ -193,7 +195,8 @@ struct TextDocumentCodeLensHandler } } else { AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), - GetDeclarations(db, def->bases), false /*force_display*/); + GetDeclarations(db, def->bases), + false /*force_display*/); } break; diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index c14e360fd..aec06e27c 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -197,10 +197,10 @@ void FilterAndSortCompletionResponse( : FuzzyMatcher::kMinScore; } items.erase(std::remove_if(items.begin(), items.end(), - [](const lsCompletionItem& item) { - return item.score_ <= FuzzyMatcher::kMinScore; - }), - items.end()); + [](const lsCompletionItem& item) { + return item.score_ <= FuzzyMatcher::kMinScore; + }), + items.end()); std::sort(items.begin(), items.end(), [](const lsCompletionItem& lhs, const lsCompletionItem& rhs) { if (lhs.score_ != rhs.score_) @@ -300,7 +300,7 @@ struct TextDocumentCompletionHandler : MessageHandler { { std::unique_lock lock( - include_complete->completion_items_mutex, std::defer_lock); + include_complete->completion_items_mutex, std::defer_lock); if (include_complete->is_scanning) lock.lock(); std::string quote = result.match[5]; @@ -314,7 +314,7 @@ struct TextDocumentCompletionHandler : MessageHandler { item.filterText = item.label; FilterAndSortCompletionResponse(&out, result.pattern, - config->completion.filterAndSort); + config->completion.filterAndSort); DecorateIncludePaths(result.match, &out.result.items); for (lsCompletionItem& item : out.result.items) { diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 62f365856..e5823794c 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -156,8 +156,7 @@ struct TextDocumentDefinitionHandler } } if (best_i != -1) { - Maybe use = - GetDefinitionSpell(db, db->symbols[best_i]); + Maybe use = GetDefinitionSpell(db, db->symbols[best_i]); assert(use); if (auto ls_loc = GetLsLocationEx(db, working_files, *use, config->xref.container)) diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index b6631bd12..54e5cf28f 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -45,7 +45,8 @@ struct TextDocumentDocumentSymbolHandler if (sym.kind == SymbolKind::Var) { QueryVar& var = db->GetVar(sym); auto* def = var.AnyDef(); - if (!def || !def->spell) continue; + if (!def || !def->spell) + continue; // Ignore local variables. if (def->spell->kind == SymbolKind::Func && def->storage != StorageClass::Static && diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 9745862b1..dac467aee 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -22,21 +22,21 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentTypeDefinition, jsonrpc, id, result); struct TextDocumentTypeDefinitionHandler : BaseMessageHandler { void Run(Ipc_TextDocumentTypeDefinition* request) override { - QueryFile* file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - nullptr)) { - return; - } - WorkingFile* working_file = - working_files->GetFileByFilename(file->def->path); + QueryFile* file; + if (!FindFileOrFail(db, project, request->id, + request->params.textDocument.uri.GetPath(), &file, + nullptr)) { + return; + } + WorkingFile* working_file = + working_files->GetFileByFilename(file->def->path); - Out_TextDocumentTypeDefinition out; - out.id = request->id; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - Id id = sym.id; - switch (sym.kind) { + Out_TextDocumentTypeDefinition out; + out.id = request->id; + for (SymbolRef sym : + FindSymbolsAtLocation(working_file, file, request->params.position)) { + Id id = sym.id; + switch (sym.kind) { case SymbolKind::Var: { const QueryVar::Def* def = db->GetVar(sym).AnyDef(); if (!def || !def->type) @@ -56,10 +56,10 @@ struct TextDocumentTypeDefinitionHandler } default: break; - } } + } - QueueManager::WriteStdout(IpcId::TextDocumentTypeDefinition, out); + QueueManager::WriteStdout(IpcId::TextDocumentTypeDefinition, out); } }; REGISTER_MESSAGE_HANDLER(TextDocumentTypeDefinitionHandler); diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 29b5f57d9..7b90fc8d1 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -25,11 +25,11 @@ struct WorkspaceDidChangeConfigurationHandler Timer time; project->Load(config, config->projectRoot); time.ResetAndPrint("[perf] Loaded compilation entries (" + - std::to_string(project->entries.size()) + " files)"); + std::to_string(project->entries.size()) + " files)"); time.Reset(); project->Index(config, QueueManager::instance(), working_files, - std::monostate()); + std::monostate()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); } diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 9595baf8e..092167122 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -107,7 +107,8 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { for (int i = 0; i < (int)db->symbols.size(); ++i) { std::string_view detailed_name = db->GetSymbolDetailedName(i); - if (CaseFoldingSubsequenceMatch(query_without_space, detailed_name).first) { + if (CaseFoldingSubsequenceMatch(query_without_space, detailed_name) + .first) { // Do not show the same entry twice. if (!inserted_results.insert(std::string(detailed_name)).second) continue; diff --git a/src/project.cc b/src/project.cc index 2568ab93c..0c476a714 100644 --- a/src/project.cc +++ b/src/project.cc @@ -89,8 +89,7 @@ std::vector kPathArgs = { "-I", "-iquote", "-isystem", "--sysroot=", "-isysroot", "-gcc-toolchain", "-include-pch", "-iframework", "-F", "-imacros", "-include", "/I", - "-idirafter" -}; + "-idirafter"}; // Arguments which always require an absolute path, ie, clang -working-directory // does not work as expected. Argument processing assumes that this is a subset @@ -431,7 +430,7 @@ std::vector LoadCompilationEntriesFromDirectory( comp_db_dir.c_str(), &cx_db_load_error); if (!config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 - // TODO + // TODO #else unlink((comp_db_dir + "/compile_commands.json").c_str()); rmdir(comp_db_dir.c_str()); diff --git a/src/project.h b/src/project.h index 17e41c591..db93f4b29 100644 --- a/src/project.h +++ b/src/project.h @@ -38,10 +38,10 @@ struct Project { // compile_commands.json in it, otherwise they are retrieved in // |root_directory|. // For .cquery, recursive directory listing is used and files with known - // suffixes are indexed. .cquery files can exist in subdirectories and they will affect - // flags in their subtrees (relative paths are relative to the project root, - // not subdirectories). - // For compile_commands.json, its entries are indexed. + // suffixes are indexed. .cquery files can exist in subdirectories and they + // will affect flags in their subtrees (relative paths are relative to the + // project root, not subdirectories). For compile_commands.json, its entries + // are indexed. void Load(Config* config, const std::string& root_directory); // Lookup the CompilationEntry for |filename|. If no entry was found this diff --git a/src/query_utils.cc b/src/query_utils.cc index 7377ad176..81bab28f7 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -100,8 +100,7 @@ std::vector GetDeclarations(QueryDatabase* db, return GetDeclarations(db->vars, ids); } -std::vector GetNonDefDeclarations(QueryDatabase* db, - SymbolIdx sym) { +std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym) { switch (sym.kind) { case SymbolKind::Func: return db->GetFunc(sym).declarations; diff --git a/src/query_utils.h b/src/query_utils.h index f9a10a6ad..f7f43a57f 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -10,10 +10,14 @@ Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); Maybe GetDeclarationFileForSymbol(QueryDatabase* db, SymbolIdx sym); -// Get defining declaration (if exists) or an arbitrary declaration (otherwise) for each id. -std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); -std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); -std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); +// Get defining declaration (if exists) or an arbitrary declaration (otherwise) +// for each id. +std::vector GetDeclarations(QueryDatabase* db, + const std::vector& ids); +std::vector GetDeclarations(QueryDatabase* db, + const std::vector& ids); +std::vector GetDeclarations(QueryDatabase* db, + const std::vector& ids); // Get non-defining declarations. std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym); @@ -78,7 +82,10 @@ void EachEntityDef(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { } template -void EachOccurrence(QueryDatabase* db, SymbolIdx sym, bool include_decl, Fn&& fn) { +void EachOccurrence(QueryDatabase* db, + SymbolIdx sym, + bool include_decl, + Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { for (Use use : entity.uses) fn(use); diff --git a/src/queue_manager.h b/src/queue_manager.h index 46312d541..61db1d233 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -81,7 +81,7 @@ struct Index_OnIndexed { class QueueManager { static std::unique_ptr instance_; -public: + public: static QueueManager* instance() { return instance_.get(); } static void Init(MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter, diff --git a/src/semantic_highlight_symbol_cache.cc b/src/semantic_highlight_symbol_cache.cc index 5992b5d4c..10f8ebc41 100644 --- a/src/semantic_highlight_symbol_cache.cc +++ b/src/semantic_highlight_symbol_cache.cc @@ -62,7 +62,7 @@ SemanticHighlightSymbolCache::SemanticHighlightSymbolCache() void SemanticHighlightSymbolCache::Init(Config* config) { match_ = std::make_unique(config->highlight.whitelist, - config->highlight.blacklist); + config->highlight.blacklist); } std::shared_ptr diff --git a/src/test.cc b/src/test.cc index 429da3297..925a82f46 100644 --- a/src/test.cc +++ b/src/test.cc @@ -6,11 +6,11 @@ #include "utils.h" #include -#include #include #include #include #include +#include #include #include diff --git a/src/threaded_queue.h b/src/threaded_queue.h index aeaab5d19..5f9404e0d 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -32,12 +32,8 @@ template struct MultiQueueLock { MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); } ~MultiQueueLock() { unlock(); } - void lock() { - lock_impl(typename std::index_sequence_for{}); - } - void unlock() { - unlock_impl(typename std::index_sequence_for{}); - } + void lock() { lock_impl(typename std::index_sequence_for{}); } + void unlock() { unlock_impl(typename std::index_sequence_for{}); } private: template From 7c1155392aff76b12582723d9b9b8fdcb35753c5 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 19 Mar 2018 20:01:23 -0700 Subject: [PATCH 023/378] Try to prevent long queue lengths. --- src/import_pipeline.cc | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 8052083fa..a12d8836e 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -45,6 +45,22 @@ MAKE_REFLECT_STRUCT(Out_Progress::Params, activeThreads); MAKE_REFLECT_STRUCT(Out_Progress, jsonrpc, method, params); +// Instead of processing messages forever, we only process upto +// |kIterationSize| messages of a type at one time. While the import time +// likely stays the same, this should reduce overall queue lengths which means +// the user gets a usable index faster. +struct IterationLoop { + const int kIterationSize = 100; + int count = 0; + + bool Next() { + return count++ < kIterationSize; + } + void Reset() { + count = 0; + } +}; + struct IModificationTimestampFetcher { virtual ~IModificationTimestampFetcher() = default; virtual optional GetModificationTime(const std::string& path) = 0; @@ -522,7 +538,8 @@ bool IndexMergeIndexUpdates() { return false; bool did_merge = false; - while (true) { + IterationLoop loop; + while (loop.Next()) { optional to_join = queue->on_indexed.TryPopBack(); if (!to_join) { queue->on_indexed.PushFront(std::move(*root)); @@ -599,7 +616,8 @@ void Indexer_Main(Config* config, // Build one index per-indexer, as building the index acquires a global lock. auto indexer = IIndexer::MakeClangIndexer(); - while (true) { + IterationLoop loop; + while (loop.Next()) { bool did_work = false; { @@ -726,6 +744,7 @@ void QueryDb_OnIndexed(QueueManager* queue, import_manager->DoneQueryDbImport(updated_file.value.path); } } + } // namespace bool QueryDb_ImportMain(Config* config, @@ -740,7 +759,8 @@ bool QueryDb_ImportMain(Config* config, bool did_work = false; - while (true) { + IterationLoop loop; + while (loop.Next()) { optional request = queue->do_id_map.TryPopFront(); if (!request) break; @@ -748,7 +768,8 @@ bool QueryDb_ImportMain(Config* config, QueryDb_DoIdMap(queue, db, import_manager, &*request); } - while (true) { + loop.Reset(); + while (loop.Next()) { optional response = queue->on_indexed.TryPopFront(); if (!response) break; From c6ea1f19467f4500e56d03e03405f2dd115f557d Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Mon, 19 Mar 2018 21:28:11 +0100 Subject: [PATCH 024/378] Conditionally allow reindex on didChange --- src/config.h | 6 ++++++ src/messages/text_document_did_change.cc | 17 +++++++++++++++++ src/messages/text_document_did_save.cc | 23 +++++++++++++---------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/config.h b/src/config.h index 9ca7ab5b4..9030a9031 100644 --- a/src/config.h +++ b/src/config.h @@ -212,6 +212,10 @@ struct Config { bool sort = true; } workspaceSymbol; + // Allow indexing on textDocument/didChange. + // May be too slow for big projects, so it is off by default. + bool enableIndexOnDidChange = false; + struct Xref { // If true, |Location[]| response will include lexical container. bool container = false; @@ -272,6 +276,8 @@ MAKE_REFLECT_STRUCT(Config, index, workspaceSymbol, xref, + + enableIndexOnDidChange, dumpAST); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 90e6dc9cc..d32f20977 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -1,6 +1,11 @@ +#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" +#include "project.h" #include "working_files.h" +#include "queue_manager.h" + +#include namespace { struct Ipc_TextDocumentDidChange @@ -17,6 +22,18 @@ struct TextDocumentDidChangeHandler void Run(Ipc_TextDocumentDidChange* request) override { std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); + if (config->enableIndexOnDidChange) { + optional content = ReadContent(path); + if (!content) { + LOG_S(ERROR) << "Unable to read file content after saving " << path; + } else { + Project::Entry entry = project->FindCompilationEntryForFile(path); + QueueManager::instance()->index_request.PushBack( + Index_Request(entry.filename, entry.args, true /*is_interactive*/, + *content, ICacheManager::Make(config)), + true); + } + } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( std::monostate(), diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index f76292870..3635d7679 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -34,7 +34,8 @@ struct TextDocumentDidSaveHandler // Send out an index request, and copy the current buffer state so we // can update the cached index contents when the index is done. // - // We also do not index if there is already an index request. + // We also do not index if there is already an index request or if + // the client requested indexing on didChange instead. // // TODO: Cancel outgoing index request. Might be tricky to make // efficient since we have to cancel. @@ -44,15 +45,17 @@ struct TextDocumentDidSaveHandler // mutex and check to see if we should skip the current request. // if so, ignore that index response. // TODO: send as priority request - optional content = ReadContent(path); - if (!content) { - LOG_S(ERROR) << "Unable to read file content after saving " << path; - } else { - Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content, ICacheManager::Make(config)), - true); + if (!config->enableIndexOnDidChange) { + optional content = ReadContent(path); + if (!content) { + LOG_S(ERROR) << "Unable to read file content after saving " << path; + } else { + Project::Entry entry = project->FindCompilationEntryForFile(path); + QueueManager::instance()->index_request.PushBack( + Index_Request(entry.filename, entry.args, true /*is_interactive*/, + *content, ICacheManager::Make(config)), + true); + } } clang_complete->NotifySave(path); From 07b3208cb4d6c236d5e38efae0a5ec720405f720 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Tue, 20 Mar 2018 10:12:52 -0700 Subject: [PATCH 025/378] Ensure IndexMergeIndexUpdates always returns a bool --- src/import_pipeline.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index a12d8836e..4876bba02 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -555,6 +555,8 @@ bool IndexMergeIndexUpdates() { // return update.path; //})); } + + return did_merge; } } // namespace From f137ec6a6d9dd5fdf4219ff95d076ac6c5adb590 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Tue, 20 Mar 2018 11:55:40 -0700 Subject: [PATCH 026/378] Reduce queue lengths by running index updates as iteration loop A single translation unit can create many index updates, so give IndexMain_DoCreateIndexUpdate a chance to run a few times. This should also be faster as it is more icache friendly. --- src/import_pipeline.cc | 117 ++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 4876bba02..3fcff636e 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -452,67 +452,74 @@ bool IndexMain_DoParse( bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { auto* queue = QueueManager::instance(); - optional response = queue->on_id_mapped.TryPopFront(); - if (!response) - return false; - Timer time; + bool did_work = false; + IterationLoop loop; + while (loop.Next()) { + optional response = queue->on_id_mapped.TryPopFront(); + if (!response) + return did_work; - IdMap* previous_id_map = nullptr; - IndexFile* previous_index = nullptr; - if (response->previous) { - previous_id_map = response->previous->ids.get(); - previous_index = response->previous->file.get(); - } + did_work = true; - // Build delta update. - IndexUpdate update = - IndexUpdate::CreateDelta(previous_id_map, response->current->ids.get(), - previous_index, response->current->file.get()); - response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); - LOG_S(INFO) << "Built index update for " << response->current->file->path - << " (is_delta=" << !!response->previous << ")"; - - // Write current index to disk if requested. - if (response->write_to_disk) { - LOG_S(INFO) << "Writing cached index to disk for " - << response->current->file->path; - time.Reset(); - response->cache_manager->WriteToCache(*response->current->file); - response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); - timestamp_manager->UpdateCachedModificationTime( - response->current->file->path, - response->current->file->last_modification_time); - } + Timer time; -#if false -#define PRINT_SECTION(name) \ - if (response->perf.name) { \ - total += response->perf.name; \ - output << " " << #name << ": " << FormatMicroseconds(response->perf.name); \ + IdMap* previous_id_map = nullptr; + IndexFile* previous_index = nullptr; + if (response->previous) { + previous_id_map = response->previous->ids.get(); + previous_index = response->previous->file.get(); + } + + // Build delta update. + IndexUpdate update = + IndexUpdate::CreateDelta(previous_id_map, response->current->ids.get(), + previous_index, response->current->file.get()); + response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); + LOG_S(INFO) << "Built index update for " << response->current->file->path + << " (is_delta=" << !!response->previous << ")"; + + // Write current index to disk if requested. + if (response->write_to_disk) { + LOG_S(INFO) << "Writing cached index to disk for " + << response->current->file->path; + time.Reset(); + response->cache_manager->WriteToCache(*response->current->file); + response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); + timestamp_manager->UpdateCachedModificationTime( + response->current->file->path, + response->current->file->last_modification_time); + } + + #if false + #define PRINT_SECTION(name) \ + if (response->perf.name) { \ + total += response->perf.name; \ + output << " " << #name << ": " << FormatMicroseconds(response->perf.name); \ + } + std::stringstream output; + long long total = 0; + output << "[perf]"; + PRINT_SECTION(index_parse); + PRINT_SECTION(index_build); + PRINT_SECTION(index_save_to_disk); + PRINT_SECTION(index_load_cached); + PRINT_SECTION(querydb_id_map); + PRINT_SECTION(index_make_delta); + output << "\n total: " << FormatMicroseconds(total); + output << " path: " << response->current_index->path; + LOG_S(INFO) << output.rdbuf(); + #undef PRINT_SECTION + + if (response->is_interactive) + LOG_S(INFO) << "Applying IndexUpdate" << std::endl << update.ToString(); + #endif + + Index_OnIndexed reply(std::move(update), response->perf); + queue->on_indexed.PushBack(std::move(reply), response->is_interactive); } - std::stringstream output; - long long total = 0; - output << "[perf]"; - PRINT_SECTION(index_parse); - PRINT_SECTION(index_build); - PRINT_SECTION(index_save_to_disk); - PRINT_SECTION(index_load_cached); - PRINT_SECTION(querydb_id_map); - PRINT_SECTION(index_make_delta); - output << "\n total: " << FormatMicroseconds(total); - output << " path: " << response->current_index->path; - LOG_S(INFO) << output.rdbuf(); -#undef PRINT_SECTION - - if (response->is_interactive) - LOG_S(INFO) << "Applying IndexUpdate" << std::endl << update.ToString(); -#endif - - Index_OnIndexed reply(std::move(update), response->perf); - queue->on_indexed.PushBack(std::move(reply), response->is_interactive); - return true; + return did_work; } bool IndexMain_LoadPreviousIndex() { From f17196e3da71ae9c4cd7bef121878bf086eb3715 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 20 Mar 2018 08:33:02 -0400 Subject: [PATCH 027/378] Flush all clang-complete sessions on workspace/didChangeConfiguration --- src/clang_complete.cc | 14 ++++++++++++++ src/clang_complete.h | 5 +++++ src/diagnostics_engine.cc | 5 ----- src/import_pipeline.cc | 6 ++++++ src/lru_cache.h | 9 +++++++++ src/messages/workspace_did_change_configuration.cc | 6 ++++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 734dcf304..8584b5ad3 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -802,3 +802,17 @@ std::shared_ptr ClangCompleteManager::TryGetSession( return completion_session; } + +void ClangCompleteManager::FlushSession(const std::string& filename) { + std::lock_guard lock(sessions_lock_); + + preloaded_sessions_.TryTake(filename); + completion_sessions_.TryTake(filename); +} + +void ClangCompleteManager::FlushAllSessions() { + std::lock_guard lock(sessions_lock_); + + preloaded_sessions_.Clear(); + completion_sessions_.Clear(); +} diff --git a/src/clang_complete.h b/src/clang_complete.h index ef5060057..03197a602 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -110,6 +110,11 @@ struct ClangCompleteManager { bool mark_as_completion, bool create_if_needed); + // Flushes all saved sessions with the supplied filename + void FlushSession(const std::string& filename); + // Flushes all saved sessions + void FlushAllSessions(void); + // TODO: make these configurable. const int kMaxPreloadedSessions = 10; const int kMaxCompletionSessions = 5; diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 36453ea27..15253d1d5 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -13,11 +13,6 @@ void DiagnosticsEngine::Init(Config* config) { void DiagnosticsEngine::Publish(WorkingFiles* working_files, std::string path, std::vector diagnostics) { - // Cache diagnostics so we can show fixits. - working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { - if (working_file) - working_file->diagnostics_ = diagnostics; - }); int64_t now = std::chrono::duration_cast( diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 3fcff636e..03d8f47cb 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -408,6 +408,12 @@ void ParseFile(Config* config, for (std::unique_ptr& new_index : *indexes) { Timer time; + // Cache diagnostics so we can show fixits. + working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { + if (working_file) + working_file->diagnostics_ = diagnostics; + }); + // Only emit diagnostics for non-interactive sessions, which makes it easier // to identify indexing problems. For interactive sessions, diagnostics are // handled by code completion. diff --git a/src/lru_cache.h b/src/lru_cache.h index 5539cc784..c6e3d9c4b 100644 --- a/src/lru_cache.h +++ b/src/lru_cache.h @@ -29,6 +29,9 @@ struct LruCache { template void IterateValues(TFunc func); + // Empties the cache + void Clear(void); + private: // There is a global score counter, when we access an element we increase // its score to the current global value, so it has the highest overall @@ -124,3 +127,9 @@ void LruCache::IncrementScore() { entry.score = next_score_++; } } + +template +void LruCache::Clear(void) { + entries_.clear(); + next_score_ = 0; +} diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 7b90fc8d1..3506cf59e 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -1,10 +1,13 @@ #include "cache_manager.h" +#include "clang_complete.h" #include "message_handler.h" #include "project.h" #include "queue_manager.h" #include "timer.h" #include "working_files.h" +#include + namespace { struct lsDidChangeConfigurationParams { bool placeholder; @@ -32,6 +35,9 @@ struct WorkspaceDidChangeConfigurationHandler std::monostate()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); + + clang_complete->FlushAllSessions(); + LOG_S(INFO) << "Flushed all clang complete sessions"; } }; REGISTER_MESSAGE_HANDLER(WorkspaceDidChangeConfigurationHandler); From 958422e77fa0e6a4d0ec4ec43e619322f30497de Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 20 Mar 2018 08:47:12 -0400 Subject: [PATCH 028/378] Undo changes to diagnostics engine and import pipeline They didn't seem necessary --- src/diagnostics_engine.cc | 5 +++++ src/import_pipeline.cc | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 15253d1d5..36453ea27 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -13,6 +13,11 @@ void DiagnosticsEngine::Init(Config* config) { void DiagnosticsEngine::Publish(WorkingFiles* working_files, std::string path, std::vector diagnostics) { + // Cache diagnostics so we can show fixits. + working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { + if (working_file) + working_file->diagnostics_ = diagnostics; + }); int64_t now = std::chrono::duration_cast( diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 03d8f47cb..3fcff636e 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -408,12 +408,6 @@ void ParseFile(Config* config, for (std::unique_ptr& new_index : *indexes) { Timer time; - // Cache diagnostics so we can show fixits. - working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { - if (working_file) - working_file->diagnostics_ = diagnostics; - }); - // Only emit diagnostics for non-interactive sessions, which makes it easier // to identify indexing problems. For interactive sessions, diagnostics are // handled by code completion. From 1afb6c398887eaa727bedb5f999f2b501319bfc1 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 20 Mar 2018 18:49:40 -0400 Subject: [PATCH 029/378] Flush sessions on textDocument/didOpen --- src/messages/text_document_did_open.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 0bd4f9901..36e207380 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -7,6 +7,8 @@ #include "timer.h" #include "working_files.h" +#include + namespace { // Open, view, change, close file struct Ipc_TextDocumentDidOpen @@ -65,6 +67,9 @@ struct TextDocumentDidOpenHandler entry.filename, params.args.size() ? params.args : entry.args, true /*is_interactive*/, params.textDocument.text, cache_manager), true /* priority */); + + clang_complete->FlushSession(entry.filename); + LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; } }; REGISTER_MESSAGE_HANDLER(TextDocumentDidOpenHandler); From 7e6965afe3641af14873f7fe29d8f65e1ae48a49 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Wed, 21 Mar 2018 11:57:09 -0700 Subject: [PATCH 030/378] Don't use an IterationLoop for main indexer. This causes the indexer to exit. --- src/import_pipeline.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 3fcff636e..27d524114 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -625,8 +625,7 @@ void Indexer_Main(Config* config, // Build one index per-indexer, as building the index acquires a global lock. auto indexer = IIndexer::MakeClangIndexer(); - IterationLoop loop; - while (loop.Next()) { + while (true) { bool did_work = false; { From bdabb7596cb71886dfa28897a50759cf490d19b1 Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Wed, 21 Mar 2018 20:49:28 +0100 Subject: [PATCH 031/378] Make overridden flags persistent didOpen can override flags from compilation database. didSave was able to reset the flags back. This makes sure that the overridden flags persist. --- src/messages/text_document_did_open.cc | 5 ++++- src/project.cc | 17 +++++++++++++++++ src/project.h | 7 +++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 36e207380..e354e449e 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -61,7 +61,7 @@ struct TextDocumentDidOpenHandler clang_complete->NotifyView(path); // Submit new index request. - const Project::Entry& entry = project->FindCompilationEntryForFile(path); + Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( Index_Request( entry.filename, params.args.size() ? params.args : entry.args, @@ -70,6 +70,9 @@ struct TextDocumentDidOpenHandler clang_complete->FlushSession(entry.filename); LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; + if (params.args.size()) { + project->SetFlagsForFile(params.args, path); + } } }; REGISTER_MESSAGE_HANDLER(TextDocumentDidOpenHandler); diff --git a/src/project.cc b/src/project.cc index 0c476a714..11617fe13 100644 --- a/src/project.cc +++ b/src/project.cc @@ -569,6 +569,23 @@ void Project::Load(Config* config, const std::string& root_directory) { absolute_path_to_entry_index_[entries[i].filename] = i; } +void Project::SetFlagsForFile( + const std::vector& flags, + const std::string& path) { + auto it = absolute_path_to_entry_index_.find(path); + if (it != absolute_path_to_entry_index_.end()) { + // The entry already exists in the project, just set the flags. + this->entries[it->second].args = flags; + } else { + // Entry wasn't found, so we create a new one. + Entry entry; + entry.is_inferred = false; + entry.filename = path; + entry.args = flags; + this->entries.emplace_back(entry); + } +} + Project::Entry Project::FindCompilationEntryForFile( const std::string& filename) { auto it = absolute_path_to_entry_index_.find(filename); diff --git a/src/project.h b/src/project.h index db93f4b29..c3acdf223 100644 --- a/src/project.h +++ b/src/project.h @@ -48,6 +48,13 @@ struct Project { // will infer one based on existing project structure. Entry FindCompilationEntryForFile(const std::string& filename); + // If the client has overridden the flags, or specified them for a file + // that is not in the compilation_database.json make sure those changes + // are permanent. + void SetFlagsForFile( + const std::vector& flags, + const std::string& path); + // Run |action| on every file in the project. void ForAllFilteredFiles( Config* config, From 5f085729bdff7e7ee05b3041b3a57db30104fd01 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Wed, 21 Mar 2018 21:04:41 -0700 Subject: [PATCH 032/378] Fix some warnings due to missing returns --- src/clang_indexer.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 4e2b571b8..fbbdf396e 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -150,6 +150,8 @@ lsSymbolKind GetSymbolKind(CXIdxEntityKind kind) { case CXIdxEntity_CXXInterface: return lsSymbolKind::Struct; } + + return lsSymbolKind::Unknown; } StorageClass GetStorageClass(CX_StorageClass storage) { @@ -170,6 +172,8 @@ StorageClass GetStorageClass(CX_StorageClass storage) { case CX_SC_Register: return StorageClass::Register; } + + return StorageClass::None; } // Caches all instances of constructors, regardless if they are indexed or not. From cad6dcda0cbe690844ee351745726c42c151f1d3 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Wed, 21 Mar 2018 21:05:25 -0700 Subject: [PATCH 033/378] Remove global list of message ids. Also do some naming cleanup. Also remove xmacros. --- src/command_line.cc | 71 ++++++------------- src/diagnostics_engine.cc | 2 +- src/import_pipeline.cc | 4 +- src/ipc.cc | 30 ++------ src/ipc.h | 42 +++-------- src/lsp.h | 11 +-- src/match.cc | 2 +- src/message_handler.cc | 6 +- src/message_handler.h | 5 +- src/messages/cquery_base.cc | 22 +++--- src/messages/cquery_call_hierarchy.cc | 28 +++++--- src/messages/cquery_callers.cc | 19 ++--- src/messages/cquery_derived.cc | 19 ++--- src/messages/cquery_did_view.cc | 22 +++--- src/messages/cquery_file_info.cc | 19 ++--- src/messages/cquery_freshen_index.cc | 20 +++--- src/messages/cquery_index_file.cc | 19 ++--- src/messages/cquery_inheritance_hierarchy.cc | 25 ++++--- src/messages/cquery_member_hierarchy.cc | 26 ++++--- src/messages/cquery_random.cc | 20 +++--- src/messages/cquery_vars.cc | 21 +++--- src/messages/cquery_wait.cc | 17 +++-- src/messages/exit.cc | 16 ++--- src/messages/initialize.cc | 21 +++--- src/messages/shutdown.cc | 19 ++--- src/messages/text_document_code_action.cc | 27 +++---- src/messages/text_document_code_lens.cc | 22 +++--- src/messages/text_document_completion.cc | 26 +++---- src/messages/text_document_definition.cc | 21 +++--- src/messages/text_document_did_change.cc | 21 +++--- src/messages/text_document_did_close.cc | 25 ++++--- src/messages/text_document_did_open.cc | 24 ++++--- src/messages/text_document_did_save.cc | 24 ++++--- .../text_document_document_highlight.cc | 22 +++--- src/messages/text_document_document_link.cc | 24 ++++--- src/messages/text_document_document_symbol.cc | 22 +++--- src/messages/text_document_formatting.cc | 23 +++--- src/messages/text_document_hover.cc | 18 ++--- .../text_document_range_formatting.cc | 22 +++--- src/messages/text_document_references.cc | 27 +++---- src/messages/text_document_rename.cc | 20 +++--- src/messages/text_document_signature_help.cc | 23 +++--- src/messages/text_document_type_definition.cc | 21 +++--- .../workspace_did_change_configuration.cc | 20 +++--- .../workspace_did_change_watched_files.cc | 20 +++--- src/messages/workspace_execute_command.cc | 21 +++--- src/messages/workspace_symbol.cc | 20 +++--- src/methods.inc | 60 ---------------- src/queue_manager.cc | 4 +- src/queue_manager.h | 4 +- 50 files changed, 517 insertions(+), 550 deletions(-) delete mode 100644 src/methods.inc diff --git a/src/command_line.cc b/src/command_line.cc index 8a58da027..6229ad330 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -57,20 +57,15 @@ namespace { std::vector kEmptyArgs; // This function returns true if e2e timing should be displayed for the given -// IpcId. -bool ShouldDisplayIpcTiming(IpcId id) { - switch (id) { - case IpcId::TextDocumentPublishDiagnostics: - case IpcId::CqueryPublishInactiveRegions: - case IpcId::Unknown: - return false; - default: - return true; - } +// MethodId. +bool ShouldDisplayMethodTiming(MethodType type) { + return + type != kMethodType_TextDocumentPublishDiagnostics && + type != kMethodType_CqueryPublishInactiveRegions && + type != kMethodType_Unknown; + return true; } -REGISTER_IPC_MESSAGE(Ipc_CancelRequest); - void PrintHelp() { std::cout << R"help(cquery is a low-latency C/C++/Objective-C language server. @@ -146,16 +141,16 @@ bool QueryDbMainLoop(Config* config, queue->for_querydb.DequeueAll(); bool did_work = messages.size(); for (auto& message : messages) { + // TODO: Consider using std::unordered_map to lookup the handler for (MessageHandler* handler : *MessageHandler::message_handlers) { - if (handler->GetId() == message->method_id) { + if (handler->GetMethodType() == message->GetMethodType()) { handler->Run(std::move(message)); break; } } if (message) { - LOG_S(FATAL) << "Exiting; unhandled IPC message " - << IpcIdToString(message->method_id); + LOG_S(FATAL) << "Exiting; no handler for " << message->GetMethodType(); exit(1); } } @@ -199,7 +194,7 @@ void RunQueryDbThread(const std::string& bin_name, out.error.message = "Dropping completion request; a newer request " "has come in that will be serviced instead."; - QueueManager::WriteStdout(IpcId::Unknown, out); + QueueManager::WriteStdout(kMethodType_Unknown, out); } }); @@ -278,7 +273,7 @@ void RunQueryDbThread(const std::string& bin_name, // // |ipc| is connected to a server. void LaunchStdinLoop(Config* config, - std::unordered_map* request_times) { + std::unordered_map* request_times) { // If flushing cin requires flushing cout there could be deadlocks in some // clients. std::cin.tie(nullptr); @@ -301,47 +296,28 @@ void LaunchStdinLoop(Config* config, out.id = id; out.error.code = lsErrorCodes::InvalidParams; out.error.message = std::move(*err); - queue->WriteStdout(IpcId::Unknown, out); + queue->WriteStdout(kMethodType_Unknown, out); } } continue; } // Cache |method_id| so we can access it after moving |message|. - IpcId method_id = message->method_id; - (*request_times)[method_id] = Timer(); - - switch (method_id) { - case IpcId::Initialized: { - // TODO: don't send output until we get this notification - break; - } + MethodType method_type = message->GetMethodType(); + (*request_times)[method_type] = Timer(); - case IpcId::CancelRequest: { - // TODO: support cancellation - break; - } - - case IpcId::Exit: -#define CASE(name, method) case IpcId::name: -#include "methods.inc" -#undef CASE - queue->for_querydb.PushBack(std::move(message)); - break; - - case IpcId::Unknown: - break; - } + LOG_S(ERROR) << "!! Got message of type " << method_type; + queue->for_querydb.PushBack(std::move(message)); // If the message was to exit then querydb will take care of the actual // exit. Stop reading from stdin since it might be detached. - if (method_id == IpcId::Exit) + if (method_type == kMethodType_Exit) break; } }); } -void LaunchStdoutThread(std::unordered_map* request_times, +void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { WorkThread::StartThread("stdout", [=]() { auto* queue = QueueManager::instance(); @@ -354,10 +330,9 @@ void LaunchStdoutThread(std::unordered_map* request_times, } for (auto& message : messages) { - if (ShouldDisplayIpcTiming(message.id)) { - Timer time = (*request_times)[message.id]; - time.ResetAndPrint("[e2e] Running " + - std::string(IpcIdToString(message.id))); + if (ShouldDisplayMethodTiming(message.method)) { + Timer time = (*request_times)[message.method]; + time.ResetAndPrint("[e2e] Running " + std::string(message.method)); } RecordOutput(message.content); @@ -374,7 +349,7 @@ void LanguageServerMain(const std::string& bin_name, MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter, MultiQueueWaiter* stdout_waiter) { - std::unordered_map request_times; + std::unordered_map request_times; LaunchStdinLoop(config, &request_times); diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 36453ea27..75dfe4a48 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -30,6 +30,6 @@ void DiagnosticsEngine::Publish(WorkingFiles* working_files, Out_TextDocumentPublishDiagnostics out; out.params.uri = lsDocumentUri::FromPath(path); out.params.diagnostics = diagnostics; - QueueManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out); + QueueManager::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); } } diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 27d524114..90e1ac090 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -136,7 +136,7 @@ struct ActiveThread { GetCurrentTimeInMilliseconds() + config_->progressReportFrequencyMs; } - QueueManager::WriteStdout(IpcId::Unknown, out); + QueueManager::WriteStdout(kMethodType_Unknown, out); } Config* config_; @@ -400,7 +400,7 @@ void ParseFile(Config* config, out.id = request.id; out.error.code = lsErrorCodes::InternalError; out.error.message = "Failed to index " + path_to_index; - QueueManager::WriteStdout(IpcId::Unknown, out); + QueueManager::WriteStdout(kMethodType_Unknown, out); } return; } diff --git a/src/ipc.cc b/src/ipc.cc index 90c75f9b1..811393198 100644 --- a/src/ipc.cc +++ b/src/ipc.cc @@ -1,30 +1,10 @@ #include "ipc.h" -#include - -const char* IpcIdToString(IpcId id) { - switch (id) { - case IpcId::CancelRequest: - return "$/cancelRequest"; - case IpcId::Initialized: - return "initialized"; - case IpcId::Exit: - return "exit"; - -#define CASE(name, method) \ - case IpcId::name: \ - return method; -#include "methods.inc" -#undef CASE - - case IpcId::Unknown: - return "$unknown"; - } - - CQUERY_UNREACHABLE("missing IpcId string name"); -} - -BaseIpcMessage::BaseIpcMessage(IpcId method_id) : method_id(method_id) {} +const char* kMethodType_Unknown = "$unknown"; +const char* kMethodType_Exit = "exit"; +const char* kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; +const char* kMethodType_CqueryPublishInactiveRegions = "$cquery/publishInactiveRegions"; +const char* kMethodType_CqueryPublishSemanticHighlighting = "$cquery/publishSemanticHighlighting"; BaseIpcMessage::~BaseIpcMessage() = default; diff --git a/src/ipc.h b/src/ipc.h index 3992e0589..0718d7fec 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -7,48 +7,26 @@ using lsRequestId = std::variant; -enum class IpcId : int { - // Language server specific requests. - CancelRequest = 0, - Initialized, - Exit, - -#define CASE(x, _) x, -#include "methods.inc" -#undef CASE - - // Internal implementation detail. - Unknown, -}; -MAKE_ENUM_HASHABLE(IpcId) -MAKE_REFLECT_TYPE_PROXY(IpcId) -const char* IpcIdToString(IpcId id); +using MethodType = std::string; + +extern const char* kMethodType_Unknown; +extern const char* kMethodType_Exit; +extern const char* kMethodType_TextDocumentPublishDiagnostics; +extern const char* kMethodType_CqueryPublishInactiveRegions; +extern const char* kMethodType_CqueryPublishSemanticHighlighting; struct BaseIpcMessage { - const IpcId method_id; - BaseIpcMessage(IpcId method_id); virtual ~BaseIpcMessage(); + virtual MethodType GetMethodType() const = 0; virtual lsRequestId GetRequestId(); - - template - T* As() { - assert(method_id == T::kIpcId); - return static_cast(this); - } }; -template struct RequestMessage : public BaseIpcMessage { - // number | string, actually no null + // number or string, actually no null lsRequestId id; - RequestMessage() : BaseIpcMessage(T::kIpcId) {} - lsRequestId GetRequestId() override { return id; } }; // NotificationMessage does not have |id|. -template -struct NotificationMessage : public BaseIpcMessage { - NotificationMessage() : BaseIpcMessage(T::kIpcId) {} -}; +struct NotificationMessage : public BaseIpcMessage {}; diff --git a/src/lsp.h b/src/lsp.h index b44024cea..e0d70cb50 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -24,7 +24,7 @@ ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -#define REGISTER_IPC_MESSAGE(type) \ +#define REGISTER_IN_MESSAGE(type) \ static MessageRegistryRegister type##message_handler_instance_; struct MessageRegistry { @@ -44,7 +44,8 @@ struct MessageRegistry { template struct MessageRegistryRegister { MessageRegistryRegister() { - std::string method_name = IpcIdToString(T::kIpcId); + T dummy; + std::string method_name = dummy.GetMethodType(); MessageRegistry::instance()->allocators[method_name] = [](Reader& visitor, std::unique_ptr* message) { *message = std::make_unique(); @@ -334,12 +335,6 @@ struct lsFormattingOptions { }; MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); -// Cancel an existing request. -struct Ipc_CancelRequest : public RequestMessage { - static const IpcId kIpcId = IpcId::CancelRequest; -}; -MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id); - // MarkedString can be used to render human readable text. It is either a // markdown string or a code-block that provides a language and a code snippet. // The language identifier is sematically equal to the optional language diff --git a/src/match.cc b/src/match.cc index bec67dcf3..21f0b55fb 100644 --- a/src/match.cc +++ b/src/match.cc @@ -32,7 +32,7 @@ optional Matcher::Create(const std::string& search) { out.params.type = lsMessageType::Error; out.params.message = "cquery: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); - QueueManager::WriteStdout(IpcId::Unknown, out); + QueueManager::WriteStdout(kMethodType_Unknown, out); return nullopt; } } diff --git a/src/message_handler.cc b/src/message_handler.cc index a00bc8593..2236d6aa5 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -99,7 +99,7 @@ bool FindFileOrFail(QueryDatabase* db, out.error.code = lsErrorCodes::InternalError; out.error.message = "Unable to find file " + absolute_path; } - QueueManager::WriteStdout(IpcId::Unknown, out); + QueueManager::WriteStdout(kMethodType_Unknown, out); } return false; @@ -114,7 +114,7 @@ void EmitInactiveLines(WorkingFile* working_file, if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); } - QueueManager::WriteStdout(IpcId::CqueryPublishInactiveRegions, out); + QueueManager::WriteStdout(kMethodType_CqueryPublishInactiveRegions, out); } void EmitSemanticHighlighting(QueryDatabase* db, @@ -277,7 +277,7 @@ void EmitSemanticHighlighting(QueryDatabase* db, for (auto& entry : grouped_symbols) if (entry.second.ranges.size()) out.params.symbols.push_back(entry.second); - QueueManager::WriteStdout(IpcId::CqueryPublishSemanticHighlighting, out); + QueueManager::WriteStdout(kMethodType_CqueryPublishSemanticHighlighting, out); } bool ShouldIgnoreFileForIndexing(const std::string& path) { diff --git a/src/message_handler.h b/src/message_handler.h index d5b79d48a..a68990f4f 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -86,7 +86,7 @@ struct MessageHandler { CodeCompleteCache* non_global_code_complete_cache = nullptr; CodeCompleteCache* signature_cache = nullptr; - virtual IpcId GetId() const = 0; + virtual MethodType GetMethodType() const = 0; virtual void Run(std::unique_ptr message) = 0; static std::vector* message_handlers; @@ -100,9 +100,8 @@ struct BaseMessageHandler : MessageHandler { virtual void Run(TMessage* message) = 0; // MessageHandler: - IpcId GetId() const override { return TMessage::kIpcId; } void Run(std::unique_ptr message) override { - Run(message->As()); + Run(static_cast(message.get())); } }; diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index 6a11a0644..05963f850 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -3,15 +3,21 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryBase : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryBase; + +MethodType kMethodType = "$cquery/base"; + +struct In_CqueryBase : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryBase, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryBase); +MAKE_REFLECT_STRUCT(In_CqueryBase, id, params); +REGISTER_IN_MESSAGE(In_CqueryBase); + +struct Handler_CqueryBase : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct CqueryBaseHandler : BaseMessageHandler { - void Run(Ipc_CqueryBase* request) override { + void Run(In_CqueryBase* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -39,8 +45,8 @@ struct CqueryBaseHandler : BaseMessageHandler { break; } } - QueueManager::WriteStdout(IpcId::CqueryBase, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryBaseHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryBase); } // namespace diff --git a/src/messages/cquery_call_hierarchy.cc b/src/messages/cquery_call_hierarchy.cc index 594ce931d..7143680ba 100644 --- a/src/messages/cquery_call_hierarchy.cc +++ b/src/messages/cquery_call_hierarchy.cc @@ -5,6 +5,9 @@ #include namespace { + +MethodType kMethodType = "$cquery/callHierarchy"; + enum class CallType : uint8_t { Direct = 0, Base = 1, @@ -17,9 +20,9 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct Ipc_CqueryCallHierarchy - : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryCallHierarchy; +struct In_CqueryCallHierarchy : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + struct Params { // If id is specified, expand a node; otherwise textDocument+position should // be specified for building the root and |levels| of nodes below. @@ -38,8 +41,9 @@ struct Ipc_CqueryCallHierarchy int levels = 1; }; Params params; + }; -MAKE_REFLECT_STRUCT(Ipc_CqueryCallHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CqueryCallHierarchy::Params, textDocument, position, id, @@ -47,8 +51,8 @@ MAKE_REFLECT_STRUCT(Ipc_CqueryCallHierarchy::Params, callType, detailedName, levels); -MAKE_REFLECT_STRUCT(Ipc_CqueryCallHierarchy, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryCallHierarchy); +MAKE_REFLECT_STRUCT(In_CqueryCallHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CqueryCallHierarchy); struct Out_CqueryCallHierarchy : public lsOutMessage { struct Entry { @@ -155,8 +159,10 @@ bool Expand(MessageHandler* m, return true; } -struct CqueryCallHierarchyHandler - : BaseMessageHandler { +struct Handler_CqueryCallHierarchy + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + optional BuildInitial(QueryFuncId root_id, bool callee, CallType call_type, @@ -178,7 +184,7 @@ struct CqueryCallHierarchyHandler return entry; } - void Run(Ipc_CqueryCallHierarchy* request) override { + void Run(In_CqueryCallHierarchy* request) override { const auto& params = request->params; Out_CqueryCallHierarchy out; out.id = request->id; @@ -209,9 +215,9 @@ struct CqueryCallHierarchyHandler } } - QueueManager::WriteStdout(IpcId::CqueryCallHierarchy, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryCallHierarchyHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryCallHierarchy); } // namespace diff --git a/src/messages/cquery_callers.cc b/src/messages/cquery_callers.cc index 088b93137..4214253f8 100644 --- a/src/messages/cquery_callers.cc +++ b/src/messages/cquery_callers.cc @@ -3,15 +3,18 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryCallers : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryCallers; +MethodType kMethodType = "$cquery/callers"; + +struct In_CqueryCallers : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryCallers, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryCallers); +MAKE_REFLECT_STRUCT(In_CqueryCallers, id, params); +REGISTER_IN_MESSAGE(In_CqueryCallers); -struct CqueryCallersHandler : BaseMessageHandler { - void Run(Ipc_CqueryCallers* request) override { +struct Handler_CqueryCallers : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CqueryCallers* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -38,8 +41,8 @@ struct CqueryCallersHandler : BaseMessageHandler { break; } } - QueueManager::WriteStdout(IpcId::CqueryCallers, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryCallersHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryCallers); } // namespace diff --git a/src/messages/cquery_derived.cc b/src/messages/cquery_derived.cc index 08e7033f1..e43da9123 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/cquery_derived.cc @@ -3,15 +3,18 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryDerived : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryDerived; +MethodType kMethodType = "$cquery/derived"; + +struct In_CqueryDerived : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryDerived, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryDerived); +MAKE_REFLECT_STRUCT(In_CqueryDerived, id, params); +REGISTER_IN_MESSAGE(In_CqueryDerived); -struct CqueryDerivedHandler : BaseMessageHandler { - void Run(Ipc_CqueryDerived* request) override { +struct Handler_CqueryDerived : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CqueryDerived* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -39,8 +42,8 @@ struct CqueryDerivedHandler : BaseMessageHandler { break; } } - QueueManager::WriteStdout(IpcId::CqueryDerived, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryDerivedHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryDerived); } // namespace diff --git a/src/messages/cquery_did_view.cc b/src/messages/cquery_did_view.cc index 7b3949967..d01f6d95d 100644 --- a/src/messages/cquery_did_view.cc +++ b/src/messages/cquery_did_view.cc @@ -3,21 +3,23 @@ #include "working_files.h" namespace { -struct Ipc_CqueryTextDocumentDidView - : public NotificationMessage { - const static IpcId kIpcId = IpcId::CqueryTextDocumentDidView; +MethodType kMethodType = "$cquery/textDocumentDidView"; + +struct In_CqueryTextDocumentDidView : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { lsDocumentUri textDocumentUri; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView::Params, textDocumentUri); -MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryTextDocumentDidView); +MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView::Params, textDocumentUri); +MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView, params); +REGISTER_IN_MESSAGE(In_CqueryTextDocumentDidView); -struct CqueryDidViewHandler - : BaseMessageHandler { - void Run(Ipc_CqueryTextDocumentDidView* request) override { +struct Handler_CqueryDidView + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CqueryTextDocumentDidView* request) override { std::string path = request->params.textDocumentUri.GetPath(); WorkingFile* working_file = working_files->GetFileByFilename(path); @@ -34,5 +36,5 @@ struct CqueryDidViewHandler } } }; -REGISTER_MESSAGE_HANDLER(CqueryDidViewHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryDidView); } // namespace diff --git a/src/messages/cquery_file_info.cc b/src/messages/cquery_file_info.cc index 1fa9998b3..22db960cd 100644 --- a/src/messages/cquery_file_info.cc +++ b/src/messages/cquery_file_info.cc @@ -3,17 +3,19 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "$cquery/fileInfo"; + struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; }; MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); -struct Ipc_CqueryFileInfo : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryFileInfo; +struct In_CqueryFileInfo : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsDocumentSymbolParams params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryFileInfo, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryFileInfo); +MAKE_REFLECT_STRUCT(In_CqueryFileInfo, id, params); +REGISTER_IN_MESSAGE(In_CqueryFileInfo); struct Out_CqueryFileInfo : public lsOutMessage { lsRequestId id; @@ -21,8 +23,9 @@ struct Out_CqueryFileInfo : public lsOutMessage { }; MAKE_REFLECT_STRUCT(Out_CqueryFileInfo, jsonrpc, id, result); -struct CqueryFileInfoHandler : BaseMessageHandler { - void Run(Ipc_CqueryFileInfo* request) override { +struct Handler_CqueryFileInfo : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CqueryFileInfo* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -37,8 +40,8 @@ struct CqueryFileInfoHandler : BaseMessageHandler { out.result.language = file->def->language; out.result.includes = file->def->includes; out.result.inactive_regions = file->def->inactive_regions; - QueueManager::WriteStdout(IpcId::CqueryFileInfo, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryFileInfoHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryFileInfo); } // namespace diff --git a/src/messages/cquery_freshen_index.cc b/src/messages/cquery_freshen_index.cc index bb08b2a11..0b7cc073d 100644 --- a/src/messages/cquery_freshen_index.cc +++ b/src/messages/cquery_freshen_index.cc @@ -13,9 +13,10 @@ #include namespace { -struct Ipc_CqueryFreshenIndex - : public NotificationMessage { - const static IpcId kIpcId = IpcId::CqueryFreshenIndex; +MethodType kMethodType = "$cquery/freshenIndex"; + +struct In_CqueryFreshenIndex : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { bool dependencies = true; std::vector whitelist; @@ -23,15 +24,16 @@ struct Ipc_CqueryFreshenIndex }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryFreshenIndex::Params, +MAKE_REFLECT_STRUCT(In_CqueryFreshenIndex::Params, dependencies, whitelist, blacklist); -MAKE_REFLECT_STRUCT(Ipc_CqueryFreshenIndex, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryFreshenIndex); +MAKE_REFLECT_STRUCT(In_CqueryFreshenIndex, params); +REGISTER_IN_MESSAGE(In_CqueryFreshenIndex); -struct CqueryFreshenIndexHandler : BaseMessageHandler { - void Run(Ipc_CqueryFreshenIndex* request) override { +struct Handler_CqueryFreshenIndex : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CqueryFreshenIndex* request) override { LOG_S(INFO) << "Freshening " << project->entries.size() << " files"; // TODO: think about this flow and test it more. @@ -90,5 +92,5 @@ struct CqueryFreshenIndexHandler : BaseMessageHandler { time.ResetAndPrint("[perf] Dispatched $cquery/freshenIndex index requests"); } }; -REGISTER_MESSAGE_HANDLER(CqueryFreshenIndexHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryFreshenIndex); } // namespace diff --git a/src/messages/cquery_index_file.cc b/src/messages/cquery_index_file.cc index 59ef02f5b..0d188ea6e 100644 --- a/src/messages/cquery_index_file.cc +++ b/src/messages/cquery_index_file.cc @@ -6,8 +6,10 @@ #include namespace { -struct Ipc_CqueryIndexFile : public NotificationMessage { - static constexpr IpcId kIpcId = IpcId::CqueryIndexFile; +MethodType kMethodType = "$cquery/indexFile"; + +struct In_CqueryIndexFile : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string path; std::vector args; @@ -16,16 +18,17 @@ struct Ipc_CqueryIndexFile : public NotificationMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile::Params, +MAKE_REFLECT_STRUCT(In_CqueryIndexFile::Params, path, args, is_interactive, contents); -MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryIndexFile); +MAKE_REFLECT_STRUCT(In_CqueryIndexFile, params); +REGISTER_IN_MESSAGE(In_CqueryIndexFile); -struct CqueryIndexFileHandler : BaseMessageHandler { - void Run(Ipc_CqueryIndexFile* request) override { +struct Handler_CqueryIndexFile : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_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, @@ -33,5 +36,5 @@ struct CqueryIndexFileHandler : BaseMessageHandler { ICacheManager::Make(config))); } }; -REGISTER_MESSAGE_HANDLER(CqueryIndexFileHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryIndexFile); } // namespace diff --git a/src/messages/cquery_inheritance_hierarchy.cc b/src/messages/cquery_inheritance_hierarchy.cc index d81df3434..3c024619f 100644 --- a/src/messages/cquery_inheritance_hierarchy.cc +++ b/src/messages/cquery_inheritance_hierarchy.cc @@ -3,9 +3,10 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryInheritanceHierarchy - : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryInheritanceHierarchy; +MethodType kMethodType = "$cquery/inheritanceHierarchy"; + +struct In_CqueryInheritanceHierarchy : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { // If id+kind are specified, expand a node; otherwise textDocument+position // should be specified for building the root and |levels| of nodes below. @@ -23,7 +24,7 @@ struct Ipc_CqueryInheritanceHierarchy Params params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CqueryInheritanceHierarchy::Params, textDocument, position, id, @@ -31,8 +32,8 @@ MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchy::Params, derived, detailedName, levels); -MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchy, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryInheritanceHierarchy); +MAKE_REFLECT_STRUCT(In_CqueryInheritanceHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CqueryInheritanceHierarchy); struct Out_CqueryInheritanceHierarchy : public lsOutMessage { @@ -127,8 +128,10 @@ bool Expand(MessageHandler* m, m->db->types[entry->id.id]); } -struct CqueryInheritanceHierarchyHandler - : BaseMessageHandler { +struct Handler_CqueryInheritanceHierarchy + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + optional BuildInitial(SymbolRef sym, bool derived, bool detailed_name, int levels) { Out_CqueryInheritanceHierarchy::Entry entry; @@ -138,7 +141,7 @@ struct CqueryInheritanceHierarchyHandler return entry; } - void Run(Ipc_CqueryInheritanceHierarchy* request) override { + void Run(In_CqueryInheritanceHierarchy* request) override { const auto& params = request->params; Out_CqueryInheritanceHierarchy out; out.id = request->id; @@ -171,9 +174,9 @@ struct CqueryInheritanceHierarchyHandler } } - QueueManager::WriteStdout(IpcId::CqueryInheritanceHierarchy, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryInheritanceHierarchyHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryInheritanceHierarchy); } // namespace diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/cquery_member_hierarchy.cc index 8245c8571..b4f03763f 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/cquery_member_hierarchy.cc @@ -3,9 +3,11 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryMemberHierarchy - : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryMemberHierarchy; +MethodType kMethodType = "$cquery/memberHierarchy"; + +struct In_CqueryMemberHierarchy : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + struct Params { // If id is specified, expand a node; otherwise textDocument+position should // be specified for building the root and |levels| of nodes below. @@ -20,14 +22,14 @@ struct Ipc_CqueryMemberHierarchy Params params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryMemberHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CqueryMemberHierarchy::Params, textDocument, position, id, detailedName, levels); -MAKE_REFLECT_STRUCT(Ipc_CqueryMemberHierarchy, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryMemberHierarchy); +MAKE_REFLECT_STRUCT(In_CqueryMemberHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CqueryMemberHierarchy); struct Out_CqueryMemberHierarchy : public lsOutMessage { @@ -158,8 +160,10 @@ bool Expand(MessageHandler* m, return true; } -struct CqueryMemberHierarchyHandler - : BaseMessageHandler { +struct Handler_CqueryMemberHierarchy + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + optional BuildInitial(QueryFuncId root_id, bool detailed_name, int levels) { @@ -202,7 +206,7 @@ struct CqueryMemberHierarchyHandler return entry; } - void Run(Ipc_CqueryMemberHierarchy* request) override { + void Run(In_CqueryMemberHierarchy* request) override { const auto& params = request->params; Out_CqueryMemberHierarchy out; out.id = request->id; @@ -246,9 +250,9 @@ struct CqueryMemberHierarchyHandler } } - QueueManager::WriteStdout(IpcId::CqueryMemberHierarchy, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryMemberHierarchyHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryMemberHierarchy); } // namespace diff --git a/src/messages/cquery_random.cc b/src/messages/cquery_random.cc index 510088c08..bf7c46686 100644 --- a/src/messages/cquery_random.cc +++ b/src/messages/cquery_random.cc @@ -7,11 +7,13 @@ #include namespace { -struct Ipc_CqueryRandom : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryRandom; +MethodType kMethodType = "$cquery/random"; + +struct In_CqueryRandom : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } }; -MAKE_REFLECT_STRUCT(Ipc_CqueryRandom, id); -REGISTER_IPC_MESSAGE(Ipc_CqueryRandom); +MAKE_REFLECT_STRUCT(In_CqueryRandom, id); +REGISTER_IN_MESSAGE(In_CqueryRandom); const double kDeclWeight = 3; const double kDamping = 0.1; @@ -44,8 +46,10 @@ void Add(const std::unordered_map& sym2id, } } -struct CqueryRandomHandler : BaseMessageHandler { - void Run(Ipc_CqueryRandom* request) override { +struct Handler_CqueryRandom : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_CqueryRandom* request) override { std::unordered_map sym2id; std::vector syms; int n = 0; @@ -137,8 +141,8 @@ struct CqueryRandomHandler : BaseMessageHandler { break; } } - QueueManager::WriteStdout(IpcId::CqueryRandom, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryRandomHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryRandom); } // namespace diff --git a/src/messages/cquery_vars.cc b/src/messages/cquery_vars.cc index 1f6b9c568..812ec6f0c 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/cquery_vars.cc @@ -3,15 +3,20 @@ #include "queue_manager.h" namespace { -struct Ipc_CqueryVars : public RequestMessage { - const static IpcId kIpcId = IpcId::CqueryVars; +MethodType kMethodType = "$cquery/vars"; + +struct In_CqueryVars : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_CqueryVars, id, params); -REGISTER_IPC_MESSAGE(Ipc_CqueryVars); +MAKE_REFLECT_STRUCT(In_CqueryVars, id, params); +REGISTER_IN_MESSAGE(In_CqueryVars); + +struct Handler_CqueryVars : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct CqueryVarsHandler : BaseMessageHandler { - void Run(Ipc_CqueryVars* request) override { + void Run(In_CqueryVars* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -45,8 +50,8 @@ struct CqueryVarsHandler : BaseMessageHandler { } } } - QueueManager::WriteStdout(IpcId::CqueryVars, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(CqueryVarsHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryVars); } // namespace diff --git a/src/messages/cquery_wait.cc b/src/messages/cquery_wait.cc index 2e59e9972..c91097291 100644 --- a/src/messages/cquery_wait.cc +++ b/src/messages/cquery_wait.cc @@ -6,14 +6,17 @@ #include namespace { -struct Ipc_CqueryWait : public NotificationMessage { - static constexpr IpcId kIpcId = IpcId::CqueryWait; +MethodType kMethodType = "$cquery/wait"; + +struct In_CqueryWait : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } }; -MAKE_REFLECT_EMPTY_STRUCT(Ipc_CqueryWait); -REGISTER_IPC_MESSAGE(Ipc_CqueryWait); +MAKE_REFLECT_EMPTY_STRUCT(In_CqueryWait); +REGISTER_IN_MESSAGE(In_CqueryWait); + +struct Handler_CqueryWait : MessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct CqueryWaitHandler : MessageHandler { - IpcId GetId() const override { return IpcId::CqueryWait; } void Run(std::unique_ptr request) override { // TODO: use status message system here, then run querydb as normal? Maybe // this cannot be a normal message, ie, it needs to be re-entrant. @@ -40,5 +43,5 @@ struct CqueryWaitHandler : MessageHandler { LOG_S(INFO) << "Done waiting for idle"; } }; -REGISTER_MESSAGE_HANDLER(CqueryWaitHandler); +REGISTER_MESSAGE_HANDLER(Handler_CqueryWait); } // namespace diff --git a/src/messages/exit.cc b/src/messages/exit.cc index a0e403f42..d90d80ed3 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -3,19 +3,19 @@ #include namespace { -struct Ipc_Exit : public NotificationMessage { - static const IpcId kIpcId = IpcId::Exit; +struct In_Exit : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType_Exit; } }; -MAKE_REFLECT_EMPTY_STRUCT(Ipc_Exit); -REGISTER_IPC_MESSAGE(Ipc_Exit); +MAKE_REFLECT_EMPTY_STRUCT(In_Exit); +REGISTER_IN_MESSAGE(In_Exit); -struct ExitHandler : MessageHandler { - IpcId GetId() const override { return IpcId::Exit; } +struct Handler_Exit : MessageHandler { + MethodType GetMethodType() const override { return kMethodType_Exit; } void Run(std::unique_ptr request) override { - LOG_S(INFO) << "Exiting; got IpcId::Exit"; + LOG_S(INFO) << "Exiting; got exit message"; exit(0); } }; -REGISTER_MESSAGE_HANDLER(ExitHandler); +REGISTER_MESSAGE_HANDLER(Handler_Exit); } // namespace diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index e08724491..ffbc6115c 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -23,6 +23,8 @@ extern std::string g_init_options; namespace { +MethodType kMethodType = "initialize"; + // Code Lens options. struct lsCodeLensOptions { // Code lens has a resolve provider as well. @@ -460,12 +462,13 @@ struct lsInitializeError { }; MAKE_REFLECT_STRUCT(lsInitializeError, retry); -struct Ipc_InitializeRequest : public RequestMessage { - const static IpcId kIpcId = IpcId::Initialize; +struct In_InitializeRequest : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + lsInitializeParams params; }; -MAKE_REFLECT_STRUCT(Ipc_InitializeRequest, id, params); -REGISTER_IPC_MESSAGE(Ipc_InitializeRequest); +MAKE_REFLECT_STRUCT(In_InitializeRequest, id, params); +REGISTER_IN_MESSAGE(In_InitializeRequest); struct Out_InitializeResponse : public lsOutMessage { struct InitializeResult { @@ -477,8 +480,10 @@ struct Out_InitializeResponse : public lsOutMessage { MAKE_REFLECT_STRUCT(Out_InitializeResponse::InitializeResult, capabilities); MAKE_REFLECT_STRUCT(Out_InitializeResponse, jsonrpc, id, result); -struct InitializeHandler : BaseMessageHandler { - void Run(Ipc_InitializeRequest* request) override { +struct Handler_Initialize : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_InitializeRequest* request) override { // Log initialization parameters. rapidjson::StringBuffer output; rapidjson::Writer writer(output); @@ -573,7 +578,7 @@ struct InitializeHandler : BaseMessageHandler { out.result.capabilities.documentRangeFormattingProvider = true; #endif - QueueManager::WriteStdout(IpcId::Initialize, out); + QueueManager::WriteStdout(kMethodType, out); // Set project root. EnsureEndsInSlash(project_path); @@ -627,5 +632,5 @@ struct InitializeHandler : BaseMessageHandler { } } }; -REGISTER_MESSAGE_HANDLER(InitializeHandler); +REGISTER_MESSAGE_HANDLER(Handler_Initialize); } // namespace diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index 5755fb6a0..f93f43208 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -2,11 +2,13 @@ #include "queue_manager.h" namespace { -struct Ipc_Shutdown : public RequestMessage { - static const IpcId kIpcId = IpcId::Shutdown; +MethodType kMethodType = "shutdown"; + +struct In_Shutdown : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } }; -MAKE_REFLECT_STRUCT(Ipc_Shutdown, id); -REGISTER_IPC_MESSAGE(Ipc_Shutdown); +MAKE_REFLECT_STRUCT(In_Shutdown, id); +REGISTER_IN_MESSAGE(In_Shutdown); struct Out_Shutdown : public lsOutMessage { lsRequestId id; // defaults to std::monostate (null) @@ -14,12 +16,13 @@ struct Out_Shutdown : public lsOutMessage { }; MAKE_REFLECT_STRUCT(Out_Shutdown, jsonrpc, id, result); -struct ShutdownHandler : BaseMessageHandler { - void Run(Ipc_Shutdown* request) override { +struct Handler_Shutdown : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_Shutdown* request) override { Out_Shutdown out; out.id = request->id; - QueueManager::WriteStdout(IpcId::TextDocumentDefinition, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(ShutdownHandler); +REGISTER_MESSAGE_HANDLER(Handler_Shutdown); } // namespace diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index 559cae308..487fbca3a 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -11,6 +11,7 @@ #include namespace { +MethodType kMethodType = "textDocument/codeAction"; optional FindIncludeLine(const std::vector& lines, const std::string& full_include_line) { @@ -256,9 +257,9 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, return nullopt; } -struct Ipc_TextDocumentCodeAction - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentCodeAction; +struct In_TextDocumentCodeAction : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } + // Contains additional diagnostic information about the context in which // a code action is run. struct lsCodeActionContext { @@ -276,14 +277,14 @@ struct Ipc_TextDocumentCodeAction }; lsCodeActionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionContext, +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, diagnostics); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionParams, +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument, range, context); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeAction); +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); struct Out_TextDocumentCodeAction : public lsOutMessage { @@ -294,9 +295,11 @@ struct Out_TextDocumentCodeAction }; MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result); -struct TextDocumentCodeActionHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentCodeAction* request) override { +struct Handler_TextDocumentCodeAction + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_TextDocumentCodeAction* request) override { // NOTE: This code snippet will generate some FixIts for testing: // // struct origin { int x, int y }; @@ -534,10 +537,10 @@ struct TextDocumentCodeActionHandler } } - QueueManager::WriteStdout(IpcId::TextDocumentCodeAction, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentCodeActionHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); TEST_SUITE("FindIncludeLine") { TEST_CASE("in document") { diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 239a543a2..f735f1bb6 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -5,19 +5,20 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "textDocument/codeLens"; + struct lsDocumentCodeLensParams { lsTextDocumentIdentifier textDocument; }; MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument); using TCodeLens = lsCodeLens; -struct Ipc_TextDocumentCodeLens - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentCodeLens; +struct In_TextDocumentCodeLens : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsDocumentCodeLensParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeLens, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeLens); +MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentCodeLens); struct Out_TextDocumentCodeLens : public lsOutMessage { @@ -81,9 +82,10 @@ void AddCodeLens(const char* singular, common->result->push_back(code_lens); } -struct TextDocumentCodeLensHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentCodeLens* request) override { +struct Handler_TextDocumentCodeLens + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentCodeLens* request) override { Out_TextDocumentCodeLens out; out.id = request->id; @@ -225,8 +227,8 @@ struct TextDocumentCodeLensHandler }; } - QueueManager::WriteStdout(IpcId::TextDocumentCodeLens, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentCodeLensHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); } // namespace diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index aec06e27c..43dc6c8cd 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -14,6 +14,7 @@ #include namespace { +MethodType kMethodType = "textDocument/completion"; // How a completion was triggered enum class lsCompletionTriggerKind { @@ -47,13 +48,12 @@ struct lsCompletionParams : lsTextDocumentPositionParams { }; MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); -struct Ipc_TextDocumentComplete - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentCompletion; +struct In_TextDocumentComplete : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsCompletionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentComplete, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentComplete); +MAKE_REFLECT_STRUCT(In_TextDocumentComplete, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentComplete); struct lsTextDocumentCompleteResult { // This list it not complete. Further typing should result in recomputing @@ -216,17 +216,17 @@ void FilterAndSortCompletionResponse( finalize(); } -struct TextDocumentCompletionHandler : MessageHandler { - IpcId GetId() const override { return IpcId::TextDocumentCompletion; } +struct Handler_TextDocumentCompletion : MessageHandler { + MethodType GetMethodType() const override { return kMethodType; } void Run(std::unique_ptr message) override { - auto request = std::shared_ptr( - static_cast(message.release())); + auto request = std::shared_ptr( + static_cast(message.release())); auto write_empty_result = [request]() { Out_TextDocumentComplete out; out.id = request->id; - QueueManager::WriteStdout(IpcId::TextDocumentCompletion, out); + QueueManager::WriteStdout(kMethodType, out); }; std::string path = request->params.textDocument.uri.GetPath(); @@ -324,7 +324,7 @@ struct TextDocumentCompletionHandler : MessageHandler { item.textEdit->range.end.character = (int)buffer_line.size(); } - QueueManager::WriteStdout(IpcId::TextDocumentCompletion, out); + QueueManager::WriteStdout(kMethodType, out); } else { ClangCompleteManager::OnComplete callback = std::bind( [this, is_global_completion, existing_completion, request]( @@ -337,7 +337,7 @@ struct TextDocumentCompletionHandler : MessageHandler { // Emit completion results. FilterAndSortCompletionResponse(&out, existing_completion, config->completion.filterAndSort); - QueueManager::WriteStdout(IpcId::TextDocumentCompletion, out); + QueueManager::WriteStdout(kMethodType, out); // Cache completion results. if (!is_cached_result) { @@ -395,6 +395,6 @@ struct TextDocumentCompletionHandler : MessageHandler { } } }; -REGISTER_MESSAGE_HANDLER(TextDocumentCompletionHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCompletion); } // namespace diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index e5823794c..95410f0e5 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -8,14 +8,14 @@ #include namespace { +MethodType kMethodType = "textDocument/definition"; -struct Ipc_TextDocumentDefinition - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentDefinition; +struct In_TextDocumentDefinition : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDefinition, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDefinition); +MAKE_REFLECT_STRUCT(In_TextDocumentDefinition, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentDefinition); struct Out_TextDocumentDefinition : public lsOutMessage { @@ -46,9 +46,10 @@ std::vector GetNonDefDeclarationTargets(QueryDatabase* db, SymbolRef sym) { } } -struct TextDocumentDefinitionHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDefinition* request) override { +struct Handler_TextDocumentDefinition + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentDefinition* request) override { QueryFileId file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, @@ -165,8 +166,8 @@ struct TextDocumentDefinitionHandler } } - QueueManager::WriteStdout(IpcId::TextDocumentDefinition, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDefinitionHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); } // namespace diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index d32f20977..fb16e3c32 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -8,18 +8,21 @@ #include namespace { -struct Ipc_TextDocumentDidChange - : public NotificationMessage { - const static IpcId kIpcId = IpcId::TextDocumentDidChange; +MethodType kMethodType = "textDocument/didChange"; + +struct In_TextDocumentDidChange : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentDidChangeParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidChange, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidChange); +MAKE_REFLECT_STRUCT(In_TextDocumentDidChange, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidChange); + +struct Handler_TextDocumentDidChange + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct TextDocumentDidChangeHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDidChange* request) override { + void Run(In_TextDocumentDidChange* request) override { std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); if (config->enableIndexOnDidChange) { @@ -40,5 +43,5 @@ struct TextDocumentDidChangeHandler request->params.textDocument.AsTextDocumentIdentifier()); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDidChangeHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); } // namespace diff --git a/src/messages/text_document_did_close.cc b/src/messages/text_document_did_close.cc index d83f0fa66..e76ee52f6 100644 --- a/src/messages/text_document_did_close.cc +++ b/src/messages/text_document_did_close.cc @@ -4,32 +4,35 @@ #include "working_files.h" namespace { -struct Ipc_TextDocumentDidClose - : public NotificationMessage { - const static IpcId kIpcId = IpcId::TextDocumentDidClose; +MethodType kMethodType = "textDocument/didClose"; + +struct In_TextDocumentDidClose : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose::Params, textDocument); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidClose); +MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); +MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidClose); + +struct Handler_TextDocumentDidClose + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct TextDocumentDidCloseHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDidClose* request) override { + void Run(In_TextDocumentDidClose* request) override { std::string path = request->params.textDocument.uri.GetPath(); // Clear any diagnostics for the file. Out_TextDocumentPublishDiagnostics out; out.params.uri = request->params.textDocument.uri; - QueueManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out); + QueueManager::WriteStdout(kMethodType, out); // Remove internal state. working_files->OnClose(request->params.textDocument); clang_complete->NotifyClose(path); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDidCloseHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); } // namespace diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index e354e449e..2b2562d88 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -10,10 +10,12 @@ #include namespace { +MethodType kMethodType = "textDocument/didOpen"; + // Open, view, change, close file -struct Ipc_TextDocumentDidOpen - : public NotificationMessage { - const static IpcId kIpcId = IpcId::TextDocumentDidOpen; +struct In_TextDocumentDidOpen : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } + struct Params { lsTextDocumentItem textDocument; @@ -24,13 +26,15 @@ struct Ipc_TextDocumentDidOpen }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen::Params, textDocument, args); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidOpen); +MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen::Params, textDocument, args); +MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidOpen); + +struct Handler_TextDocumentDidOpen + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct TextDocumentDidOpenHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDidOpen* request) override { + void Run(In_TextDocumentDidOpen* request) override { // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. const auto& params = request->params; @@ -75,5 +79,5 @@ struct TextDocumentDidOpenHandler } } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDidOpenHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); } // namespace diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 3635d7679..7eec5dd0d 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -7,9 +7,11 @@ #include namespace { -struct Ipc_TextDocumentDidSave - : public NotificationMessage { - const static IpcId kIpcId = IpcId::TextDocumentDidSave; +MethodType kMethodType = "textDocument/didSave"; + +struct In_TextDocumentDidSave : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } + struct Params { // The document that was saved. lsTextDocumentIdentifier textDocument; @@ -20,13 +22,15 @@ struct Ipc_TextDocumentDidSave }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave::Params, textDocument); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidSave); +MAKE_REFLECT_STRUCT(In_TextDocumentDidSave::Params, textDocument); +MAKE_REFLECT_STRUCT(In_TextDocumentDidSave, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidSave); + +struct Handler_TextDocumentDidSave + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } -struct TextDocumentDidSaveHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDidSave* request) override { + void Run(In_TextDocumentDidSave* request) override { std::string path = request->params.textDocument.uri.GetPath(); if (ShouldIgnoreFileForIndexing(path)) return; @@ -61,5 +65,5 @@ struct TextDocumentDidSaveHandler clang_complete->NotifySave(path); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDidSaveHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); } // namespace diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index 1183e1d51..b01bc7a6a 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -4,13 +4,14 @@ #include "symbol.h" namespace { -struct Ipc_TextDocumentDocumentHighlight - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentDocumentHighlight; +MethodType kMethodType = "textDocument/documentHighlight"; + +struct In_TextDocumentDocumentHighlight : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentHighlight, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentHighlight); +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight); struct Out_TextDocumentDocumentHighlight : public lsOutMessage { @@ -19,9 +20,10 @@ struct Out_TextDocumentDocumentHighlight }; MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result); -struct TextDocumentDocumentHighlightHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDocumentHighlight* request) override { +struct Handler_TextDocumentDocumentHighlight + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentDocumentHighlight* request) override { QueryFileId file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, @@ -59,8 +61,8 @@ struct TextDocumentDocumentHighlightHandler break; } - QueueManager::WriteStdout(IpcId::TextDocumentDocumentHighlight, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDocumentHighlightHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); } // namespace diff --git a/src/messages/text_document_document_link.cc b/src/messages/text_document_document_link.cc index b68bfbcc9..fc6994faf 100644 --- a/src/messages/text_document_document_link.cc +++ b/src/messages/text_document_document_link.cc @@ -6,18 +6,19 @@ #include namespace { -struct Ipc_TextDocumentDocumentLink - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentDocumentLink; +MethodType kMethodType = "textDocument/documentLink"; + +struct In_TextDocumentDocumentLink : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { // The document to provide document links for. lsTextDocumentIdentifier textDocument; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink::Params, textDocument); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentLink); +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentLink::Params, textDocument); +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentLink, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentDocumentLink); // A document link is a range in a text document that links to an internal or // external resource, like another text document or a web site. @@ -36,9 +37,10 @@ struct Out_TextDocumentDocumentLink }; MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentLink, jsonrpc, id, result); -struct TextDocumentDocumentLinkHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDocumentLink* request) override { +struct Handler_TextDocumentDocumentLink + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentDocumentLink* request) override { Out_TextDocumentDocumentLink out; out.id = request->id; @@ -76,8 +78,8 @@ struct TextDocumentDocumentLinkHandler } } - QueueManager::WriteStdout(IpcId::TextDocumentDocumentLink, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDocumentLinkHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentLink); } // namespace diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 54e5cf28f..4a48a2d3f 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -3,18 +3,19 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "textDocument/documentSymbol"; + struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; }; MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); -struct Ipc_TextDocumentDocumentSymbol - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentDocumentSymbol; +struct In_TextDocumentDocumentSymbol : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsDocumentSymbolParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentSymbol, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentSymbol); +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); struct Out_TextDocumentDocumentSymbol : public lsOutMessage { @@ -23,9 +24,10 @@ struct Out_TextDocumentDocumentSymbol }; MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result); -struct TextDocumentDocumentSymbolHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentDocumentSymbol* request) override { +struct Handler_TextDocumentDocumentSymbol + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentDocumentSymbol* request) override { Out_TextDocumentDocumentSymbol out; out.id = request->id; @@ -62,8 +64,8 @@ struct TextDocumentDocumentSymbolHandler } } - QueueManager::WriteStdout(IpcId::TextDocumentDocumentSymbol, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentDocumentSymbolHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); } // namespace diff --git a/src/messages/text_document_formatting.cc b/src/messages/text_document_formatting.cc index 08a8d1a2a..55c8f4876 100644 --- a/src/messages/text_document_formatting.cc +++ b/src/messages/text_document_formatting.cc @@ -6,19 +6,19 @@ #include namespace { +MethodType kMethodType = "textDocument/formatting"; -struct Ipc_TextDocumentFormatting - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentFormatting; +struct In_TextDocumentFormatting : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; lsFormattingOptions options; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentFormatting::Params, textDocument, options); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentFormatting, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentFormatting); +MAKE_REFLECT_STRUCT(In_TextDocumentFormatting::Params, textDocument, options); +MAKE_REFLECT_STRUCT(In_TextDocumentFormatting, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentFormatting); struct Out_TextDocumentFormatting : public lsOutMessage { @@ -27,9 +27,10 @@ struct Out_TextDocumentFormatting }; MAKE_REFLECT_STRUCT(Out_TextDocumentFormatting, jsonrpc, id, result); -struct TextDocumentFormattingHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentFormatting* request) override { +struct Handler_TextDocumentFormatting + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentFormatting* request) override { Out_TextDocumentFormatting response; response.id = request->id; #if USE_CLANG_CXX @@ -54,8 +55,8 @@ struct TextDocumentFormattingHandler response.result = {}; #endif - QueueManager::WriteStdout(IpcId::TextDocumentFormatting, response); + QueueManager::WriteStdout(kMethodType, response); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentFormattingHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); } // namespace diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 9af5f077e..2dbf26a13 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -3,6 +3,7 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "textDocument/hover"; std::pair GetCommentsAndHover( QueryDatabase* db, @@ -41,12 +42,12 @@ std::pair GetCommentsAndHover( return {"", ""}; } -struct Ipc_TextDocumentHover : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentHover; +struct In_TextDocumentHover : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentHover, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentHover); +MAKE_REFLECT_STRUCT(In_TextDocumentHover, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentHover); struct Out_TextDocumentHover : public lsOutMessage { struct Result { @@ -73,8 +74,9 @@ void Reflect(Writer& visitor, Out_TextDocumentHover& value) { REFLECT_MEMBER_END(); } -struct TextDocumentHoverHandler : BaseMessageHandler { - void Run(Ipc_TextDocumentHover* request) override { +struct Handler_TextDocumentHover : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentHover* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -111,8 +113,8 @@ struct TextDocumentHoverHandler : BaseMessageHandler { } } - QueueManager::WriteStdout(IpcId::TextDocumentHover, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentHoverHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); } // namespace diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc index 93608905f..29605e50e 100644 --- a/src/messages/text_document_range_formatting.cc +++ b/src/messages/text_document_range_formatting.cc @@ -7,6 +7,7 @@ #include namespace { +MethodType kMethodType = "textDocument/rangeFormatting"; struct lsTextDocumentRangeFormattingParams { lsTextDocumentIdentifier textDocument; @@ -18,13 +19,12 @@ MAKE_REFLECT_STRUCT(lsTextDocumentRangeFormattingParams, range, options); -struct Ipc_TextDocumentRangeFormatting - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentRangeFormatting; +struct In_TextDocumentRangeFormatting : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentRangeFormattingParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentRangeFormatting, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentRangeFormatting); +MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentRangeFormatting); struct Out_TextDocumentRangeFormatting : public lsOutMessage { @@ -33,9 +33,11 @@ struct Out_TextDocumentRangeFormatting }; MAKE_REFLECT_STRUCT(Out_TextDocumentRangeFormatting, jsonrpc, id, result); -struct TextDocumentRangeFormattingHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentRangeFormatting* request) override { +struct Handler_TextDocumentRangeFormatting + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_TextDocumentRangeFormatting* request) override { Out_TextDocumentRangeFormatting response; response.id = request->id; #if USE_CLANG_CXX @@ -62,8 +64,8 @@ struct TextDocumentRangeFormattingHandler response.result = {}; #endif - QueueManager::WriteStdout(IpcId::TextDocumentRangeFormatting, response); + QueueManager::WriteStdout(kMethodType, response); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentRangeFormattingHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); } // namespace diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index f905dcb2c..bd6896d78 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -5,9 +5,10 @@ #include namespace { -struct Ipc_TextDocumentReferences - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentReferences; +MethodType kMethodType = "textDocument/references"; + +struct In_TextDocumentReferences : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct lsReferenceContext { // Include the declaration of the current symbol. bool includeDeclaration; @@ -22,15 +23,15 @@ struct Ipc_TextDocumentReferences Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::lsReferenceContext, +MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, includeDeclaration, role); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::Params, +MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position, context); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentReferences); +MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentReferences); struct Out_TextDocumentReferences : public lsOutMessage { @@ -39,9 +40,11 @@ struct Out_TextDocumentReferences }; MAKE_REFLECT_STRUCT(Out_TextDocumentReferences, jsonrpc, id, result); -struct TextDocumentReferencesHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentReferences* request) override { +struct Handler_TextDocumentReferences + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_TextDocumentReferences* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -93,8 +96,8 @@ struct TextDocumentReferencesHandler if ((int)out.result.size() >= config->xref.maxNum) out.result.resize(config->xref.maxNum); - QueueManager::WriteStdout(IpcId::TextDocumentReferences, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentReferencesHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); } // namespace diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index 719eddfe2..b44048ad4 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -3,6 +3,7 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "textDocument/rename"; lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, @@ -47,8 +48,8 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, return edit; } -struct Ipc_TextDocumentRename : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentRename; +struct In_TextDocumentRename : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { // The document to format. lsTextDocumentIdentifier textDocument; @@ -63,12 +64,12 @@ struct Ipc_TextDocumentRename : public RequestMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename::Params, +MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position, newName); -MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentRename); +MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentRename); struct Out_TextDocumentRename : public lsOutMessage { lsRequestId id; @@ -76,8 +77,9 @@ struct Out_TextDocumentRename : public lsOutMessage { }; MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result); -struct TextDocumentRenameHandler : BaseMessageHandler { - void Run(Ipc_TextDocumentRename* request) override { +struct Handler_TextDocumentRename : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentRename* request) override { QueryFileId file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, @@ -100,8 +102,8 @@ struct TextDocumentRenameHandler : BaseMessageHandler { break; } - QueueManager::WriteStdout(IpcId::TextDocumentRename, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentRenameHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); } // namespace diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index ec1a9c907..c4e740297 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -7,13 +7,14 @@ #include namespace { -struct Ipc_TextDocumentSignatureHelp - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentSignatureHelp; +MethodType kMethodType = "textDocument/signatureHelp"; + +struct In_TextDocumentSignatureHelp : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentSignatureHelp, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentSignatureHelp); +MAKE_REFLECT_STRUCT(In_TextDocumentSignatureHelp, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentSignatureHelp); // Represents a parameter of a callable-signature. A parameter can // have a label and a doc-comment. @@ -82,11 +83,11 @@ struct Out_TextDocumentSignatureHelp }; MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result); -struct TextDocumentSignatureHelpHandler : MessageHandler { - IpcId GetId() const override { return IpcId::TextDocumentSignatureHelp; } +struct Handler_TextDocumentSignatureHelp : MessageHandler { + MethodType GetMethodType() const override { return kMethodType; } void Run(std::unique_ptr message) override { - auto request = message->As(); + auto request = static_cast(message.get()); lsTextDocumentPositionParams& params = request->params; WorkingFile* file = working_files->GetFileByFilename(params.textDocument.uri.GetPath()); @@ -105,7 +106,7 @@ struct TextDocumentSignatureHelpHandler : MessageHandler { [this](BaseIpcMessage* message, std::string search, int active_param, const std::vector& results, bool is_cached_result) { - auto msg = message->As(); + auto msg = static_cast(message); Out_TextDocumentSignatureHelp out; out.id = msg->id; @@ -142,7 +143,7 @@ struct TextDocumentSignatureHelpHandler : MessageHandler { out.result.activeParameter = active_param; Timer timer; - QueueManager::WriteStdout(IpcId::TextDocumentSignatureHelp, out); + QueueManager::WriteStdout(kMethodType, out); if (!is_cached_result) { signature_cache->WithLock([&]() { @@ -168,5 +169,5 @@ struct TextDocumentSignatureHelpHandler : MessageHandler { } } }; -REGISTER_MESSAGE_HANDLER(TextDocumentSignatureHelpHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentSignatureHelp); } // namespace diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index dac467aee..9797af8af 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -3,14 +3,14 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "textDocument/typeDefinition"; -struct Ipc_TextDocumentTypeDefinition - : public RequestMessage { - const static IpcId kIpcId = IpcId::TextDocumentTypeDefinition; +struct In_TextDocumentTypeDefinition : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(Ipc_TextDocumentTypeDefinition, id, params); -REGISTER_IPC_MESSAGE(Ipc_TextDocumentTypeDefinition); +MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition); struct Out_TextDocumentTypeDefinition : public lsOutMessage { @@ -19,9 +19,10 @@ struct Out_TextDocumentTypeDefinition }; MAKE_REFLECT_STRUCT(Out_TextDocumentTypeDefinition, jsonrpc, id, result); -struct TextDocumentTypeDefinitionHandler - : BaseMessageHandler { - void Run(Ipc_TextDocumentTypeDefinition* request) override { +struct Handler_TextDocumentTypeDefinition + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_TextDocumentTypeDefinition* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, @@ -59,9 +60,9 @@ struct TextDocumentTypeDefinitionHandler } } - QueueManager::WriteStdout(IpcId::TextDocumentTypeDefinition, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(TextDocumentTypeDefinitionHandler); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); } // namespace diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 3506cf59e..8714217a3 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -9,22 +9,24 @@ #include namespace { +MethodType kMethodType = "workspace/didChangeConfiguration"; + struct lsDidChangeConfigurationParams { bool placeholder; }; MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); -struct Ipc_WorkspaceDidChangeConfiguration - : public NotificationMessage { - const static IpcId kIpcId = IpcId::WorkspaceDidChangeConfiguration; +struct In_WorkspaceDidChangeConfiguration : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } lsDidChangeConfigurationParams params; }; -MAKE_REFLECT_STRUCT(Ipc_WorkspaceDidChangeConfiguration, params); -REGISTER_IPC_MESSAGE(Ipc_WorkspaceDidChangeConfiguration); +MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeConfiguration, params); +REGISTER_IN_MESSAGE(In_WorkspaceDidChangeConfiguration); -struct WorkspaceDidChangeConfigurationHandler - : BaseMessageHandler { - void Run(Ipc_WorkspaceDidChangeConfiguration* request) override { +struct Handler_WorkspaceDidChangeConfiguration + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_WorkspaceDidChangeConfiguration* request) override { Timer time; project->Load(config, config->projectRoot); time.ResetAndPrint("[perf] Loaded compilation entries (" + @@ -40,5 +42,5 @@ struct WorkspaceDidChangeConfigurationHandler LOG_S(INFO) << "Flushed all clang complete sessions"; } }; -REGISTER_MESSAGE_HANDLER(WorkspaceDidChangeConfigurationHandler); +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeConfiguration); } // namespace diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 18e58d0c1..88471b940 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -8,6 +8,8 @@ #include namespace { +MethodType kMethodType = "workspace/didChangeWatchedFiles"; + enum class lsFileChangeType { Created = 1, Changed = 2, @@ -26,17 +28,17 @@ struct lsDidChangeWatchedFilesParams { }; MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes); -struct Ipc_WorkspaceDidChangeWatchedFiles - : public NotificationMessage { - const static IpcId kIpcId = IpcId::WorkspaceDidChangeWatchedFiles; +struct In_WorkspaceDidChangeWatchedFiles : public NotificationMessage { + MethodType GetMethodType() const override { return kMethodType; } lsDidChangeWatchedFilesParams params; }; -MAKE_REFLECT_STRUCT(Ipc_WorkspaceDidChangeWatchedFiles, params); -REGISTER_IPC_MESSAGE(Ipc_WorkspaceDidChangeWatchedFiles); +MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeWatchedFiles, params); +REGISTER_IN_MESSAGE(In_WorkspaceDidChangeWatchedFiles); -struct WorkspaceDidChangeWatchedFilesHandler - : BaseMessageHandler { - void Run(Ipc_WorkspaceDidChangeWatchedFiles* request) override { +struct Handler_WorkspaceDidChangeWatchedFiles + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_WorkspaceDidChangeWatchedFiles* request) override { for (lsFileEvent& event : request->params.changes) { std::string path = event.uri.GetPath(); auto it = project->absolute_path_to_entry_index_.find(path); @@ -69,5 +71,5 @@ struct WorkspaceDidChangeWatchedFilesHandler } } }; -REGISTER_MESSAGE_HANDLER(WorkspaceDidChangeWatchedFilesHandler); +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeWatchedFiles); } // namespace diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index adb405f45..f1600d895 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -4,14 +4,14 @@ #include "queue_manager.h" namespace { +MethodType kMethodType = "workspace/executeCommand"; -struct Ipc_WorkspaceExecuteCommand - : public RequestMessage { - const static IpcId kIpcId = IpcId::WorkspaceExecuteCommand; +struct In_WorkspaceExecuteCommand : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } lsCommand params; }; -MAKE_REFLECT_STRUCT(Ipc_WorkspaceExecuteCommand, id, params); -REGISTER_IPC_MESSAGE(Ipc_WorkspaceExecuteCommand); +MAKE_REFLECT_STRUCT(In_WorkspaceExecuteCommand, id, params); +REGISTER_IN_MESSAGE(In_WorkspaceExecuteCommand); struct Out_WorkspaceExecuteCommand : public lsOutMessage { @@ -28,9 +28,10 @@ void Reflect(Writer& visitor, Out_WorkspaceExecuteCommand& value) { REFLECT_MEMBER_END(); } -struct WorkspaceExecuteCommandHandler - : BaseMessageHandler { - void Run(Ipc_WorkspaceExecuteCommand* request) override { +struct Handler_WorkspaceExecuteCommand + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_WorkspaceExecuteCommand* request) override { const auto& params = request->params; Out_WorkspaceExecuteCommand out; out.id = request->id; @@ -41,9 +42,9 @@ struct WorkspaceExecuteCommandHandler out.result = params.arguments.locations; } - QueueManager::WriteStdout(IpcId::WorkspaceExecuteCommand, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(WorkspaceExecuteCommandHandler); +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); } // namespace diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 092167122..68d0abca9 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -12,6 +12,7 @@ #include namespace { +MethodType kMethodType = "workspace/symbol"; // Lookup |symbol| in |db| and insert the value into |result|. bool InsertSymbolIntoResult(QueryDatabase* db, @@ -42,16 +43,16 @@ bool InsertSymbolIntoResult(QueryDatabase* db, return true; } -struct Ipc_WorkspaceSymbol : public RequestMessage { - const static IpcId kIpcId = IpcId::WorkspaceSymbol; +struct In_WorkspaceSymbol : public RequestMessage { + MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string query; }; Params params; }; -MAKE_REFLECT_STRUCT(Ipc_WorkspaceSymbol::Params, query); -MAKE_REFLECT_STRUCT(Ipc_WorkspaceSymbol, id, params); -REGISTER_IPC_MESSAGE(Ipc_WorkspaceSymbol); +MAKE_REFLECT_STRUCT(In_WorkspaceSymbol::Params, query); +MAKE_REFLECT_STRUCT(In_WorkspaceSymbol, id, params); +REGISTER_IN_MESSAGE(In_WorkspaceSymbol); struct Out_WorkspaceSymbol : public lsOutMessage { lsRequestId id; @@ -61,8 +62,9 @@ MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result); ///// Fuzzy matching -struct WorkspaceSymbolHandler : BaseMessageHandler { - void Run(Ipc_WorkspaceSymbol* request) override { +struct Handler_WorkspaceSymbol : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_WorkspaceSymbol* request) override { Out_WorkspaceSymbol out; out.id = request->id; @@ -151,8 +153,8 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { LOG_S(INFO) << "[querydb] Found " << out.result.size() << " results for query " << query; - QueueManager::WriteStdout(IpcId::WorkspaceSymbol, out); + QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(WorkspaceSymbolHandler); +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); } // namespace diff --git a/src/methods.inc b/src/methods.inc deleted file mode 100644 index 8298c0d6e..000000000 --- a/src/methods.inc +++ /dev/null @@ -1,60 +0,0 @@ -// General -CASE(Initialize, "initialize") -CASE(Shutdown, "shutdown") - -CASE(CodeLensResolve, "codeLens/resolve") -CASE(TextDocumentCodeAction, "textDocument/codeAction") -CASE(TextDocumentCodeLens, "textDocument/codeLens") -CASE(TextDocumentCompletion, "textDocument/completion") -CASE(TextDocumentDefinition, "textDocument/definition") -CASE(TextDocumentDidChange, "textDocument/didChange") -CASE(TextDocumentDidClose, "textDocument/didClose") -CASE(TextDocumentDidOpen, "textDocument/didOpen") -CASE(TextDocumentDidSave, "textDocument/didSave") -CASE(TextDocumentDocumentHighlight, "textDocument/documentHighlight") -CASE(TextDocumentDocumentLink, "textDocument/documentLink") -CASE(TextDocumentDocumentSymbol, "textDocument/documentSymbol") -CASE(TextDocumentFormatting, "textDocument/formatting") -CASE(TextDocumentHover, "textDocument/hover") -CASE(TextDocumentOnTypeFormatting, "textDocument/onTypeFormatting") -CASE(TextDocumentPublishDiagnostics, "textDocument/publishDiagnostics") -CASE(TextDocumentRangeFormatting, "textDocument/rangeFormatting") -CASE(TextDocumentReferences, "textDocument/references") -CASE(TextDocumentRename, "textDocument/rename") -CASE(TextDocumentSignatureHelp, "textDocument/signatureHelp") -CASE(TextDocumentTypeDefinition, "textDocument/typeDefinition") -CASE(WorkspaceDidChangeConfiguration, "workspace/didChangeConfiguration") -CASE(WorkspaceDidChangeWatchedFiles, "workspace/didChangeWatchedFiles") -CASE(WorkspaceExecuteCommand, "workspace/executeCommand") -CASE(WorkspaceSymbol, "workspace/symbol") - -// Notification extensions -CASE(CqueryTextDocumentDidView, "$cquery/textDocumentDidView") -CASE(CqueryPublishInactiveRegions, "$cquery/publishInactiveRegions") -CASE(CqueryPublishSemanticHighlighting, "$cquery/publishSemanticHighlighting") - -// Request extensions -CASE(CqueryFileInfo, "$cquery/fileInfo") -CASE(CqueryFreshenIndex, "$cquery/freshenIndex") - -CASE(CqueryCallHierarchy, "$cquery/callHierarchy") -CASE(CqueryInheritanceHierarchy, "$cquery/inheritanceHierarchy") -CASE(CqueryMemberHierarchy, "$cquery/memberHierarchy") - -// Cross reference extensions. -// Show all variables of a type. -CASE(CqueryVars, "$cquery/vars") -// Show all callers of a function. -CASE(CqueryCallers, "$cquery/callers") -// Show base types/method. -CASE(CqueryBase, "$cquery/base") -// Show all derived types/methods. -CASE(CqueryDerived, "$cquery/derived") -// Show random definition. -CASE(CqueryRandom, "$cquery/random") - -// Messages for testing. -// Index the given file contents. -CASE(CqueryIndexFile, "$cquery/indexFile") -// Wait until all cquery threads are idle. -CASE(CqueryWait, "$cquery/wait") diff --git a/src/queue_manager.cc b/src/queue_manager.cc index c3a24cfdd..edcec6d29 100644 --- a/src/queue_manager.cc +++ b/src/queue_manager.cc @@ -63,13 +63,13 @@ void QueueManager::Init(MultiQueueWaiter* querydb_waiter, } // static -void QueueManager::WriteStdout(IpcId id, lsBaseOutMessage& response) { +void QueueManager::WriteStdout(MethodType method, lsBaseOutMessage& response) { std::ostringstream sstream; response.Write(sstream); Stdout_Request out; out.content = sstream.str(); - out.id = id; + out.method = method; instance()->for_stdout.PushBack(std::move(out)); } diff --git a/src/queue_manager.h b/src/queue_manager.h index 61db1d233..34cc3b007 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -11,7 +11,7 @@ struct ICacheManager; struct lsBaseOutMessage; struct Stdout_Request { - IpcId id; + MethodType method; std::string content; }; @@ -86,7 +86,7 @@ class QueueManager { static void Init(MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter, MultiQueueWaiter* stdout_waiter); - static void WriteStdout(IpcId id, lsBaseOutMessage& response); + static void WriteStdout(MethodType method, lsBaseOutMessage& response); bool HasWork(); From 7ff4a9aac94226048c92c822668174bdcd9a5586 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Wed, 21 Mar 2018 22:01:21 -0700 Subject: [PATCH 034/378] ipc.h -> method.h, rename some types --- CMakeLists.txt | 34 +++++++++---------- src/command_line.cc | 4 +-- src/lsp.cc | 4 +-- src/lsp.h | 10 +++--- src/message_handler.h | 6 ++-- src/messages/cquery_base.cc | 2 +- src/messages/cquery_call_hierarchy.cc | 2 +- src/messages/cquery_callers.cc | 2 +- src/messages/cquery_derived.cc | 2 +- src/messages/cquery_did_view.cc | 2 +- src/messages/cquery_file_info.cc | 2 +- src/messages/cquery_freshen_index.cc | 2 +- src/messages/cquery_index_file.cc | 2 +- src/messages/cquery_inheritance_hierarchy.cc | 2 +- src/messages/cquery_member_hierarchy.cc | 2 +- src/messages/cquery_random.cc | 2 +- src/messages/cquery_vars.cc | 2 +- src/messages/cquery_wait.cc | 4 +-- src/messages/exit.cc | 4 +-- src/messages/initialize.cc | 2 +- src/messages/shutdown.cc | 2 +- src/messages/text_document_code_action.cc | 2 +- src/messages/text_document_code_lens.cc | 2 +- src/messages/text_document_completion.cc | 4 +-- src/messages/text_document_definition.cc | 2 +- src/messages/text_document_did_change.cc | 2 +- src/messages/text_document_did_close.cc | 2 +- src/messages/text_document_did_open.cc | 2 +- src/messages/text_document_did_save.cc | 2 +- .../text_document_document_highlight.cc | 2 +- src/messages/text_document_document_link.cc | 2 +- src/messages/text_document_document_symbol.cc | 2 +- src/messages/text_document_formatting.cc | 2 +- src/messages/text_document_hover.cc | 2 +- .../text_document_range_formatting.cc | 2 +- src/messages/text_document_references.cc | 2 +- src/messages/text_document_rename.cc | 2 +- src/messages/text_document_signature_help.cc | 6 ++-- src/messages/text_document_type_definition.cc | 2 +- .../workspace_did_change_configuration.cc | 2 +- .../workspace_did_change_watched_files.cc | 2 +- src/messages/workspace_execute_command.cc | 2 +- src/messages/workspace_symbol.cc | 2 +- src/{ipc.cc => method.cc} | 12 ++++--- src/{ipc.h => method.h} | 21 ++++++------ src/project.h | 3 +- src/queue_manager.h | 4 +-- 47 files changed, 94 insertions(+), 90 deletions(-) rename src/{ipc.cc => method.cc} (68%) rename src/{ipc.h => method.h} (63%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0244908c7..beca46ea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ add_executable(cquery "") ### Compile options # CMake default compile flags: -# MSVC + Clang(Windows): +# MSVC + Clang(Windows): # debug: /MDd /Zi /Ob0 /Od /RTC1 # release: /MD /O2 /Ob2 /DNDEBUG # GCC + Clang(Linux): @@ -32,15 +32,15 @@ set_property(TARGET cquery PROPERTY CXX_EXTENSIONS OFF) if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Common MSVC/Clang(Windows) options - target_compile_options(cquery PRIVATE - /nologo - /EHsc + target_compile_options(cquery PRIVATE + /nologo + /EHsc /W3 # roughly -Wall /wd4996 # disable loguru unsafe warnings - /wd4722 # ignores warning C4722 + /wd4722 # ignores warning C4722 # (destructor never returns) in loguru - /wd4267 # ignores warning C4267 - # (conversion from 'size_t' to 'type'), + /wd4267 # ignores warning C4267 + # (conversion from 'size_t' to 'type'), # roughly -Wno-sign-compare /wd4800 $<$:/FS> @@ -48,8 +48,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) else() # Common GCC/Clang(Linux) options target_compile_options(cquery PRIVATE - -Wall - -Wno-sign-compare + -Wall + -Wno-sign-compare ) if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) @@ -57,14 +57,14 @@ else() endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) - target_compile_options(cquery PRIVATE + target_compile_options(cquery PRIVATE $<$:-fno-limit-debug-info>) endif() if(CLANG_CXX) # -Wno-comment: include/clang/Format/Format.h error: multi-line comment # -fno-rtti: # Without -fno-rtti, some Clang C++ functions may report - # `undefined references to typeinfo` + # `undefined references to typeinfo` target_compile_options(cquery PRIVATE -Wno-comment -fno-rtti) endif() @@ -148,21 +148,21 @@ install(TARGETS cquery RUNTIME DESTINATION bin) if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) - set_property(TARGET cquery APPEND PROPERTY + set_property(TARGET cquery APPEND PROPERTY INSTALL_RPATH $ORIGIN/../lib) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - set_property(TARGET cquery APPEND PROPERTY - INSTALL_RPATH @loader_path/../lib) + set_property(TARGET cquery APPEND PROPERTY + INSTALL_RPATH @loader_path/../lib) endif() - file(GLOB LIBCLANG_PLUS_SYMLINKS + file(GLOB LIBCLANG_PLUS_SYMLINKS ${DOWNLOADED_CLANG_DIR}/lib/libclang.[so,dylib]*) install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib) endif() ### Sources -target_sources(cquery PRIVATE third_party/siphash.cc) +target_sources(cquery PRIVATE third_party/siphash.cc) target_sources(cquery PRIVATE src/cache_manager.cc @@ -183,7 +183,7 @@ target_sources(cquery PRIVATE src/import_manager.cc src/import_pipeline.cc src/include_complete.cc - src/ipc.cc + src/method.cc src/lex_utils.cc src/lsp_diagnostic.cc src/lsp.cc diff --git a/src/command_line.cc b/src/command_line.cc index 6229ad330..14bd2c357 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -137,7 +137,7 @@ bool QueryDbMainLoop(Config* config, CodeCompleteCache* non_global_code_complete_cache, CodeCompleteCache* signature_cache) { auto* queue = QueueManager::instance(); - std::vector> messages = + std::vector> messages = queue->for_querydb.DequeueAll(); bool did_work = messages.size(); for (auto& message : messages) { @@ -281,7 +281,7 @@ void LaunchStdinLoop(Config* config, WorkThread::StartThread("stdin", [request_times]() { auto* queue = QueueManager::instance(); while (true) { - std::unique_ptr message; + std::unique_ptr message; optional err = MessageRegistry::instance()->ReadMessageFromStdin(&message); diff --git a/src/lsp.cc b/src/lsp.cc index 38fdee6fe..07daebe67 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -123,7 +123,7 @@ optional ReadCharFromStdinBlocking() { } optional MessageRegistry::ReadMessageFromStdin( - std::unique_ptr* message) { + std::unique_ptr* message) { optional content = ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking); if (!content) { @@ -141,7 +141,7 @@ optional MessageRegistry::ReadMessageFromStdin( optional MessageRegistry::Parse( Reader& visitor, - std::unique_ptr* message) { + std::unique_ptr* message) { if (!visitor.HasMember("jsonrpc") || std::string(visitor["jsonrpc"]->GetString()) != "2.0") { LOG_S(FATAL) << "Bad or missing jsonrpc version"; diff --git a/src/lsp.h b/src/lsp.h index e0d70cb50..88e06358d 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -1,7 +1,7 @@ #pragma once #include "config.h" -#include "ipc.h" +#include "method.h" #include "serializer.h" #include "utils.h" @@ -32,13 +32,13 @@ struct MessageRegistry { static MessageRegistry* instance(); using Allocator = - std::function*)>; + std::function*)>; std::unordered_map allocators; optional ReadMessageFromStdin( - std::unique_ptr* message); + std::unique_ptr* message); optional Parse(Reader& visitor, - std::unique_ptr* message); + std::unique_ptr* message); }; template @@ -47,7 +47,7 @@ struct MessageRegistryRegister { T dummy; std::string method_name = dummy.GetMethodType(); MessageRegistry::instance()->allocators[method_name] = - [](Reader& visitor, std::unique_ptr* message) { + [](Reader& visitor, std::unique_ptr* message) { *message = std::make_unique(); // Reflect may throw and *message will be partially deserialized. Reflect(visitor, static_cast(**message)); diff --git a/src/message_handler.h b/src/message_handler.h index a68990f4f..e838bfb1d 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -1,7 +1,7 @@ #pragma once -#include "ipc.h" #include "lsp.h" +#include "method.h" #include "query.h" #include @@ -87,7 +87,7 @@ struct MessageHandler { CodeCompleteCache* signature_cache = nullptr; virtual MethodType GetMethodType() const = 0; - virtual void Run(std::unique_ptr message) = 0; + virtual void Run(std::unique_ptr message) = 0; static std::vector* message_handlers; @@ -100,7 +100,7 @@ struct BaseMessageHandler : MessageHandler { virtual void Run(TMessage* message) = 0; // MessageHandler: - void Run(std::unique_ptr message) override { + void Run(std::unique_ptr message) override { Run(static_cast(message.get())); } }; diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index 05963f850..c38314333 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -6,7 +6,7 @@ namespace { MethodType kMethodType = "$cquery/base"; -struct In_CqueryBase : public RequestMessage { +struct In_CqueryBase : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; diff --git a/src/messages/cquery_call_hierarchy.cc b/src/messages/cquery_call_hierarchy.cc index 7143680ba..9f6e576f8 100644 --- a/src/messages/cquery_call_hierarchy.cc +++ b/src/messages/cquery_call_hierarchy.cc @@ -20,7 +20,7 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct In_CqueryCallHierarchy : public RequestMessage { +struct In_CqueryCallHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { diff --git a/src/messages/cquery_callers.cc b/src/messages/cquery_callers.cc index 4214253f8..701aefbe0 100644 --- a/src/messages/cquery_callers.cc +++ b/src/messages/cquery_callers.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/callers"; -struct In_CqueryCallers : public RequestMessage { +struct In_CqueryCallers : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/cquery_derived.cc b/src/messages/cquery_derived.cc index e43da9123..9700e88f6 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/cquery_derived.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/derived"; -struct In_CqueryDerived : public RequestMessage { +struct In_CqueryDerived : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/cquery_did_view.cc b/src/messages/cquery_did_view.cc index d01f6d95d..73da37da8 100644 --- a/src/messages/cquery_did_view.cc +++ b/src/messages/cquery_did_view.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/textDocumentDidView"; -struct In_CqueryTextDocumentDidView : public NotificationMessage { +struct In_CqueryTextDocumentDidView : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsDocumentUri textDocumentUri; diff --git a/src/messages/cquery_file_info.cc b/src/messages/cquery_file_info.cc index 22db960cd..a72612d6e 100644 --- a/src/messages/cquery_file_info.cc +++ b/src/messages/cquery_file_info.cc @@ -10,7 +10,7 @@ struct lsDocumentSymbolParams { }; MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); -struct In_CqueryFileInfo : public RequestMessage { +struct In_CqueryFileInfo : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDocumentSymbolParams params; }; diff --git a/src/messages/cquery_freshen_index.cc b/src/messages/cquery_freshen_index.cc index 0b7cc073d..e52b52368 100644 --- a/src/messages/cquery_freshen_index.cc +++ b/src/messages/cquery_freshen_index.cc @@ -15,7 +15,7 @@ namespace { MethodType kMethodType = "$cquery/freshenIndex"; -struct In_CqueryFreshenIndex : public NotificationMessage { +struct In_CqueryFreshenIndex : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { bool dependencies = true; diff --git a/src/messages/cquery_index_file.cc b/src/messages/cquery_index_file.cc index 0d188ea6e..9e1065582 100644 --- a/src/messages/cquery_index_file.cc +++ b/src/messages/cquery_index_file.cc @@ -8,7 +8,7 @@ namespace { MethodType kMethodType = "$cquery/indexFile"; -struct In_CqueryIndexFile : public NotificationMessage { +struct In_CqueryIndexFile : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string path; diff --git a/src/messages/cquery_inheritance_hierarchy.cc b/src/messages/cquery_inheritance_hierarchy.cc index 3c024619f..17a0b1baa 100644 --- a/src/messages/cquery_inheritance_hierarchy.cc +++ b/src/messages/cquery_inheritance_hierarchy.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/inheritanceHierarchy"; -struct In_CqueryInheritanceHierarchy : public RequestMessage { +struct In_CqueryInheritanceHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // If id+kind are specified, expand a node; otherwise textDocument+position diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/cquery_member_hierarchy.cc index b4f03763f..e98e53d53 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/cquery_member_hierarchy.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/memberHierarchy"; -struct In_CqueryMemberHierarchy : public RequestMessage { +struct In_CqueryMemberHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { diff --git a/src/messages/cquery_random.cc b/src/messages/cquery_random.cc index bf7c46686..7bbf0761d 100644 --- a/src/messages/cquery_random.cc +++ b/src/messages/cquery_random.cc @@ -9,7 +9,7 @@ namespace { MethodType kMethodType = "$cquery/random"; -struct In_CqueryRandom : public RequestMessage { +struct In_CqueryRandom : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } }; MAKE_REFLECT_STRUCT(In_CqueryRandom, id); diff --git a/src/messages/cquery_vars.cc b/src/messages/cquery_vars.cc index 812ec6f0c..8ac9816f6 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/cquery_vars.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "$cquery/vars"; -struct In_CqueryVars : public RequestMessage { +struct In_CqueryVars : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; diff --git a/src/messages/cquery_wait.cc b/src/messages/cquery_wait.cc index c91097291..3a05df756 100644 --- a/src/messages/cquery_wait.cc +++ b/src/messages/cquery_wait.cc @@ -8,7 +8,7 @@ namespace { MethodType kMethodType = "$cquery/wait"; -struct In_CqueryWait : public NotificationMessage { +struct In_CqueryWait : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } }; MAKE_REFLECT_EMPTY_STRUCT(In_CqueryWait); @@ -17,7 +17,7 @@ REGISTER_IN_MESSAGE(In_CqueryWait); struct Handler_CqueryWait : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(std::unique_ptr request) override { + void Run(std::unique_ptr request) override { // TODO: use status message system here, then run querydb as normal? Maybe // this cannot be a normal message, ie, it needs to be re-entrant. diff --git a/src/messages/exit.cc b/src/messages/exit.cc index d90d80ed3..2722dca51 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -3,7 +3,7 @@ #include namespace { -struct In_Exit : public NotificationMessage { +struct In_Exit : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType_Exit; } }; MAKE_REFLECT_EMPTY_STRUCT(In_Exit); @@ -12,7 +12,7 @@ REGISTER_IN_MESSAGE(In_Exit); struct Handler_Exit : MessageHandler { MethodType GetMethodType() const override { return kMethodType_Exit; } - void Run(std::unique_ptr request) override { + void Run(std::unique_ptr request) override { LOG_S(INFO) << "Exiting; got exit message"; exit(0); } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index ffbc6115c..2edd6ff07 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -462,7 +462,7 @@ struct lsInitializeError { }; MAKE_REFLECT_STRUCT(lsInitializeError, retry); -struct In_InitializeRequest : public RequestMessage { +struct In_InitializeRequest : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsInitializeParams params; diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index f93f43208..5967e2399 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -4,7 +4,7 @@ namespace { MethodType kMethodType = "shutdown"; -struct In_Shutdown : public RequestMessage { +struct In_Shutdown : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } }; MAKE_REFLECT_STRUCT(In_Shutdown, id); diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index 487fbca3a..e3913a2fb 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -257,7 +257,7 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, return nullopt; } -struct In_TextDocumentCodeAction : public RequestMessage { +struct In_TextDocumentCodeAction : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } // Contains additional diagnostic information about the context in which diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index f735f1bb6..903abf110 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -13,7 +13,7 @@ struct lsDocumentCodeLensParams { MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument); using TCodeLens = lsCodeLens; -struct In_TextDocumentCodeLens : public RequestMessage { +struct In_TextDocumentCodeLens : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDocumentCodeLensParams params; }; diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 43dc6c8cd..d6db3107e 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -48,7 +48,7 @@ struct lsCompletionParams : lsTextDocumentPositionParams { }; MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); -struct In_TextDocumentComplete : public RequestMessage { +struct In_TextDocumentComplete : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsCompletionParams params; }; @@ -219,7 +219,7 @@ void FilterAndSortCompletionResponse( struct Handler_TextDocumentCompletion : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(std::unique_ptr message) override { + void Run(std::unique_ptr message) override { auto request = std::shared_ptr( static_cast(message.release())); diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 95410f0e5..d7fc869ad 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -10,7 +10,7 @@ namespace { MethodType kMethodType = "textDocument/definition"; -struct In_TextDocumentDefinition : public RequestMessage { +struct In_TextDocumentDefinition : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index fb16e3c32..cf887adbc 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -10,7 +10,7 @@ namespace { MethodType kMethodType = "textDocument/didChange"; -struct In_TextDocumentDidChange : public NotificationMessage { +struct In_TextDocumentDidChange : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentDidChangeParams params; }; diff --git a/src/messages/text_document_did_close.cc b/src/messages/text_document_did_close.cc index e76ee52f6..6cf1d3fb0 100644 --- a/src/messages/text_document_did_close.cc +++ b/src/messages/text_document_did_close.cc @@ -6,7 +6,7 @@ namespace { MethodType kMethodType = "textDocument/didClose"; -struct In_TextDocumentDidClose : public NotificationMessage { +struct In_TextDocumentDidClose : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 2b2562d88..770c9bcb8 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -13,7 +13,7 @@ namespace { MethodType kMethodType = "textDocument/didOpen"; // Open, view, change, close file -struct In_TextDocumentDidOpen : public NotificationMessage { +struct In_TextDocumentDidOpen : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 7eec5dd0d..f187f018d 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -9,7 +9,7 @@ namespace { MethodType kMethodType = "textDocument/didSave"; -struct In_TextDocumentDidSave : public NotificationMessage { +struct In_TextDocumentDidSave : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index b01bc7a6a..42e74cdb0 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -6,7 +6,7 @@ namespace { MethodType kMethodType = "textDocument/documentHighlight"; -struct In_TextDocumentDocumentHighlight : public RequestMessage { +struct In_TextDocumentDocumentHighlight : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/text_document_document_link.cc b/src/messages/text_document_document_link.cc index fc6994faf..9a05365aa 100644 --- a/src/messages/text_document_document_link.cc +++ b/src/messages/text_document_document_link.cc @@ -8,7 +8,7 @@ namespace { MethodType kMethodType = "textDocument/documentLink"; -struct In_TextDocumentDocumentLink : public RequestMessage { +struct In_TextDocumentDocumentLink : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // The document to provide document links for. diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 4a48a2d3f..2ec075330 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -10,7 +10,7 @@ struct lsDocumentSymbolParams { }; MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); -struct In_TextDocumentDocumentSymbol : public RequestMessage { +struct In_TextDocumentDocumentSymbol : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDocumentSymbolParams params; }; diff --git a/src/messages/text_document_formatting.cc b/src/messages/text_document_formatting.cc index 55c8f4876..793c86d63 100644 --- a/src/messages/text_document_formatting.cc +++ b/src/messages/text_document_formatting.cc @@ -8,7 +8,7 @@ namespace { MethodType kMethodType = "textDocument/formatting"; -struct In_TextDocumentFormatting : public RequestMessage { +struct In_TextDocumentFormatting : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 2dbf26a13..6a852d8f4 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -42,7 +42,7 @@ std::pair GetCommentsAndHover( return {"", ""}; } -struct In_TextDocumentHover : public RequestMessage { +struct In_TextDocumentHover : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc index 29605e50e..175dbb2ae 100644 --- a/src/messages/text_document_range_formatting.cc +++ b/src/messages/text_document_range_formatting.cc @@ -19,7 +19,7 @@ MAKE_REFLECT_STRUCT(lsTextDocumentRangeFormattingParams, range, options); -struct In_TextDocumentRangeFormatting : public RequestMessage { +struct In_TextDocumentRangeFormatting : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentRangeFormattingParams params; }; diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index bd6896d78..19684cdb0 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -7,7 +7,7 @@ namespace { MethodType kMethodType = "textDocument/references"; -struct In_TextDocumentReferences : public RequestMessage { +struct In_TextDocumentReferences : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct lsReferenceContext { // Include the declaration of the current symbol. diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index b44048ad4..b8dcc9d9f 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -48,7 +48,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, return edit; } -struct In_TextDocumentRename : public RequestMessage { +struct In_TextDocumentRename : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // The document to format. diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index c4e740297..8f23e5be3 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -9,7 +9,7 @@ namespace { MethodType kMethodType = "textDocument/signatureHelp"; -struct In_TextDocumentSignatureHelp : public RequestMessage { +struct In_TextDocumentSignatureHelp : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; @@ -86,7 +86,7 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result); struct Handler_TextDocumentSignatureHelp : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(std::unique_ptr message) override { + void Run(std::unique_ptr message) override { auto request = static_cast(message.get()); lsTextDocumentPositionParams& params = request->params; WorkingFile* file = @@ -103,7 +103,7 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { return; ClangCompleteManager::OnComplete callback = std::bind( - [this](BaseIpcMessage* message, std::string search, int active_param, + [this](InMessage* message, std::string search, int active_param, const std::vector& results, bool is_cached_result) { auto msg = static_cast(message); diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 9797af8af..4226c558a 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -5,7 +5,7 @@ namespace { MethodType kMethodType = "textDocument/typeDefinition"; -struct In_TextDocumentTypeDefinition : public RequestMessage { +struct In_TextDocumentTypeDefinition : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 8714217a3..c2ad85cbf 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -16,7 +16,7 @@ struct lsDidChangeConfigurationParams { }; MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); -struct In_WorkspaceDidChangeConfiguration : public NotificationMessage { +struct In_WorkspaceDidChangeConfiguration : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDidChangeConfigurationParams params; }; diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 88471b940..d44081e7d 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -28,7 +28,7 @@ struct lsDidChangeWatchedFilesParams { }; MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes); -struct In_WorkspaceDidChangeWatchedFiles : public NotificationMessage { +struct In_WorkspaceDidChangeWatchedFiles : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDidChangeWatchedFilesParams params; }; diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index f1600d895..e8f66f25d 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -6,7 +6,7 @@ namespace { MethodType kMethodType = "workspace/executeCommand"; -struct In_WorkspaceExecuteCommand : public RequestMessage { +struct In_WorkspaceExecuteCommand : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsCommand params; }; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 68d0abca9..b069ec847 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -43,7 +43,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db, return true; } -struct In_WorkspaceSymbol : public RequestMessage { +struct In_WorkspaceSymbol : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string query; diff --git a/src/ipc.cc b/src/method.cc similarity index 68% rename from src/ipc.cc rename to src/method.cc index 811393198..43e136fb9 100644 --- a/src/ipc.cc +++ b/src/method.cc @@ -1,4 +1,4 @@ -#include "ipc.h" +#include "method.h" const char* kMethodType_Unknown = "$unknown"; const char* kMethodType_Exit = "exit"; @@ -6,8 +6,12 @@ const char* kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDi const char* kMethodType_CqueryPublishInactiveRegions = "$cquery/publishInactiveRegions"; const char* kMethodType_CqueryPublishSemanticHighlighting = "$cquery/publishSemanticHighlighting"; -BaseIpcMessage::~BaseIpcMessage() = default; +InMessage::~InMessage() = default; -lsRequestId BaseIpcMessage::GetRequestId() { - return std::monostate(); +lsRequestId RequestInMessage::GetRequestId() const { + return id; } + +lsRequestId NotificationInMessage::GetRequestId() const { + return std::monostate(); +} \ No newline at end of file diff --git a/src/ipc.h b/src/method.h similarity index 63% rename from src/ipc.h rename to src/method.h index 0718d7fec..2a329866d 100644 --- a/src/ipc.h +++ b/src/method.h @@ -5,28 +5,29 @@ #include -using lsRequestId = std::variant; - using MethodType = std::string; - extern const char* kMethodType_Unknown; extern const char* kMethodType_Exit; extern const char* kMethodType_TextDocumentPublishDiagnostics; extern const char* kMethodType_CqueryPublishInactiveRegions; extern const char* kMethodType_CqueryPublishSemanticHighlighting; -struct BaseIpcMessage { - virtual ~BaseIpcMessage(); +using lsRequestId = std::variant; + +struct InMessage { + virtual ~InMessage(); virtual MethodType GetMethodType() const = 0; - virtual lsRequestId GetRequestId(); + virtual lsRequestId GetRequestId() const = 0; }; -struct RequestMessage : public BaseIpcMessage { +struct RequestInMessage : public InMessage { // number or string, actually no null lsRequestId id; - lsRequestId GetRequestId() override { return id; } + lsRequestId GetRequestId() const override; }; -// NotificationMessage does not have |id|. -struct NotificationMessage : public BaseIpcMessage {}; +// NotificationInMessage does not have |id|. +struct NotificationInMessage : public InMessage { + lsRequestId GetRequestId() const override; +}; diff --git a/src/project.h b/src/project.h index c3acdf223..2e2a9253c 100644 --- a/src/project.h +++ b/src/project.h @@ -1,6 +1,7 @@ #pragma once #include "config.h" +#include "method.h" #include #include @@ -11,8 +12,6 @@ #include #include -// FIXME ipc.h -using lsRequestId = std::variant; class QueueManager; struct WorkingFiles; diff --git a/src/queue_manager.h b/src/queue_manager.h index 34cc3b007..86478a360 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -1,6 +1,6 @@ #pragma once -#include "ipc.h" +#include "method.h" #include "performance.h" #include "query.h" #include "threaded_queue.h" @@ -94,7 +94,7 @@ class QueueManager { ThreadedQueue for_stdout; // Runs on querydb thread. - ThreadedQueue> for_querydb; + ThreadedQueue> for_querydb; ThreadedQueue do_id_map; // Runs on indexer threads. From e235dbedfe0e7e16f2b0f6d6a04814d74d23722a Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Fri, 23 Mar 2018 12:48:58 +0800 Subject: [PATCH 035/378] Fix missing include completions. --- src/messages/text_document_completion.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index d6db3107e..8378539ff 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -303,15 +303,12 @@ struct Handler_TextDocumentCompletion : MessageHandler { include_complete->completion_items_mutex, std::defer_lock); if (include_complete->is_scanning) lock.lock(); - std::string quote = result.match[5]; - for (auto& item : include_complete->completion_items) - if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) - out.result.items.push_back(item); + out.result.items = include_complete->completion_items; } // Needed by |FilterAndSortCompletionResponse|. for (lsCompletionItem& item : out.result.items) - item.filterText = item.label; + item.filterText = "include" + item.label; FilterAndSortCompletionResponse(&out, result.pattern, config->completion.filterAndSort); From d87afce1fc99f800c9e688a1d6e19d6cebf034d6 Mon Sep 17 00:00:00 2001 From: Patrick Reisert Date: Thu, 22 Mar 2018 10:00:59 +0100 Subject: [PATCH 036/378] Ignore cl's -showIncludes --- src/project.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/project.cc b/src/project.cc index 11617fe13..a194b31fe 100644 --- a/src/project.cc +++ b/src/project.cc @@ -80,7 +80,7 @@ std::vector kBlacklistMulti = { // Blacklisted flags which are always removed from the command line. std::vector kBlacklist = { - "-c", "-MP", "-MD", "-MMD", "--fcolor-diagnostics", + "-c", "-MP", "-MD", "-MMD", "--fcolor-diagnostics", "-showIncludes" }; // Arguments which are followed by a potentially relative path. We need to make From ddc318eef3cbbd6daf0a09dcf795b207c19e5c83 Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Sat, 24 Mar 2018 12:21:23 +0800 Subject: [PATCH 037/378] Preprocessor keyword completion. --- src/messages/text_document_completion.cc | 63 ++++++++++++++++++------ 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 8378539ff..7229d65b7 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -98,6 +98,8 @@ void DecorateIncludePaths(const std::smatch& match, struct ParseIncludeLineResult { bool ok; + std::string keyword; + std::string quote; std::string pattern; std::smatch match; }; @@ -115,8 +117,28 @@ ParseIncludeLineResult ParseIncludeLine(const std::string& line) { "(.*)"); // [7]: suffix after quote char std::smatch match; bool ok = std::regex_match(line, match, pattern); - std::string text = match[3].str() + match[6].str(); - return {ok, text, match}; + return {ok, match[3], match[5], match[6], match}; +} + +static const std::vector preprocessorKeywords = { + "define", "undef", "include", "if", "ifdef", "ifndef", + "else", "elif", "endif", "line", "error", "pragma"}; + +std::vector preprocessorKeywordCompletionItems( + const std::smatch& match) { + std::vector items; + for (auto& keyword : preprocessorKeywords) { + lsCompletionItem item; + item.label = keyword; + item.priority_ = (keyword == "include" ? 2 : 1); + item.textEdit = lsTextEdit(); + std::string space = (keyword == "else" || keyword == "endif") ? "" : " "; + item.textEdit->newText = match[1].str() + "#" + match[2].str() + keyword + + space + match[6].str(); + item.insertTextFormat = lsInsertTextFormat::PlainText; + items.push_back(item); + } + return items; } template @@ -298,22 +320,31 @@ struct Handler_TextDocumentCompletion : MessageHandler { Out_TextDocumentComplete out; out.id = request->id; - { - std::unique_lock lock( - include_complete->completion_items_mutex, std::defer_lock); - if (include_complete->is_scanning) - lock.lock(); - out.result.items = include_complete->completion_items; + if (result.quote.empty() && result.pattern.empty()) { + // no quote or path of file, do preprocessor keyword completion + if (!std::any_of(preprocessorKeywords.begin(), + preprocessorKeywords.end(), + [&result](std::string_view k) { + return k == result.keyword; + })) { + out.result.items = preprocessorKeywordCompletionItems(result.match); + FilterAndSortCompletionResponse(&out, result.keyword, + config->completion.filterAndSort); + } + } else if (result.keyword.compare("include") == 0) { + { + // do include completion + std::unique_lock lock( + include_complete->completion_items_mutex, std::defer_lock); + if (include_complete->is_scanning) + lock.lock(); + out.result.items = include_complete->completion_items; + } + FilterAndSortCompletionResponse(&out, result.pattern, + config->completion.filterAndSort); + DecorateIncludePaths(result.match, &out.result.items); } - // Needed by |FilterAndSortCompletionResponse|. - for (lsCompletionItem& item : out.result.items) - item.filterText = "include" + item.label; - - FilterAndSortCompletionResponse(&out, result.pattern, - config->completion.filterAndSort); - DecorateIncludePaths(result.match, &out.result.items); - for (lsCompletionItem& item : out.result.items) { item.textEdit->range.start.line = request->params.position.line; item.textEdit->range.start.character = 0; From a566167db6e0caf8148fb16e3a255eee58af53ad Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Sat, 24 Mar 2018 17:34:01 +0100 Subject: [PATCH 038/378] Change default cmake build type to Release --- cmake/DefaultCMakeBuildType.cmake | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmake/DefaultCMakeBuildType.cmake b/cmake/DefaultCMakeBuildType.cmake index 89ea3ede5..ae440bf54 100644 --- a/cmake/DefaultCMakeBuildType.cmake +++ b/cmake/DefaultCMakeBuildType.cmake @@ -1,8 +1,4 @@ -# Set a default build type if none was specified set(DEFAULT_CMAKE_BUILD_TYPE Release) -if(EXISTS ${CMAKE_SOURCE_DIR}/.git) - set(DEFAULT_CMAKE_BUILD_TYPE Debug) -endif() # CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used # (eg Visual Studio generators) From 4270b4fdef7d696a1c59192faac2c3602703ae5f Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Thu, 22 Mar 2018 20:52:06 -0700 Subject: [PATCH 039/378] Minor type cleanup --- src/command_line.cc | 1 - src/method.cc | 10 +++++----- src/method.h | 10 +++++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/command_line.cc b/src/command_line.cc index 14bd2c357..1a6b217b3 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -306,7 +306,6 @@ void LaunchStdinLoop(Config* config, MethodType method_type = message->GetMethodType(); (*request_times)[method_type] = Timer(); - LOG_S(ERROR) << "!! Got message of type " << method_type; queue->for_querydb.PushBack(std::move(message)); // If the message was to exit then querydb will take care of the actual diff --git a/src/method.cc b/src/method.cc index 43e136fb9..cd24524da 100644 --- a/src/method.cc +++ b/src/method.cc @@ -1,10 +1,10 @@ #include "method.h" -const char* kMethodType_Unknown = "$unknown"; -const char* kMethodType_Exit = "exit"; -const char* kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; -const char* kMethodType_CqueryPublishInactiveRegions = "$cquery/publishInactiveRegions"; -const char* kMethodType_CqueryPublishSemanticHighlighting = "$cquery/publishSemanticHighlighting"; +MethodType kMethodType_Unknown = "$unknown"; +MethodType kMethodType_Exit = "exit"; +MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; +MethodType kMethodType_CqueryPublishInactiveRegions = "$cquery/publishInactiveRegions"; +MethodType kMethodType_CqueryPublishSemanticHighlighting = "$cquery/publishSemanticHighlighting"; InMessage::~InMessage() = default; diff --git a/src/method.h b/src/method.h index 2a329866d..8a3673d3a 100644 --- a/src/method.h +++ b/src/method.h @@ -6,11 +6,11 @@ #include using MethodType = std::string; -extern const char* kMethodType_Unknown; -extern const char* kMethodType_Exit; -extern const char* kMethodType_TextDocumentPublishDiagnostics; -extern const char* kMethodType_CqueryPublishInactiveRegions; -extern const char* kMethodType_CqueryPublishSemanticHighlighting; +extern MethodType kMethodType_Unknown; +extern MethodType kMethodType_Exit; +extern MethodType kMethodType_TextDocumentPublishDiagnostics; +extern MethodType kMethodType_CqueryPublishInactiveRegions; +extern MethodType kMethodType_CqueryPublishSemanticHighlighting; using lsRequestId = std::variant; From 33bd27b9134e586addc6592fa47a706846f8b77e Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Sat, 24 Mar 2018 10:26:10 -0700 Subject: [PATCH 040/378] Work on e2e tests --- src/message_handler.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/message_handler.cc b/src/message_handler.cc index 2236d6aa5..e06e9f4da 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -84,8 +84,8 @@ bool FindFileOrFail(QueryDatabase* db, /* LOG_S(INFO) << "Files (size=" << db->usr_to_file.size() << "): " << StringJoinMap(db->usr_to_file, - [](const std::pair& entry) { - return entry.first; + [](const std::pair& entry) { + return entry.first.path; }); */ From 9c729e19377beef0d44cea23a38de77332c9b872 Mon Sep 17 00:00:00 2001 From: Maxim Kot Date: Sun, 25 Mar 2018 18:21:42 +0000 Subject: [PATCH 041/378] UB fixed. Forgotten return was removed. --- src/command_line.cc | 1 - src/method.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/command_line.cc b/src/command_line.cc index 1a6b217b3..91f96e0d8 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -63,7 +63,6 @@ bool ShouldDisplayMethodTiming(MethodType type) { type != kMethodType_TextDocumentPublishDiagnostics && type != kMethodType_CqueryPublishInactiveRegions && type != kMethodType_Unknown; - return true; } void PrintHelp() { diff --git a/src/method.h b/src/method.h index 8a3673d3a..77d926165 100644 --- a/src/method.h +++ b/src/method.h @@ -5,7 +5,7 @@ #include -using MethodType = std::string; +using MethodType = const char*; extern MethodType kMethodType_Unknown; extern MethodType kMethodType_Exit; extern MethodType kMethodType_TextDocumentPublishDiagnostics; From 401d542ba7ec4b7596cd5455adba367f0690a566 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 26 Mar 2018 16:24:05 +0200 Subject: [PATCH 042/378] Switch to -print-resource-dir (drop support for system clang 4.0) --- cmake/FindClang.cmake | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 57524aca2..c8e0d2473 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -99,23 +99,9 @@ endif() _Clang_find_program(Clang_EXECUTABLE clang) if(Clang_EXECUTABLE) # Find Clang resource directory with Clang executable - # TODO: simplify by using -print-resource-dir once Clang 4 support is dropped - if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) - set(_DEV_NULL NUL) - else() - set(_DEV_NULL /dev/null) - endif() - - # clang "-###" -xc /dev/null - execute_process(COMMAND ${Clang_EXECUTABLE} "-###" -xc ${_DEV_NULL} - ERROR_VARIABLE Clang_RESOURCE_DIR OUTPUT_QUIET) - # Strip everything except '"-resource-dir" ""' - string(REGEX MATCH "\"-resource-dir\" \"([^\"]*)\"" - Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) - # Strip quotes - string(REPLACE "\"" "" Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) - # Strip '-resource-dir ' - string(REPLACE "-resource-dir " "" Clang_RESOURCE_DIR ${Clang_RESOURCE_DIR}) + execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir + OUTPUT_VARIABLE Clang_RESOURCE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) # Find Clang version set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") From 59769df8b5ce4d864d3d4df14d62ec5e1d3411ad Mon Sep 17 00:00:00 2001 From: Pavel Davydov Date: Mon, 26 Mar 2018 16:21:23 +0300 Subject: [PATCH 043/378] Blacklist '-include' and '-include-pch' flags. (#545) --- src/project.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/project.cc b/src/project.cc index a194b31fe..f3c2547e2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -76,7 +76,7 @@ struct ProjectConfig { // TODO: See // https://github.com/Valloric/ycmd/blob/master/ycmd/completers/cpp/flags.py. std::vector kBlacklistMulti = { - "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang"}; + "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang", "-include", "-include-pch"}; // Blacklisted flags which are always removed from the command line. std::vector kBlacklist = { From 410fb69e25f95916a1a1820642f50e7159eb4ee5 Mon Sep 17 00:00:00 2001 From: Pavel Davydov Date: Mon, 26 Mar 2018 16:32:04 +0300 Subject: [PATCH 044/378] Add comment with short issue description. (#545) --- src/project.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/project.cc b/src/project.cc index f3c2547e2..bf3f4968e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -75,6 +75,10 @@ struct ProjectConfig { // TODO: See // https://github.com/Valloric/ycmd/blob/master/ycmd/completers/cpp/flags.py. +// Flags '-include' and '-include-pch' are blacklisted here cause libclang returns error in case when +// precompiled header was generated by a different compiler (even two different builds of same version +// of clang for the same platform are incompatible). Note that libclang always generate it's own pch +// internally. For details, see https://github.com/Valloric/ycmd/issues/892 . std::vector kBlacklistMulti = { "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang", "-include", "-include-pch"}; From 5f8418cd9bf9fa4ab00c5405adbf167231be0e60 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Mon, 26 Mar 2018 17:17:37 +0200 Subject: [PATCH 045/378] enable gcc extensions (needed for cygwin support) --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index beca46ea5..c1e3fc7f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,6 @@ add_executable(cquery "") # Enable C++14 (Required) set_property(TARGET cquery PROPERTY CXX_STANDARD 14) set_property(TARGET cquery PROPERTY CXX_STANDARD_REQUIRED ON) -# Disable gcc extensions -set_property(TARGET cquery PROPERTY CXX_EXTENSIONS OFF) if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Common MSVC/Clang(Windows) options From 975c5646a4dd82a7daf5a767cfd983601d5cb194 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Mon, 26 Mar 2018 17:30:33 +0200 Subject: [PATCH 046/378] Enable gcc extensions on cygwin only --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1e3fc7f3..a9ed816be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,10 @@ add_executable(cquery "") # Enable C++14 (Required) set_property(TARGET cquery PROPERTY CXX_STANDARD 14) set_property(TARGET cquery PROPERTY CXX_STANDARD_REQUIRED ON) +# Disable gnu extensions except for Cygwin which needs them to build properly +if(NOT CYGWIN) + set_property(TARGET cquery PROPERTY CXX_EXTENSIONS OFF) +endif() if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Common MSVC/Clang(Windows) options From 5ef55f993ffb8a627ed3451584607b6e7df5373a Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Tue, 27 Mar 2018 11:33:16 +0800 Subject: [PATCH 047/378] Fix lost index update. --- src/import_pipeline.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 90e1ac090..4c0102ba6 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -548,13 +548,10 @@ bool IndexMergeIndexUpdates() { IterationLoop loop; while (loop.Next()) { optional to_join = queue->on_indexed.TryPopBack(); - if (!to_join) { - queue->on_indexed.PushFront(std::move(*root)); - return did_merge; - } - + if (!to_join) + break; did_merge = true; - Timer time; + // Timer time; root->update.Merge(std::move(to_join->update)); // time.ResetAndPrint("Joined querydb updates for files: " + // StringJoinMap(root->update.files_def_update, @@ -563,6 +560,7 @@ bool IndexMergeIndexUpdates() { //})); } + queue->on_indexed.PushFront(std::move(*root)); return did_merge; } From 7e80959ce1764b071edb33886637ccf51ac1e6ca Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 23 Mar 2018 14:57:52 -0700 Subject: [PATCH 048/378] Improve fuzzy matching heuristics. --- src/fuzzy_match.cc | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 859307422..6e271665d 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -46,7 +46,7 @@ void CalculateRoles(std::string_view s, int roles[], int* class_set) { } // namespace int FuzzyMatcher::MissScore(int j, bool last) { - int s = last ? -20 : 0; + int s = last ? -10 : 0; if (text_role[j] == Head) s -= 10; return s; @@ -57,14 +57,16 @@ int FuzzyMatcher::MatchScore(int i, int j, bool last) { if (pat[i] == text[j]) { s++; if ((pat_set & 1 << Upper) || i == j) - s += 10; + s++; + } + if (pat_role[i] == Head) { + if (text_role[j] == Head) + s += 30; + else if (text_role[j] == Tail) + s -= 10; } - if (pat_role[i] == Head && text_role[j] == Head) - s += 30; if (text_role[j] == Tail && i && !last) s -= 30; - if (pat_role[i] == Head && text_role[j] == Tail) - s -= 10; if (i == 0 && text_role[j] == Tail) s -= 40; return s; @@ -133,7 +135,7 @@ TEST_SUITE("fuzzy_match") { ret = false; break; } - if (1 || !ret) { + if (!ret) { for (size_t i = 0; i < texts.size(); i++) printf("%s %d ", texts[i], scores[i]); puts(""); @@ -147,22 +149,24 @@ TEST_SUITE("fuzzy_match") { CHECK(fuzzy.Match("aaa") < 0); // case - Ranks("monad", {"monad", "Monad", "mONAD"}); + CHECK(Ranks("monad", {"monad", "Monad", "mONAD"})); // initials - Ranks("ab", {"ab", "aoo_boo", "acb"}); - Ranks("CC", {"CamelCase", "camelCase", "camelcase"}); - Ranks("cC", {"camelCase", "CamelCase", "camelcase"}); - Ranks("c c", - {"camel case", "camelCase", "CamelCase", "camelcase", "camel ace"}); - Ranks("Da.Te", {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"}); + CHECK(Ranks("ab", {"ab", "aoo_boo", "acb"})); + CHECK(Ranks("CC", {"CamelCase", "camelCase", "camelcase"})); + CHECK(Ranks("cC", {"camelCase", "CamelCase", "camelcase"})); + CHECK(Ranks("c c", {"camel case", "camelCase", "CamelCase", "camelcase", + "camel ace"})); + CHECK(Ranks("Da.Te", + {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"})); + CHECK(Ranks("foo bar.h", {"foo/bar.h", "foobar.h"})); // prefix - Ranks("is", {"isIEEE", "inSuf"}); + CHECK(Ranks("is", {"isIEEE", "inSuf"})); // shorter - Ranks("ma", {"map", "many", "maximum"}); - Ranks("print", {"printf", "sprintf"}); + CHECK(Ranks("ma", {"map", "many", "maximum"})); + CHECK(Ranks("print", {"printf", "sprintf"})); // score(PRINT) = kMinScore - Ranks("ast", {"ast", "AST", "INT_FAST16_MAX"}); + CHECK(Ranks("ast", {"ast", "AST", "INT_FAST16_MAX"})); // score(PRINT) > kMinScore - Ranks("Int", {"int", "INT", "PRINT"}); + CHECK(Ranks("Int", {"int", "INT", "PRINT"})); } } From 2f0b9ccfdcfc5b78232aff85fd2d42c3cde9abfa Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Wed, 28 Mar 2018 15:02:44 +0800 Subject: [PATCH 049/378] Extract LLVM to specific directory. --- cmake/DownloadAndExtractLLVM.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake index 83f82b96a..4a122e355 100644 --- a/cmake/DownloadAndExtractLLVM.cmake +++ b/cmake/DownloadAndExtractLLVM.cmake @@ -99,6 +99,8 @@ if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) message(STATUS "Extracting downloaded LLVM with CMake built-in tar ...") # CMake has builtin support for tar via the -E flag execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} + # Extract to here to allow running cmake from everywhere + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_QUIET) endif() endif() From 512cd8cbd35f15f927dba8eed0ec2d088ca84f1d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 29 Mar 2018 16:57:10 -0700 Subject: [PATCH 050/378] Better textDocument/definition heuristic for T::name style dependent names --- src/messages/text_document_definition.cc | 42 +++++++++++++++--------- src/utils.cc | 4 +-- src/utils.h | 5 +-- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index d7fc869ad..e6e4caf73 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -128,10 +128,15 @@ struct Handler_TextDocumentDefinition lsPosition position = request->params.position; const std::string& buffer = working_file->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); - bool has_scope = query.find(':') != std::string::npos; + std::string_view short_query = query; + { + auto pos = query.rfind(':'); + if (pos != std::string::npos) + short_query = query.substr(pos + 1); + } // For symbols whose short/detailed names contain |query| as a - // substring, we use the tuple to find the best match. std::tuple best_score{INT_MAX, 0, true, 0}; int best_i = -1; @@ -139,21 +144,28 @@ struct Handler_TextDocumentDefinition if (db->symbols[i].kind == SymbolKind::Invalid) continue; - std::string_view name = has_scope ? db->GetSymbolDetailedName(i) - : db->GetSymbolShortName(i); - auto pos = name.find(query); + std::string_view name = short_query.size() < query.size() + ? db->GetSymbolDetailedName(i) + : db->GetSymbolShortName(i); + auto pos = name.rfind(short_query); if (pos == std::string::npos) continue; - Maybe use = GetDefinitionSpell(db, db->symbols[i]); - if (!use) - continue; - - std::tuple score{ - int(name.size() - query.size()), int(pos), use->file != file_id, - std::abs(use->range.start.line - position.line)}; - if (score < best_score) { - best_score = score; - best_i = i; + if (Maybe use = GetDefinitionSpell(db, db->symbols[i])) { + std::tuple score{ + int(name.size() - short_query.size()), -pos, + use->file != file_id, + std::abs(use->range.start.line - position.line)}; + // Update the score with qualified name if the qualified name + // occurs in |name|. + pos = name.rfind(query); + if (pos != std::string::npos) { + std::get<0>(score) = int(name.size() - query.size()); + std::get<1>(score) = -pos; + } + if (score < best_score) { + best_score = score; + best_i = i; + } } } if (best_i != -1) { diff --git a/src/utils.cc b/src/utils.cc index 5d3cda96c..38080abf4 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -77,13 +77,13 @@ uint64_t HashUsr(const char* s, size_t n) { } // See http://stackoverflow.com/a/2072890 -bool EndsWith(const std::string& value, const std::string& ending) { +bool EndsWith(std::string_view value, std::string_view ending) { if (ending.size() > value.size()) return false; return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } -bool StartsWith(const std::string& value, const std::string& start) { +bool StartsWith(std::string_view value, std::string_view start) { if (start.size() > value.size()) return false; return std::equal(start.begin(), start.end(), value.begin()); diff --git a/src/utils.h b/src/utils.h index a602c760f..da54e338c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -22,8 +23,8 @@ uint64_t HashUsr(const char* s); uint64_t HashUsr(const char* s, size_t n); // Returns true if |value| starts/ends with |start| or |ending|. -bool StartsWith(const std::string& value, const std::string& start); -bool EndsWith(const std::string& value, const std::string& ending); +bool StartsWith(std::string_view value, std::string_view start); +bool EndsWith(std::string_view value, std::string_view ending); bool AnyStartsWith(const std::vector& values, const std::string& start); bool StartsWithAny(const std::string& value, From da649891ae3bd108a75556088737db5534afb7ea Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Mar 2018 20:16:33 -0700 Subject: [PATCH 051/378] Resurrection of ccls --- .gitignore | 28 +- CMakeLists.txt | 86 +-- README.md | 28 +- index_tests/_empty_test.cc | 10 + index_tests/class_forward_declaration.cc | 31 + index_tests/constructors/constructor.cc | 92 +++ index_tests/constructors/destructor.cc | 100 +++ .../constructors/implicit_constructor.cc | 90 +++ index_tests/constructors/invalid_reference.cc | 51 ++ index_tests/constructors/make_functions.cc | 353 +++++++++++ index_tests/constructors/make_functions.h | 10 + .../declaration_vs_definition/class.cc | 33 + .../declaration_vs_definition/class_member.cc | 56 ++ .../class_member_static.cc | 58 ++ index_tests/declaration_vs_definition/func.cc | 40 ++ .../func_associated_function_params.cc | 78 +++ .../declaration_vs_definition/method.cc | 87 +++ index_tests/enums/enum_class_decl.cc | 90 +++ index_tests/enums/enum_decl.cc | 57 ++ index_tests/enums/enum_inherit.cc | 138 ++++ index_tests/enums/enum_usage.cc | 72 +++ index_tests/foobar.cc | 108 ++++ index_tests/function_declaration.cc | 28 + .../function_declaration_definition.cc | 32 + index_tests/function_definition.cc | 27 + index_tests/inheritance/class_inherit.cc | 45 ++ .../class_inherit_templated_parent.cc | 146 +++++ .../inheritance/class_multiple_inherit.cc | 79 +++ index_tests/inheritance/function_override.cc | 82 +++ .../inheritance/interface_pure_virtual.cc | 47 ++ .../inheritance/multiple_base_functions.cc | 116 ++++ index_tests/lambdas/lambda.cc | 115 ++++ index_tests/macros/complex.cc | 95 +++ index_tests/macros/foo.cc | 102 +++ index_tests/method_declaration.cc | 51 ++ index_tests/method_definition.cc | 51 ++ index_tests/method_inline_declaration.cc | 46 ++ index_tests/multi_file/funky_enum.cc | 97 +++ index_tests/multi_file/funky_enum.h | 6 + index_tests/multi_file/header.h | 18 + index_tests/multi_file/impl.cc | 229 +++++++ index_tests/multi_file/simple_header.h | 3 + index_tests/multi_file/simple_impl.cc | 71 +++ index_tests/multi_file/static.cc | 88 +++ index_tests/multi_file/static.h | 5 + index_tests/namespaces/anonymous_function.cc | 45 ++ .../namespaces/function_declaration.cc | 61 ++ index_tests/namespaces/function_definition.cc | 60 ++ index_tests/namespaces/method_declaration.cc | 79 +++ index_tests/namespaces/method_definition.cc | 83 +++ .../namespaces/method_inline_declaration.cc | 78 +++ index_tests/namespaces/namespace_alias.cc | 171 +++++ index_tests/namespaces/namespace_reference.cc | 123 ++++ index_tests/objective-c/class.m | 184 ++++++ index_tests/operators/operator.cc | 100 +++ index_tests/outline/outline.cc | 120 ++++ index_tests/outline/outline2.cc | 158 +++++ .../outline/static_function_in_type.cc | 192 ++++++ index_tests/outline/static_function_in_type.h | 9 + index_tests/preprocessor/include_guard.cc | 27 + index_tests/preprocessor/skipped.cc | 25 + .../func_specialized_template_param.cc | 70 ++ .../implicit_variable_instantiation.cc | 155 +++++ .../templates/member_ref_in_template.cc | 107 ++++ ...ass_template_func_usage_folded_into_one.cc | 125 ++++ ...ace_template_type_usage_folded_into_one.cc | 88 +++ index_tests/templates/specialization.cc | 436 +++++++++++++ .../templates/specialized_func_definition.cc | 81 +++ ...mplate_class_func_usage_folded_into_one.cc | 92 +++ ...ass_template_func_usage_folded_into_one.cc | 93 +++ ...mplate_class_type_usage_folded_into_one.cc | 127 ++++ ...emplate_class_var_usage_folded_into_one.cc | 85 +++ .../template_func_usage_folded_into_one.cc | 76 +++ .../template_type_usage_folded_into_one.cc | 56 ++ .../template_var_usage_folded_into_one.cc | 125 ++++ index_tests/types/anonymous_struct.cc | 109 ++++ index_tests/types/typedefs.cc | 61 ++ index_tests/unions/union_decl.cc | 83 +++ index_tests/unions/union_usage.cc | 120 ++++ .../usage/func_called_from_constructor.cc | 70 ++ .../usage/func_called_from_macro_argument.cc | 61 ++ .../usage/func_called_from_template.cc | 69 ++ .../usage/func_called_implicit_ctor.cc | 83 +++ index_tests/usage/func_usage_addr_func.cc | 75 +++ index_tests/usage/func_usage_addr_method.cc | 78 +++ index_tests/usage/func_usage_call_func.cc | 45 ++ index_tests/usage/func_usage_call_method.cc | 80 +++ .../usage/func_usage_class_inline_var_def.cc | 76 +++ .../usage/func_usage_forward_decl_func.cc | 46 ++ .../usage/func_usage_forward_decl_method.cc | 79 +++ index_tests/usage/func_usage_template_func.cc | 65 ++ .../usage/type_usage_as_template_parameter.cc | 105 +++ ...ype_usage_as_template_parameter_complex.cc | 234 +++++++ ...type_usage_as_template_parameter_simple.cc | 59 ++ .../usage/type_usage_declare_extern.cc | 39 ++ index_tests/usage/type_usage_declare_field.cc | 88 +++ index_tests/usage/type_usage_declare_local.cc | 87 +++ index_tests/usage/type_usage_declare_param.cc | 84 +++ .../type_usage_declare_param_prototype.cc | 64 ++ .../usage/type_usage_declare_param_unnamed.cc | 41 ++ .../usage/type_usage_declare_qualifiers.cc | 122 ++++ .../usage/type_usage_declare_static.cc | 40 ++ .../usage/type_usage_on_return_type.cc | 152 +++++ .../usage/type_usage_typedef_and_using.cc | 181 ++++++ .../type_usage_typedef_and_using_template.cc | 66 ++ index_tests/usage/type_usage_various.cc | 78 +++ index_tests/usage/usage_inside_of_call.cc | 141 ++++ .../usage/usage_inside_of_call_simple.cc | 64 ++ index_tests/usage/var_usage_call_function.cc | 60 ++ index_tests/usage/var_usage_class_member.cc | 142 +++++ .../usage/var_usage_class_member_static.cc | 91 +++ index_tests/usage/var_usage_cstyle_cast.cc | 133 ++++ index_tests/usage/var_usage_extern.cc | 54 ++ index_tests/usage/var_usage_func_parameter.cc | 54 ++ index_tests/usage/var_usage_local.cc | 55 ++ index_tests/usage/var_usage_shadowed_local.cc | 72 +++ .../usage/var_usage_shadowed_parameter.cc | 72 +++ index_tests/usage/var_usage_static.cc | 57 ++ index_tests/vars/class_member.cc | 41 ++ index_tests/vars/class_static_member.cc | 44 ++ .../vars/class_static_member_decl_only.cc | 53 ++ index_tests/vars/deduce_auto_type.cc | 71 +++ index_tests/vars/function_local.cc | 57 ++ index_tests/vars/function_param.cc | 67 ++ index_tests/vars/function_param_unnamed.cc | 26 + index_tests/vars/function_shadow_local.cc | 72 +++ index_tests/vars/function_shadow_param.cc | 67 ++ index_tests/vars/global_variable.cc | 38 ++ index_tests/vars/global_variable_decl_only.cc | 35 + .../vars/type_instance_on_using_type.cc | 79 +++ src/cache_manager.cc | 12 +- src/cache_manager.h | 4 +- src/clang_complete.cc | 8 +- src/clang_complete.h | 4 +- src/clang_cursor.h | 2 +- src/clang_indexer.cc | 84 +-- src/clang_translation_unit.cc | 2 +- src/clang_utils.cc | 4 +- src/clang_utils.h | 4 +- src/code_complete_cache.h | 6 +- src/command_line.cc | 8 +- src/config.h | 24 +- src/file_consumer.cc | 6 +- src/file_contents.cc | 10 +- src/file_contents.h | 7 +- src/fuzzy_match.h | 2 +- src/iindexer.cc | 6 +- src/iindexer.h | 4 +- src/import_pipeline.cc | 42 +- src/include_complete.cc | 4 +- src/include_complete.h | 2 +- src/indexer.h | 12 +- src/lex_utils.cc | 16 +- src/lex_utils.h | 6 +- src/lsp.cc | 42 +- src/lsp.h | 22 +- src/lsp_code_action.h | 2 +- src/lsp_completion.h | 10 +- src/lsp_diagnostic.h | 6 +- src/match.cc | 10 +- src/match.h | 4 +- src/maybe.h | 10 +- src/message_handler.cc | 32 +- src/message_handler.h | 16 +- src/messages/{cquery_base.cc => ccls_base.cc} | 14 +- ...ll_hierarchy.cc => ccls_call_hierarchy.cc} | 40 +- .../{cquery_callers.cc => ccls_callers.cc} | 14 +- .../{cquery_derived.cc => ccls_derived.cc} | 14 +- .../{cquery_did_view.cc => ccls_did_view.cc} | 20 +- ...{cquery_file_info.cc => ccls_file_info.cc} | 20 +- ...freshen_index.cc => ccls_freshen_index.cc} | 22 +- ...query_index_file.cc => ccls_index_file.cc} | 16 +- ...archy.cc => ccls_inheritance_hierarchy.cc} | 48 +- ..._hierarchy.cc => ccls_member_hierarchy.cc} | 60 +- .../{cquery_random.cc => ccls_random.cc} | 14 +- src/messages/{cquery_vars.cc => ccls_vars.cc} | 14 +- src/messages/{cquery_wait.cc => ccls_wait.cc} | 12 +- src/messages/initialize.cc | 88 +-- src/messages/text_document_code_action.cc | 600 ------------------ src/messages/text_document_code_lens.cc | 12 +- src/messages/text_document_completion.cc | 6 +- src/messages/text_document_did_change.cc | 2 +- src/messages/text_document_did_open.cc | 8 +- src/messages/text_document_did_save.cc | 2 +- .../text_document_document_highlight.cc | 2 +- src/messages/text_document_document_link.cc | 6 +- src/messages/text_document_document_symbol.cc | 4 +- src/messages/text_document_formatting.cc | 2 +- src/messages/text_document_hover.cc | 8 +- .../text_document_range_formatting.cc | 2 +- src/messages/text_document_references.cc | 2 +- src/messages/text_document_rename.cc | 2 +- src/messages/text_document_signature_help.cc | 8 +- .../workspace_did_change_watched_files.cc | 2 +- src/messages/workspace_execute_command.cc | 8 +- src/messages/workspace_symbol.cc | 4 +- src/method.cc | 4 +- src/method.h | 4 +- src/nt_string.h | 3 +- src/platform.h | 6 +- src/platform_posix.cc | 24 +- src/platform_win.cc | 10 +- src/port.cc | 2 +- src/port.h | 4 +- src/project.cc | 76 +-- src/project.h | 10 +- src/query.cc | 40 +- src/query.h | 10 +- src/query_utils.cc | 34 +- src/query_utils.h | 12 +- src/recorder.cc | 2 +- src/recorder.h | 2 +- src/semantic_highlight_symbol_cache.cc | 8 +- src/semantic_highlight_symbol_cache.h | 4 +- src/serializer.cc | 2 +- src/serializer.h | 36 +- src/standard_includes.cc | 2 +- src/symbol.h | 2 +- src/task.cc | 16 +- src/task.h | 6 +- src/test.cc | 10 +- src/threaded_queue.h | 16 +- src/timer.cc | 2 +- src/timer.h | 4 +- src/timestamp_manager.cc | 4 +- src/timestamp_manager.h | 4 +- src/utils.cc | 8 +- src/utils.h | 6 +- src/working_files.cc | 12 +- src/working_files.h | 6 +- third_party/string_view.h | 3 - 231 files changed, 11331 insertions(+), 1363 deletions(-) create mode 100644 index_tests/_empty_test.cc create mode 100644 index_tests/class_forward_declaration.cc create mode 100644 index_tests/constructors/constructor.cc create mode 100644 index_tests/constructors/destructor.cc create mode 100644 index_tests/constructors/implicit_constructor.cc create mode 100644 index_tests/constructors/invalid_reference.cc create mode 100644 index_tests/constructors/make_functions.cc create mode 100644 index_tests/constructors/make_functions.h create mode 100644 index_tests/declaration_vs_definition/class.cc create mode 100644 index_tests/declaration_vs_definition/class_member.cc create mode 100644 index_tests/declaration_vs_definition/class_member_static.cc create mode 100644 index_tests/declaration_vs_definition/func.cc create mode 100644 index_tests/declaration_vs_definition/func_associated_function_params.cc create mode 100644 index_tests/declaration_vs_definition/method.cc create mode 100644 index_tests/enums/enum_class_decl.cc create mode 100644 index_tests/enums/enum_decl.cc create mode 100644 index_tests/enums/enum_inherit.cc create mode 100644 index_tests/enums/enum_usage.cc create mode 100644 index_tests/foobar.cc create mode 100644 index_tests/function_declaration.cc create mode 100644 index_tests/function_declaration_definition.cc create mode 100644 index_tests/function_definition.cc create mode 100644 index_tests/inheritance/class_inherit.cc create mode 100644 index_tests/inheritance/class_inherit_templated_parent.cc create mode 100644 index_tests/inheritance/class_multiple_inherit.cc create mode 100644 index_tests/inheritance/function_override.cc create mode 100644 index_tests/inheritance/interface_pure_virtual.cc create mode 100644 index_tests/inheritance/multiple_base_functions.cc create mode 100644 index_tests/lambdas/lambda.cc create mode 100644 index_tests/macros/complex.cc create mode 100644 index_tests/macros/foo.cc create mode 100644 index_tests/method_declaration.cc create mode 100644 index_tests/method_definition.cc create mode 100644 index_tests/method_inline_declaration.cc create mode 100644 index_tests/multi_file/funky_enum.cc create mode 100644 index_tests/multi_file/funky_enum.h create mode 100644 index_tests/multi_file/header.h create mode 100644 index_tests/multi_file/impl.cc create mode 100644 index_tests/multi_file/simple_header.h create mode 100644 index_tests/multi_file/simple_impl.cc create mode 100644 index_tests/multi_file/static.cc create mode 100644 index_tests/multi_file/static.h create mode 100644 index_tests/namespaces/anonymous_function.cc create mode 100644 index_tests/namespaces/function_declaration.cc create mode 100644 index_tests/namespaces/function_definition.cc create mode 100644 index_tests/namespaces/method_declaration.cc create mode 100644 index_tests/namespaces/method_definition.cc create mode 100644 index_tests/namespaces/method_inline_declaration.cc create mode 100644 index_tests/namespaces/namespace_alias.cc create mode 100644 index_tests/namespaces/namespace_reference.cc create mode 100644 index_tests/objective-c/class.m create mode 100644 index_tests/operators/operator.cc create mode 100644 index_tests/outline/outline.cc create mode 100644 index_tests/outline/outline2.cc create mode 100644 index_tests/outline/static_function_in_type.cc create mode 100644 index_tests/outline/static_function_in_type.h create mode 100644 index_tests/preprocessor/include_guard.cc create mode 100644 index_tests/preprocessor/skipped.cc create mode 100644 index_tests/templates/func_specialized_template_param.cc create mode 100644 index_tests/templates/implicit_variable_instantiation.cc create mode 100644 index_tests/templates/member_ref_in_template.cc create mode 100644 index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc create mode 100644 index_tests/templates/namespace_template_type_usage_folded_into_one.cc create mode 100644 index_tests/templates/specialization.cc create mode 100644 index_tests/templates/specialized_func_definition.cc create mode 100644 index_tests/templates/template_class_func_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_class_template_func_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_class_type_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_class_var_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_func_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_type_usage_folded_into_one.cc create mode 100644 index_tests/templates/template_var_usage_folded_into_one.cc create mode 100644 index_tests/types/anonymous_struct.cc create mode 100644 index_tests/types/typedefs.cc create mode 100644 index_tests/unions/union_decl.cc create mode 100644 index_tests/unions/union_usage.cc create mode 100644 index_tests/usage/func_called_from_constructor.cc create mode 100644 index_tests/usage/func_called_from_macro_argument.cc create mode 100644 index_tests/usage/func_called_from_template.cc create mode 100644 index_tests/usage/func_called_implicit_ctor.cc create mode 100644 index_tests/usage/func_usage_addr_func.cc create mode 100644 index_tests/usage/func_usage_addr_method.cc create mode 100644 index_tests/usage/func_usage_call_func.cc create mode 100644 index_tests/usage/func_usage_call_method.cc create mode 100644 index_tests/usage/func_usage_class_inline_var_def.cc create mode 100644 index_tests/usage/func_usage_forward_decl_func.cc create mode 100644 index_tests/usage/func_usage_forward_decl_method.cc create mode 100644 index_tests/usage/func_usage_template_func.cc create mode 100644 index_tests/usage/type_usage_as_template_parameter.cc create mode 100644 index_tests/usage/type_usage_as_template_parameter_complex.cc create mode 100644 index_tests/usage/type_usage_as_template_parameter_simple.cc create mode 100644 index_tests/usage/type_usage_declare_extern.cc create mode 100644 index_tests/usage/type_usage_declare_field.cc create mode 100644 index_tests/usage/type_usage_declare_local.cc create mode 100644 index_tests/usage/type_usage_declare_param.cc create mode 100644 index_tests/usage/type_usage_declare_param_prototype.cc create mode 100644 index_tests/usage/type_usage_declare_param_unnamed.cc create mode 100644 index_tests/usage/type_usage_declare_qualifiers.cc create mode 100644 index_tests/usage/type_usage_declare_static.cc create mode 100644 index_tests/usage/type_usage_on_return_type.cc create mode 100644 index_tests/usage/type_usage_typedef_and_using.cc create mode 100644 index_tests/usage/type_usage_typedef_and_using_template.cc create mode 100644 index_tests/usage/type_usage_various.cc create mode 100644 index_tests/usage/usage_inside_of_call.cc create mode 100644 index_tests/usage/usage_inside_of_call_simple.cc create mode 100644 index_tests/usage/var_usage_call_function.cc create mode 100644 index_tests/usage/var_usage_class_member.cc create mode 100644 index_tests/usage/var_usage_class_member_static.cc create mode 100644 index_tests/usage/var_usage_cstyle_cast.cc create mode 100644 index_tests/usage/var_usage_extern.cc create mode 100644 index_tests/usage/var_usage_func_parameter.cc create mode 100644 index_tests/usage/var_usage_local.cc create mode 100644 index_tests/usage/var_usage_shadowed_local.cc create mode 100644 index_tests/usage/var_usage_shadowed_parameter.cc create mode 100644 index_tests/usage/var_usage_static.cc create mode 100644 index_tests/vars/class_member.cc create mode 100644 index_tests/vars/class_static_member.cc create mode 100644 index_tests/vars/class_static_member_decl_only.cc create mode 100644 index_tests/vars/deduce_auto_type.cc create mode 100644 index_tests/vars/function_local.cc create mode 100644 index_tests/vars/function_param.cc create mode 100644 index_tests/vars/function_param_unnamed.cc create mode 100644 index_tests/vars/function_shadow_local.cc create mode 100644 index_tests/vars/function_shadow_param.cc create mode 100644 index_tests/vars/global_variable.cc create mode 100644 index_tests/vars/global_variable_decl_only.cc create mode 100644 index_tests/vars/type_instance_on_using_type.cc rename src/messages/{cquery_base.cc => ccls_base.cc} (80%) rename src/messages/{cquery_call_hierarchy.cc => ccls_call_hierarchy.cc} (85%) rename src/messages/{cquery_callers.cc => ccls_callers.cc} (78%) rename src/messages/{cquery_derived.cc => ccls_derived.cc} (78%) rename src/messages/{cquery_did_view.cc => ccls_did_view.cc} (57%) rename src/messages/{cquery_file_info.cc => ccls_file_info.cc} (65%) rename src/messages/{cquery_freshen_index.cc => ccls_freshen_index.cc} (81%) rename src/messages/{cquery_index_file.cc => ccls_index_file.cc} (68%) rename src/messages/{cquery_inheritance_hierarchy.cc => ccls_inheritance_hierarchy.cc} (78%) rename src/messages/{cquery_member_hierarchy.cc => ccls_member_hierarchy.cc} (82%) rename src/messages/{cquery_random.cc => ccls_random.cc} (91%) rename src/messages/{cquery_vars.cc => ccls_vars.cc} (80%) rename src/messages/{cquery_wait.cc => ccls_wait.cc} (82%) delete mode 100644 src/messages/text_document_code_action.cc delete mode 100644 third_party/string_view.h diff --git a/.gitignore b/.gitignore index 4ba98ad52..a0783c5f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,4 @@ -.cquery_cached_index -.DS_Store -.lock-waf* -.vs -.vscode/ -.vscode/.ropeproject -.waf* -*.cquery -*.sln -*.swp -*.vcxproj -*.vcxproj.filters -*.vcxproj.user -**/*.pyc +.* build -cquery_diagnostics.log -cquery_log.txt -Debug -e2e_cache -foo -libcxx -vscode-extension.vsix -waf-* -waf2* -waf3* -x64 +debug +release diff --git a/CMakeLists.txt b/CMakeLists.txt index a9ed816be..90c13cc97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -project(cquery LANGUAGES CXX) +project(ccls LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) @@ -8,11 +8,11 @@ include(DownloadAndExtractLLVM) set(CLANG_VERSION 6.0.0 CACHE STRING "Downloaded Clang version (6.0.0)") option(SYSTEM_CLANG "Use system Clang instead of downloading Clang" OFF) option(ASAN "Compile with address sanitizers" OFF) -option(CLANG_CXX "Build with Clang C++ api required by some cquery \ +option(CLANG_CXX "Build with Clang C++ api required by some ccls \ features (warning: not available in LLVM Windows downloads)" OFF) # Sources for the executable are specified at end of CMakeLists.txt -add_executable(cquery "") +add_executable(ccls "") ### Compile options @@ -25,16 +25,16 @@ add_executable(cquery "") # release: -O3 -DNDEBUG # Enable C++14 (Required) -set_property(TARGET cquery PROPERTY CXX_STANDARD 14) -set_property(TARGET cquery PROPERTY CXX_STANDARD_REQUIRED ON) +set_property(TARGET ccls PROPERTY CXX_STANDARD 17) +set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) # Disable gnu extensions except for Cygwin which needs them to build properly if(NOT CYGWIN) - set_property(TARGET cquery PROPERTY CXX_EXTENSIONS OFF) + set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Common MSVC/Clang(Windows) options - target_compile_options(cquery PRIVATE + target_compile_options(ccls PRIVATE /nologo /EHsc /W3 # roughly -Wall @@ -49,17 +49,17 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) ) else() # Common GCC/Clang(Linux) options - target_compile_options(cquery PRIVATE + target_compile_options(ccls PRIVATE -Wall -Wno-sign-compare ) if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) - target_compile_options(cquery PRIVATE -Wno-return-type -Wno-unused-result) + target_compile_options(ccls PRIVATE -Wno-return-type -Wno-unused-result) endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) - target_compile_options(cquery PRIVATE + target_compile_options(ccls PRIVATE $<$:-fno-limit-debug-info>) endif() @@ -67,13 +67,13 @@ else() # -Wno-comment: include/clang/Format/Format.h error: multi-line comment # -fno-rtti: # Without -fno-rtti, some Clang C++ functions may report # `undefined references to typeinfo` - target_compile_options(cquery PRIVATE -Wno-comment -fno-rtti) + target_compile_options(ccls PRIVATE -Wno-comment -fno-rtti) endif() if(ASAN) - target_compile_options(cquery PRIVATE -fsanitize=address,undefined) + target_compile_options(ccls PRIVATE -fsanitize=address,undefined) # target_link_libraries also takes linker flags - target_link_libraries(cquery PRIVATE -fsanitize=address,undefined) + target_link_libraries(ccls PRIVATE -fsanitize=address,undefined) endif() endif() @@ -89,50 +89,50 @@ endif() # See cmake/FindClang.cmake find_package(Clang REQUIRED) -target_link_libraries(cquery PRIVATE Clang::Clang) +target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -target_link_libraries(cquery PRIVATE Threads::Threads) +target_link_libraries(ccls PRIVATE Threads::Threads) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) # loguru calls dladdr - target_link_libraries(cquery PRIVATE ${CMAKE_DL_LIBS}) + target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) # loguru::stacktrace_as_stdstring calls backtrace_symbols # sparsepp/spp_memory.h uses libkvm # src/platform_posix.cc uses libthr find_package(Backtrace REQUIRED) - target_link_libraries(cquery PRIVATE ${Backtrace_LIBRARIES} kvm thr) + target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} kvm thr) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # sparsepp/spp_memory.h uses LibPsapi - target_link_libraries(cquery PRIVATE Psapi) + target_link_libraries(ccls PRIVATE Psapi) endif() if(CLANG_CXX) # Clang C++ api uses ncurses find_package(Curses REQUIRED) - target_link_libraries(cquery PRIVATE ${CURSES_LIBRARIES}) + target_link_libraries(ccls PRIVATE ${CURSES_LIBRARIES}) endif() ### Definitions -target_compile_definitions(cquery PRIVATE +target_compile_definitions(ccls PRIVATE LOGURU_WITH_STREAMS=1 LOGURU_FILENAME_WIDTH=18 LOGURU_THREADNAME_WIDTH=13 DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}") if(CLANG_CXX) - target_compile_definitions(cquery PRIVATE USE_CLANG_CXX=1 LOGURU_RTTI=0) + target_compile_definitions(ccls PRIVATE USE_CLANG_CXX=1 LOGURU_RTTI=0) endif() ### Includes -target_include_directories(cquery PRIVATE +target_include_directories(ccls PRIVATE src third_party third_party/rapidjson/include @@ -143,17 +143,17 @@ target_include_directories(cquery PRIVATE ### Install -install(TARGETS cquery RUNTIME DESTINATION bin) +install(TARGETS ccls RUNTIME DESTINATION bin) # We don't need to install libclang on Windows if we are using downloaded LLVM # since libclang is distributed as a static library on Windows if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) - set_property(TARGET cquery APPEND PROPERTY + set_property(TARGET ccls APPEND PROPERTY INSTALL_RPATH $ORIGIN/../lib) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - set_property(TARGET cquery APPEND PROPERTY + set_property(TARGET ccls APPEND PROPERTY INSTALL_RPATH @loader_path/../lib) endif() @@ -164,9 +164,9 @@ endif() ### Sources -target_sources(cquery PRIVATE third_party/siphash.cc) +target_sources(ccls PRIVATE third_party/siphash.cc) -target_sources(cquery PRIVATE +target_sources(ccls PRIVATE src/cache_manager.cc src/clang_complete.cc src/clang_cursor.cc @@ -215,24 +215,23 @@ target_sources(cquery PRIVATE src/work_thread.cc src/working_files.cc) -target_sources(cquery PRIVATE - src/messages/cquery_base.cc - src/messages/cquery_call_hierarchy.cc - src/messages/cquery_callers.cc - src/messages/cquery_derived.cc - src/messages/cquery_did_view.cc - src/messages/cquery_file_info.cc - src/messages/cquery_freshen_index.cc - src/messages/cquery_index_file.cc - src/messages/cquery_inheritance_hierarchy.cc - src/messages/cquery_member_hierarchy.cc - src/messages/cquery_random.cc - src/messages/cquery_vars.cc - src/messages/cquery_wait.cc +target_sources(ccls PRIVATE + src/messages/ccls_base.cc + src/messages/ccls_call_hierarchy.cc + src/messages/ccls_callers.cc + src/messages/ccls_derived.cc + src/messages/ccls_did_view.cc + src/messages/ccls_file_info.cc + src/messages/ccls_freshen_index.cc + src/messages/ccls_index_file.cc + src/messages/ccls_inheritance_hierarchy.cc + src/messages/ccls_member_hierarchy.cc + src/messages/ccls_random.cc + src/messages/ccls_vars.cc + src/messages/ccls_wait.cc src/messages/exit.cc src/messages/initialize.cc src/messages/shutdown.cc - src/messages/text_document_code_action.cc src/messages/text_document_code_lens.cc src/messages/text_document_completion.cc src/messages/text_document_definition.cc @@ -252,4 +251,5 @@ target_sources(cquery PRIVATE src/messages/text_document_type_definition.cc src/messages/workspace_did_change_configuration.cc src/messages/workspace_did_change_watched_files.cc - src/messages/workspace_symbol.cc) + src/messages/workspace_symbol.cc + ) diff --git a/README.md b/README.md index 5a0668147..9f29f1b23 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ -[![Join the chat at https://gitter.im/cquery-project/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cquery-project/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# ccls -# cquery - -cquery is a highly-scalable, low-latency language server for C/C++/Objective-C. It is tested -and designed for large code bases like -[Chromium](https://chromium.googlesource.com/chromium/src/). cquery provides -accurate and fast semantic analysis without interrupting workflow. - -![Demo](https://ptpb.pw/GlSQ.png?raw=true) - -cquery implements almost the entire language server protocol and provides -some extra features to boot: +ccls is a fork of cquery, a C/C++/Objective-C language server. * code completion (with both signature help and snippets) * finding [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc) @@ -26,19 +16,7 @@ some extra features to boot: * auto-implement functions without a definition * semantic highlighting, including support for [rainbow semantic highlighting](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e) -# >>> [Getting started](https://github.com/jacobdufault/cquery/wiki/Getting-started) (CLICK HERE) <<< - - - Packaging status - - -# Limitations - -cquery is able to respond to queries quickly because it caches a huge amount of -information. When a request comes in, cquery just looks it up in the cache -without running many computations. As a result, there's a large memory overhead. -For example, a full index of Chrome will take about 10gb of memory. If you -exclude v8, webkit, and third_party, it goes down to about 6.5gb. +# >>> [Getting started](https://github.com/MaskRay/ccls/wiki/Getting-started) (CLICK HERE) <<< # License diff --git a/index_tests/_empty_test.cc b/index_tests/_empty_test.cc new file mode 100644 index 000000000..237e15534 --- /dev/null +++ b/index_tests/_empty_test.cc @@ -0,0 +1,10 @@ +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc new file mode 100644 index 000000000..e2194d759 --- /dev/null +++ b/index_tests/class_forward_declaration.cc @@ -0,0 +1,31 @@ +class Foo; +class Foo; +class Foo {}; +class Foo; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], + "spell": "3:7-3:10|-1|1|2", + "extent": "3:1-3:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc new file mode 100644 index 000000000..82c7469ff --- /dev/null +++ b/index_tests/constructors/constructor.cc @@ -0,0 +1,92 @@ +class Foo { +public: + Foo() {} +}; + +void foo() { + Foo f; + Foo* f2 = new Foo(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": ["3:3-3:6|-1|1|4"], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [0, 1], + "uses": ["3:3-3:6|0|2|4", "7:3-7:6|-1|1|4", "8:3-8:6|-1|1|4", "8:17-8:20|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 3385168158331140247, + "detailed_name": "void Foo::Foo()", + "short_name": "Foo", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "3:3-3:6|0|2|2", + "extent": "3:3-3:11|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["7:7-7:8|1|3|288", "8:17-8:20|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "6:6-6:9|-1|1|2", + "extent": "6:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": ["7:7-7:8|0|3|288", "7:7-7:8|0|3|288", "8:17-8:20|0|3|32", "8:17-8:20|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 18410644574635149442, + "detailed_name": "Foo f", + "short_name": "f", + "declarations": [], + "spell": "7:7-7:8|1|3|2", + "extent": "7:3-7:8|1|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 11468802633764653592, + "detailed_name": "Foo *f2", + "short_name": "f2", + "hover": "Foo *f2 = new Foo()", + "declarations": [], + "spell": "8:8-8:10|1|3|2", + "extent": "8:3-8:22|1|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc new file mode 100644 index 000000000..acfa71a37 --- /dev/null +++ b/index_tests/constructors/destructor.cc @@ -0,0 +1,100 @@ +class Foo { +public: + Foo() {} + ~Foo() {}; +}; + +void foo() { + Foo f; +} + +// TODO: Support destructors (notice how the dtor has no usages listed). +// - check if variable is a pointer. if so, do *not* insert dtor +// - check if variable is normal type. if so, insert dtor +// - scan for statements that look like dtors in function def handler +// - figure out some way to support w/ unique_ptrs? +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": ["3:3-3:6|-1|1|4", "4:4-4:7|-1|1|4"], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0, 1], + "vars": [], + "instances": [0], + "uses": ["3:3-3:6|0|2|4", "8:3-8:6|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 3385168158331140247, + "detailed_name": "void Foo::Foo()", + "short_name": "Foo", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "3:3-3:6|0|2|2", + "extent": "3:3-3:11|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:7-8:8|2|3|288"], + "callees": [] + }, { + "id": 1, + "usr": 7440261702884428359, + "detailed_name": "void Foo::~Foo() noexcept", + "short_name": "~Foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "4:3-4:7|0|2|2", + "extent": "4:3-4:12|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "7:6-7:9|-1|1|2", + "extent": "7:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["8:7-8:8|0|3|288", "8:7-8:8|0|3|288"] + }], + "vars": [{ + "id": 0, + "usr": 9954632887635271906, + "detailed_name": "Foo f", + "short_name": "f", + "declarations": [], + "spell": "8:7-8:8|2|3|2", + "extent": "8:3-8:8|2|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc new file mode 100644 index 000000000..fd696780a --- /dev/null +++ b/index_tests/constructors/implicit_constructor.cc @@ -0,0 +1,90 @@ +struct Type { + Type() {} +}; + +void Make() { + Type foo0; + auto foo1 = Type(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13487927231218873822, + "detailed_name": "Type", + "short_name": "Type", + "kind": 23, + "declarations": ["2:3-2:7|-1|1|4"], + "spell": "1:8-1:12|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [0, 1], + "uses": ["2:3-2:7|0|2|4", "6:3-6:7|-1|1|4", "7:15-7:19|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 10530961286677896857, + "detailed_name": "void Type::Type()", + "short_name": "Type", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "2:3-2:7|0|2|2", + "extent": "2:3-2:12|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:8-6:12|1|3|288", "7:15-7:19|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 3957104924306079513, + "detailed_name": "void Make()", + "short_name": "Make", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:10|-1|1|2", + "extent": "5:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": ["6:8-6:12|0|3|288", "6:8-6:12|0|3|288", "7:15-7:19|0|3|32", "7:15-7:19|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 17348451315735351657, + "detailed_name": "Type foo0", + "short_name": "foo0", + "declarations": [], + "spell": "6:8-6:12|1|3|2", + "extent": "6:3-6:12|1|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 3757978174345638825, + "detailed_name": "Type foo1", + "short_name": "foo1", + "declarations": [], + "spell": "7:8-7:12|1|3|2", + "extent": "7:3-7:21|1|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc new file mode 100644 index 000000000..31bacba3f --- /dev/null +++ b/index_tests/constructors/invalid_reference.cc @@ -0,0 +1,51 @@ +struct Foo {}; + +template +Foo::Foo() {} + +/* +EXTRA_FLAGS: +-fms-compatibility +-fdelayed-template-parsing + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["4:6-4:9|-1|1|4"], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-1:14|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["4:6-4:9|-1|1|4", "4:1-4:4|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 17319723337446061757, + "detailed_name": "void Foo::Foo()", + "short_name": "Foo", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|0|2|2", + "extent": "4:1-4:11|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc new file mode 100644 index 000000000..f044001af --- /dev/null +++ b/index_tests/constructors/make_functions.cc @@ -0,0 +1,353 @@ +#include "make_functions.h" + +template +T* MakeUnique(Args&&... args) { + return nullptr; +} + +template +T* maKE_NoRefs(Args... args) { + return nullptr; +} + +void caller22() { + MakeUnique(); + MakeUnique(1); + MakeUnique(1, new Bar(), nullptr); + maKE_NoRefs(1, new Bar(), nullptr); +} + +// TODO: Eliminate the extra entries in the "types" array here. They come from +// the template function definitions. + +// Foobar is defined in a separate file to ensure that we can attribute +// MakeUnique calls across translation units. + +/* +OUTPUT: make_functions.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 12993848456528750350, + "detailed_name": "Bar", + "short_name": "Bar", + "kind": 23, + "declarations": [], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-1:14|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:17-7:20|-1|1|4", "8:15-8:18|-1|1|4"] + }, { + "id": 1, + "usr": 14935975554338052500, + "detailed_name": "Foobar", + "short_name": "Foobar", + "kind": 5, + "declarations": ["5:3-5:9|-1|1|4", "6:3-6:9|-1|1|4", "7:3-7:9|-1|1|4", "8:3-8:9|-1|1|4"], + "spell": "3:7-3:13|-1|1|2", + "extent": "3:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0, 1, 2, 3], + "vars": [], + "instances": [], + "uses": ["5:3-5:9|1|2|4", "6:3-6:9|1|2|4", "7:3-7:9|1|2|4", "8:3-8:9|1|2|4"] + }], + "funcs": [{ + "id": 0, + "usr": 13131778807733950299, + "detailed_name": "void Foobar::Foobar()", + "short_name": "Foobar", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "5:3-5:9|1|2|2", + "extent": "5:3-5:14|1|2|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 13028995015627606181, + "detailed_name": "void Foobar::Foobar(int)", + "short_name": "Foobar", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "6:3-6:9|1|2|2", + "extent": "6:3-6:17|1|2|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 3765833212244435302, + "detailed_name": "void Foobar::Foobar(int &&, Bar *, bool *)", + "short_name": "Foobar", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "7:3-7:9|1|2|2", + "extent": "7:3-7:32|1|2|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 17321436359755983845, + "detailed_name": "void Foobar::Foobar(int, Bar *, bool *)", + "short_name": "Foobar", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "8:3-8:9|1|2|2", + "extent": "8:3-8:30|1|2|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +OUTPUT: make_functions.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&make_functions.h" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 7902098450755788854, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "3:20-3:21|0|3|2", + "extent": "3:11-3:21|0|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:1-4:2|-1|1|4"] + }, { + "id": 1, + "usr": 12533159752419999454, + "detailed_name": "Args", + "short_name": "Args", + "kind": 26, + "declarations": [], + "spell": "3:35-3:39|0|3|2", + "extent": "3:23-3:39|0|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:15-4:19|-1|1|4"] + }, { + "id": 2, + "usr": 18441628706991062891, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "8:20-8:21|1|3|2", + "extent": "8:11-8:21|1|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:1-9:2|-1|1|4"] + }, { + "id": 3, + "usr": 9441341235704820385, + "detailed_name": "Args", + "short_name": "Args", + "kind": 26, + "declarations": [], + "spell": "8:35-8:39|1|3|2", + "extent": "8:23-8:39|1|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:16-9:20|-1|1|4"] + }, { + "id": 4, + "usr": 14935975554338052500, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["14:14-14:20|-1|1|4", "15:14-15:20|-1|1|4", "16:14-16:20|-1|1|4", "17:15-17:21|-1|1|4"] + }, { + "id": 5, + "usr": 12993848456528750350, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["16:29-16:32|-1|1|4", "17:30-17:33|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 15793662558620604611, + "detailed_name": "T *MakeUnique(Args &&... args)", + "short_name": "MakeUnique", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:4-4:14|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": ["14:3-14:13|2|3|32", "15:3-15:13|2|3|32", "16:3-16:13|2|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 2532818908869373467, + "detailed_name": "T *maKE_NoRefs(Args... args)", + "short_name": "maKE_NoRefs", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "9:4-9:15|-1|1|2", + "extent": "9:1-11:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [1], + "uses": ["17:3-17:14|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 2816883305867289955, + "detailed_name": "void caller22()", + "short_name": "caller22", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "13:6-13:14|-1|1|2", + "extent": "13:1-18:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["14:3-14:13|0|3|32", "15:3-15:13|0|3|32", "16:3-16:13|0|3|32", "17:3-17:14|1|3|32"] + }, { + "id": 3, + "usr": 13131778807733950299, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["14:3-14:13|-1|1|288"], + "callees": [] + }, { + "id": 4, + "usr": 13028995015627606181, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["15:3-15:13|-1|1|288"], + "callees": [] + }, { + "id": 5, + "usr": 3765833212244435302, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["16:3-16:13|-1|1|288"], + "callees": [] + }, { + "id": 6, + "usr": 17321436359755983845, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["17:3-17:14|-1|1|288"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 15288691366352169805, + "detailed_name": "Args &&... args", + "short_name": "args", + "declarations": [], + "spell": "4:25-4:29|0|3|2", + "extent": "4:15-4:29|0|3|0", + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 12338908251430965107, + "detailed_name": "Args... args", + "short_name": "args", + "declarations": [], + "spell": "9:24-9:28|1|3|2", + "extent": "9:16-9:28|1|3|0", + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/constructors/make_functions.h b/index_tests/constructors/make_functions.h new file mode 100644 index 000000000..f119cfb8e --- /dev/null +++ b/index_tests/constructors/make_functions.h @@ -0,0 +1,10 @@ +struct Bar {}; + +class Foobar { + public: + Foobar() {} + Foobar(int) {} + Foobar(int&&, Bar*, bool*) {} + Foobar(int, Bar*, bool*) {} +}; + diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc new file mode 100644 index 000000000..00e22bc45 --- /dev/null +++ b/index_tests/declaration_vs_definition/class.cc @@ -0,0 +1,33 @@ +class Foo; +class Foo; +class Foo {}; +class Foo; + +/* +// NOTE: Separate decl/definition are not supported for classes. See source +// for comments. +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], + "spell": "3:7-3:10|-1|1|2", + "extent": "3:1-3:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc new file mode 100644 index 000000000..ccbbd2c91 --- /dev/null +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -0,0 +1,56 @@ +class Foo { + int foo; +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 9736582033442720743, + "detailed_name": "int Foo::foo", + "short_name": "foo", + "declarations": [], + "spell": "2:7-2:10|0|2|2", + "extent": "2:3-2:10|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc new file mode 100644 index 000000000..838913bc7 --- /dev/null +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -0,0 +1,58 @@ +class Foo { + static int foo; +}; + +int Foo::foo; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": ["5:5-5:8|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 8942920329766232482, + "detailed_name": "int Foo::foo", + "short_name": "foo", + "declarations": ["2:14-2:17|0|2|1"], + "spell": "5:10-5:13|0|2|2", + "extent": "5:1-5:13|-1|1|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 1 + }] +} +*/ diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc new file mode 100644 index 000000000..8e69aeb16 --- /dev/null +++ b/index_tests/declaration_vs_definition/func.cc @@ -0,0 +1,40 @@ +void foo(); +void foo(); +void foo() {} +void foo(); + +/* +// Note: we always use the latest seen ("most local") definition/declaration. +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:9|-1|1|1", + "param_spellings": [] + }, { + "spell": "2:6-2:9|-1|1|1", + "param_spellings": [] + }, { + "spell": "4:6-4:9|-1|1|1", + "param_spellings": [] + }], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-3:14|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc new file mode 100644 index 000000000..f917921e5 --- /dev/null +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -0,0 +1,78 @@ +int foo(int, int); +int foo(int aa, + int bb); +int foo(int aaa, int bbb); +int foo(int a, int b) { return 0; } + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 2747674671862363334, + "detailed_name": "int foo(int a, int b)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:5-1:8|-1|1|1", + "param_spellings": ["1:12-1:12", "1:17-1:17"] + }, { + "spell": "2:5-2:8|-1|1|1", + "param_spellings": ["2:13-2:15", "3:13-3:15"] + }, { + "spell": "4:5-4:8|-1|1|1", + "param_spellings": ["4:13-4:16", "4:22-4:25"] + }], + "spell": "5:5-5:8|-1|1|2", + "extent": "5:1-5:36|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 10480417713467708012, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "5:13-5:14|0|3|2", + "extent": "5:9-5:14|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 18099600680625658464, + "detailed_name": "int b", + "short_name": "b", + "declarations": [], + "spell": "5:20-5:21|0|3|2", + "extent": "5:16-5:21|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc new file mode 100644 index 000000000..1be15a33f --- /dev/null +++ b/index_tests/declaration_vs_definition/method.cc @@ -0,0 +1,87 @@ +class Foo { + void declonly(); + virtual void purevirtual() = 0; + void def(); +}; + +void Foo::def() {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0, 1, 2], + "vars": [], + "instances": [], + "uses": ["7:6-7:9|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 4012226004228259562, + "detailed_name": "void Foo::declonly()", + "short_name": "declonly", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:16|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 10939323144126021546, + "detailed_name": "void Foo::purevirtual()", + "short_name": "purevirtual", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "3:16-3:27|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 15416083548883122431, + "detailed_name": "void Foo::def()", + "short_name": "def", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "4:8-4:11|0|2|1", + "param_spellings": [] + }], + "spell": "7:11-7:14|0|2|2", + "extent": "7:1-7:19|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc new file mode 100644 index 000000000..6d1cd6fb7 --- /dev/null +++ b/index_tests/enums/enum_class_decl.cc @@ -0,0 +1,90 @@ +typedef unsigned char uint8_t; +enum class Foo : uint8_t { + A, + B = 20 +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 5, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 2010430204259339553, + "detailed_name": "uint8_t", + "short_name": "uint8_t", + "kind": 252, + "hover": "typedef unsigned char uint8_t", + "declarations": [], + "spell": "1:23-1:30|-1|1|2", + "extent": "1:1-1:30|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:23-1:30|-1|1|4", "2:12-2:15|-1|1|4"] + }, { + "id": 2, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 10, + "declarations": [], + "spell": "2:12-2:15|-1|1|2", + "extent": "2:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 439339022761937396, + "detailed_name": "Foo::A", + "short_name": "A", + "hover": "Foo::A = 0", + "declarations": [], + "spell": "3:3-3:4|2|2|2", + "extent": "3:3-3:4|2|2|0", + "type": 2, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "short_name": "B", + "hover": "Foo::B = 20", + "declarations": [], + "spell": "4:3-4:4|2|2|2", + "extent": "4:3-4:9|2|2|0", + "type": 2, + "uses": [], + "kind": 22, + "storage": 0 + }] +} +*/ diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc new file mode 100644 index 000000000..9240c5a53 --- /dev/null +++ b/index_tests/enums/enum_decl.cc @@ -0,0 +1,57 @@ +enum Foo { + A, + B = 20 +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 10, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 439339022761937396, + "detailed_name": "Foo::A", + "short_name": "A", + "hover": "Foo::A = 0", + "declarations": [], + "spell": "2:3-2:4|0|2|2", + "extent": "2:3-2:4|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "short_name": "B", + "hover": "Foo::B = 20", + "declarations": [], + "spell": "3:3-3:4|0|2|2", + "extent": "3:3-3:9|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }] +} +*/ diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc new file mode 100644 index 000000000..9ee6bcdfc --- /dev/null +++ b/index_tests/enums/enum_inherit.cc @@ -0,0 +1,138 @@ +enum Foo : int { + A, + B = 20 +}; + +typedef int int32_t; + +enum class E : int32_t { + E0, + E20 = 20 +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 10, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 14939241684006947339, + "detailed_name": "int32_t", + "short_name": "int32_t", + "kind": 252, + "hover": "typedef int int32_t", + "declarations": [], + "spell": "6:13-6:20|-1|1|2", + "extent": "6:1-6:20|-1|1|0", + "alias_of": 1, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:13-6:20|-1|1|4", "8:12-8:13|-1|1|4"] + }, { + "id": 3, + "usr": 2986879766914123941, + "detailed_name": "E", + "short_name": "E", + "kind": 10, + "declarations": [], + "spell": "8:12-8:13|-1|1|2", + "extent": "8:1-11:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 439339022761937396, + "detailed_name": "Foo::A", + "short_name": "A", + "hover": "Foo::A = 0", + "declarations": [], + "spell": "2:3-2:4|0|2|2", + "extent": "2:3-2:4|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "short_name": "B", + "hover": "Foo::B = 20", + "declarations": [], + "spell": "3:3-3:4|0|2|2", + "extent": "3:3-3:9|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 2, + "usr": 16614320383091394267, + "detailed_name": "E::E0", + "short_name": "E0", + "hover": "E::E0 = 0", + "declarations": [], + "spell": "9:3-9:5|3|2|2", + "extent": "9:3-9:5|3|2|0", + "type": 3, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 3, + "usr": 16847439761518576294, + "detailed_name": "E::E20", + "short_name": "E20", + "hover": "E::E20 = 20", + "declarations": [], + "spell": "10:3-10:6|3|2|2", + "extent": "10:3-10:11|3|2|0", + "type": 3, + "uses": [], + "kind": 22, + "storage": 0 + }] +} +*/ diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc new file mode 100644 index 000000000..c019a36c3 --- /dev/null +++ b/index_tests/enums/enum_usage.cc @@ -0,0 +1,72 @@ +enum class Foo { + A, + B = 20 +}; + +Foo x = Foo::A; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 10, + "declarations": [], + "spell": "1:12-1:15|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["6:1-6:4|-1|1|4", "6:9-6:12|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 439339022761937396, + "detailed_name": "Foo::A", + "short_name": "A", + "hover": "Foo::A = 0", + "declarations": [], + "spell": "2:3-2:4|0|2|2", + "extent": "2:3-2:4|0|2|0", + "type": 0, + "uses": ["6:14-6:15|-1|1|4"], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "short_name": "B", + "hover": "Foo::B = 20", + "declarations": [], + "spell": "3:3-3:4|0|2|2", + "extent": "3:3-3:9|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 2, + "usr": 10677751717622394455, + "detailed_name": "Foo x", + "short_name": "x", + "hover": "Foo x = Foo::A", + "declarations": [], + "spell": "6:5-6:6|-1|1|2", + "extent": "6:1-6:15|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc new file mode 100644 index 000000000..0d240d274 --- /dev/null +++ b/index_tests/foobar.cc @@ -0,0 +1,108 @@ +enum A {}; +enum B {}; + +template +struct Foo { + struct Inner {}; +}; + +Foo::Inner a; +Foo b; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 6697181287623958829, + "detailed_name": "A", + "short_name": "A", + "kind": 10, + "declarations": [], + "spell": "1:6-1:7|-1|1|2", + "extent": "1:1-1:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:5-9:6|-1|1|4"] + }, { + "id": 1, + "usr": 13892793056005362145, + "detailed_name": "B", + "short_name": "B", + "kind": 10, + "declarations": [], + "spell": "2:6-2:7|-1|1|2", + "extent": "2:1-2:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["10:5-10:6|-1|1|4"] + }, { + "id": 2, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "5:8-5:11|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": ["9:1-9:4|-1|1|4", "10:1-10:4|-1|1|4"] + }, { + "id": 3, + "usr": 13938528237873543349, + "detailed_name": "Foo::Inner", + "short_name": "Inner", + "kind": 23, + "declarations": [], + "spell": "6:10-6:15|2|2|2", + "extent": "6:3-6:18|2|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["9:9-9:14|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "Foo::Inner a", + "short_name": "a", + "declarations": [], + "spell": "9:15-9:16|-1|1|2", + "extent": "9:1-9:16|-1|1|0", + "type": 3, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "Foo b", + "short_name": "b", + "declarations": [], + "spell": "10:8-10:9|-1|1|2", + "extent": "10:1-10:9|-1|1|0", + "type": 2, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc new file mode 100644 index 000000000..a9bb6ae13 --- /dev/null +++ b/index_tests/function_declaration.cc @@ -0,0 +1,28 @@ +void foo(int a, int b); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 2747674671862363334, + "detailed_name": "void foo(int a, int b)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:9|-1|1|1", + "param_spellings": ["1:14-1:15", "1:21-1:22"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc new file mode 100644 index 000000000..7b1f40306 --- /dev/null +++ b/index_tests/function_declaration_definition.cc @@ -0,0 +1,32 @@ +void foo(); + +void foo() {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:9|-1|1|1", + "param_spellings": [] + }], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-3:14|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc new file mode 100644 index 000000000..f4ccb8825 --- /dev/null +++ b/index_tests/function_definition.cc @@ -0,0 +1,27 @@ +void foo() {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-1:14|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc new file mode 100644 index 000000000..f4e214c9e --- /dev/null +++ b/index_tests/inheritance/class_inherit.cc @@ -0,0 +1,45 @@ +class Parent {}; +class Derived : public Parent {}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 3866412049634585509, + "detailed_name": "Parent", + "short_name": "Parent", + "kind": 5, + "declarations": ["2:24-2:30|-1|1|4"], + "spell": "1:7-1:13|-1|1|2", + "extent": "1:1-1:16|-1|1|0", + "bases": [], + "derived": [1], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:24-2:30|-1|1|4"] + }, { + "id": 1, + "usr": 10963370434658308541, + "detailed_name": "Derived", + "short_name": "Derived", + "kind": 5, + "declarations": [], + "spell": "2:7-2:14|-1|1|2", + "extent": "2:1-2:33|-1|1|0", + "bases": [0], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc new file mode 100644 index 000000000..1b1bda9d1 --- /dev/null +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -0,0 +1,146 @@ +template +class Base1 {}; + +template +class Base2 {}; + +template +class Derived1 : Base1 {}; + +template +class Derived2 : Base2 {}; + +class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11930058224338108382, + "detailed_name": "Base1", + "short_name": "Base1", + "kind": 5, + "declarations": ["8:18-8:23|-1|1|4", "13:17-13:22|-1|1|4"], + "spell": "2:7-2:12|-1|1|2", + "extent": "2:1-2:15|-1|1|0", + "bases": [], + "derived": [2, 6], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["8:18-8:23|-1|1|4", "13:17-13:22|-1|1|4"] + }, { + "id": 1, + "usr": 11118288764693061434, + "detailed_name": "Base2", + "short_name": "Base2", + "kind": 5, + "declarations": ["11:18-11:23|-1|1|4", "13:27-13:32|-1|1|4"], + "spell": "5:7-5:12|-1|1|2", + "extent": "5:1-5:15|-1|1|0", + "bases": [], + "derived": [4, 6], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["11:18-11:23|-1|1|4", "13:27-13:32|-1|1|4"] + }, { + "id": 2, + "usr": 5863733211528032190, + "detailed_name": "Derived1", + "short_name": "Derived1", + "kind": 5, + "declarations": ["13:43-13:51|-1|1|4"], + "spell": "8:7-8:15|-1|1|2", + "extent": "8:1-8:29|-1|1|0", + "bases": [0], + "derived": [6], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["13:43-13:51|-1|1|4"] + }, { + "id": 3, + "usr": 9, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }, { + "id": 4, + "usr": 10651399730831737929, + "detailed_name": "Derived2", + "short_name": "Derived2", + "kind": 5, + "declarations": ["13:56-13:64|-1|1|4"], + "spell": "11:7-11:15|-1|1|2", + "extent": "11:1-11:29|-1|1|0", + "bases": [1], + "derived": [6], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["13:56-13:64|-1|1|4"] + }, { + "id": 5, + "usr": 780719166805015998, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "10:19-10:20|-1|1|2", + "extent": "10:10-10:20|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["11:24-11:25|-1|1|4"] + }, { + "id": 6, + "usr": 10963370434658308541, + "detailed_name": "Derived", + "short_name": "Derived", + "kind": 5, + "declarations": ["13:33-13:40|-1|1|4", "13:65-13:72|-1|1|4"], + "spell": "13:7-13:14|-1|1|2", + "extent": "13:1-13:76|-1|1|0", + "bases": [0, 1, 2, 4], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["13:33-13:40|-1|1|4", "13:65-13:72|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 3880651725784125791, + "detailed_name": "unsigned int T", + "short_name": "T", + "declarations": [], + "spell": "7:23-7:24|-1|1|2", + "extent": "7:10-7:24|-1|1|0", + "type": 3, + "uses": ["8:24-8:25|-1|1|4"], + "kind": 26, + "storage": 0 + }] +} +*/ diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc new file mode 100644 index 000000000..785a1bf95 --- /dev/null +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -0,0 +1,79 @@ +class Root {}; +class MiddleA : public Root {}; +class MiddleB : public Root {}; +class Derived : public MiddleA, public MiddleB {}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 3897841498936210886, + "detailed_name": "Root", + "short_name": "Root", + "kind": 5, + "declarations": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"], + "spell": "1:7-1:11|-1|1|2", + "extent": "1:1-1:14|-1|1|0", + "bases": [], + "derived": [1, 2], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"] + }, { + "id": 1, + "usr": 11863524815063131483, + "detailed_name": "MiddleA", + "short_name": "MiddleA", + "kind": 5, + "declarations": ["4:24-4:31|-1|1|4"], + "spell": "2:7-2:14|-1|1|2", + "extent": "2:1-2:31|-1|1|0", + "bases": [0], + "derived": [3], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:24-4:31|-1|1|4"] + }, { + "id": 2, + "usr": 14022569716337624303, + "detailed_name": "MiddleB", + "short_name": "MiddleB", + "kind": 5, + "declarations": ["4:40-4:47|-1|1|4"], + "spell": "3:7-3:14|-1|1|2", + "extent": "3:1-3:31|-1|1|0", + "bases": [0], + "derived": [3], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:40-4:47|-1|1|4"] + }, { + "id": 3, + "usr": 10963370434658308541, + "detailed_name": "Derived", + "short_name": "Derived", + "kind": 5, + "declarations": [], + "spell": "4:7-4:14|-1|1|2", + "extent": "4:1-4:50|-1|1|0", + "bases": [1, 2], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc new file mode 100644 index 000000000..36b5d32d7 --- /dev/null +++ b/index_tests/inheritance/function_override.cc @@ -0,0 +1,82 @@ +class Root { + virtual void foo(); +}; +class Derived : public Root { + void foo() override {} +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 3897841498936210886, + "detailed_name": "Root", + "short_name": "Root", + "kind": 5, + "declarations": ["4:24-4:28|-1|1|4"], + "spell": "1:7-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [1], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["4:24-4:28|-1|1|4"] + }, { + "id": 1, + "usr": 10963370434658308541, + "detailed_name": "Derived", + "short_name": "Derived", + "kind": 5, + "declarations": [], + "spell": "4:7-4:14|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [0], + "derived": [], + "types": [], + "funcs": [1], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 9948027785633571339, + "detailed_name": "void Root::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:16-2:19|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [1], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 6666242542855173890, + "detailed_name": "void Derived::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "5:8-5:11|1|2|2", + "extent": "5:3-5:25|1|2|0", + "declaring_type": 1, + "bases": [0], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc new file mode 100644 index 000000000..69251384d --- /dev/null +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -0,0 +1,47 @@ +class IFoo { + virtual void foo() = 0; +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 9949214233977131946, + "detailed_name": "IFoo", + "short_name": "IFoo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 3277829753446788562, + "detailed_name": "void IFoo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:16-2:19|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc new file mode 100644 index 000000000..6550bb37d --- /dev/null +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -0,0 +1,116 @@ +struct Base0 { + virtual ~Base0() { } +}; +struct Base1 { + virtual ~Base1() { } +}; +struct Derived : Base0, Base1 { + ~Derived() override { } +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11628904180681204356, + "detailed_name": "Base0", + "short_name": "Base0", + "kind": 23, + "declarations": ["2:12-2:17|-1|1|4", "7:18-7:23|-1|1|4"], + "spell": "1:8-1:13|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [2], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["7:18-7:23|-1|1|4"] + }, { + "id": 1, + "usr": 15826803741381445676, + "detailed_name": "Base1", + "short_name": "Base1", + "kind": 23, + "declarations": ["5:12-5:17|-1|1|4", "7:25-7:30|-1|1|4"], + "spell": "4:8-4:13|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [], + "derived": [2], + "types": [], + "funcs": [1], + "vars": [], + "instances": [], + "uses": ["7:25-7:30|-1|1|4"] + }, { + "id": 2, + "usr": 10963370434658308541, + "detailed_name": "Derived", + "short_name": "Derived", + "kind": 23, + "declarations": ["8:4-8:11|-1|1|4"], + "spell": "7:8-7:15|-1|1|2", + "extent": "7:1-9:2|-1|1|0", + "bases": [0, 1], + "derived": [], + "types": [], + "funcs": [2], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 16347272523198263017, + "detailed_name": "void Base0::~Base0() noexcept", + "short_name": "~Base0", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "2:11-2:17|0|2|2", + "extent": "2:3-2:23|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [2], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 8401779086123965305, + "detailed_name": "void Base1::~Base1() noexcept", + "short_name": "~Base1", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "5:11-5:17|1|2|2", + "extent": "5:3-5:23|1|2|0", + "declaring_type": 1, + "bases": [], + "derived": [2], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 13164726294460837993, + "detailed_name": "void Derived::~Derived() noexcept", + "short_name": "~Derived", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "8:3-8:11|2|2|2", + "extent": "8:3-8:26|2|2|0", + "declaring_type": 2, + "bases": [0, 1], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ \ No newline at end of file diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc new file mode 100644 index 000000000..2bc4d60f4 --- /dev/null +++ b/index_tests/lambdas/lambda.cc @@ -0,0 +1,115 @@ +void foo() { + int x; + + auto dosomething = [&x](int y) { + ++x; + ++y; + }; + + dosomething(1); + dosomething(1); + dosomething(1); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 2], + "uses": [] + }, { + "id": 1, + "usr": 1287417953265234030, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-12:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"] + }, { + "id": 1, + "usr": 1328781044864682611, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["9:14-9:15|0|3|32", "10:14-10:15|0|3|32", "11:14-11:15|0|3|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 17270098654620601683, + "detailed_name": "int x", + "short_name": "x", + "declarations": [], + "spell": "2:7-2:8|0|3|2", + "extent": "2:3-2:8|0|3|0", + "type": 0, + "uses": ["5:7-5:8|-1|1|4", "4:24-4:25|0|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 16806544259835773270, + "detailed_name": "lambda dosomething", + "short_name": "dosomething", + "declarations": [], + "spell": "4:8-4:19|0|3|2", + "extent": "4:3-7:4|0|3|0", + "type": 1, + "uses": ["9:3-9:14|0|3|4", "10:3-10:14|0|3|4", "11:3-11:14|0|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 2034725908368218782, + "detailed_name": "int y", + "short_name": "y", + "declarations": [], + "spell": "4:31-4:32|0|3|2", + "extent": "4:27-4:32|0|3|0", + "type": 0, + "uses": ["6:7-6:8|0|3|4"], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc new file mode 100644 index 000000000..827a67e1f --- /dev/null +++ b/index_tests/macros/complex.cc @@ -0,0 +1,95 @@ +#define FOO(aaa, bbb) \ + int a();\ + int a() { return aaa + bbb; } + + +int make1() { + return 3; +} +const int make2 = 5; + + +FOO(make1(), make2); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 14400399977994209582, + "detailed_name": "int make1()", + "short_name": "make1", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "6:5-6:10|-1|1|2", + "extent": "6:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["12:5-12:10|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 9720930732776154610, + "detailed_name": "int a()", + "short_name": "a", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "12:1-12:20|-1|1|1", + "param_spellings": [] + }], + "spell": "12:1-12:20|-1|1|2", + "extent": "12:1-12:20|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["12:5-12:10|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 2878407290385495202, + "detailed_name": "const int make2", + "short_name": "make2", + "hover": "const int make2 = 5", + "declarations": [], + "spell": "9:11-9:16|-1|1|2", + "extent": "9:1-9:20|-1|1|0", + "type": 0, + "uses": ["12:14-12:19|1|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 4261071340275951718, + "detailed_name": "FOO", + "short_name": "FOO", + "hover": "#define FOO(aaa, bbb)\n int a();\n int a() { return aaa + bbb; }", + "declarations": [], + "spell": "1:9-1:12|-1|1|2", + "extent": "1:9-3:32|-1|1|0", + "uses": ["12:1-12:4|-1|1|4"], + "kind": 255, + "storage": 0 + }] +} +*/ \ No newline at end of file diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc new file mode 100644 index 000000000..6dbe14661 --- /dev/null +++ b/index_tests/macros/foo.cc @@ -0,0 +1,102 @@ +#define A 5 +#define DISALLOW(type) type(type&&) = delete; + +struct Foo { + DISALLOW(Foo); +}; + +int x = A; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["5:12-5:15|-1|1|4"], + "spell": "4:8-4:11|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["5:12-5:15|0|2|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 13788753348312146871, + "detailed_name": "void Foo::Foo(Foo &&)", + "short_name": "Foo", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "5:12-5:15|0|2|2", + "extent": "5:12-5:16|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 10677751717622394455, + "detailed_name": "int x", + "short_name": "x", + "hover": "int x = A", + "declarations": [], + "spell": "8:5-8:6|-1|1|2", + "extent": "8:1-8:10|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 7651988378939587454, + "detailed_name": "A", + "short_name": "A", + "hover": "#define A 5", + "declarations": [], + "spell": "1:9-1:10|-1|1|2", + "extent": "1:9-1:12|-1|1|0", + "uses": ["8:9-8:10|-1|1|4"], + "kind": 255, + "storage": 0 + }, { + "id": 2, + "usr": 14946041066794678724, + "detailed_name": "DISALLOW", + "short_name": "DISALLOW", + "hover": "#define DISALLOW(type) type(type&&) = delete;", + "declarations": [], + "spell": "2:9-2:17|-1|1|2", + "extent": "2:9-2:46|-1|1|0", + "uses": ["5:3-5:11|-1|1|4"], + "kind": 255, + "storage": 0 + }] +} +*/ diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc new file mode 100644 index 000000000..1b2698dd4 --- /dev/null +++ b/index_tests/method_declaration.cc @@ -0,0 +1,51 @@ +class Foo { + void foo(); +}; + +/* +// NOTE: Lack of declaring_type in functions and funcs in Foo is okay, because +// those are processed when we find the definition for Foo::foo. Pure +// virtuals are treated specially and get added to the type immediately. + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17922201480358737771, + "detailed_name": "void Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:11|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc new file mode 100644 index 000000000..8da4a2afe --- /dev/null +++ b/index_tests/method_definition.cc @@ -0,0 +1,51 @@ +class Foo { + void foo() const; +}; + +void Foo::foo() const {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["5:6-5:9|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 6446764306530590711, + "detailed_name": "void Foo::foo() const", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:11|0|2|1", + "param_spellings": [] + }], + "spell": "5:11-5:14|0|2|2", + "extent": "5:1-5:25|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc new file mode 100644 index 000000000..85cfb39cb --- /dev/null +++ b/index_tests/method_inline_declaration.cc @@ -0,0 +1,46 @@ +class Foo { + void foo() {} +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17922201480358737771, + "detailed_name": "void Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "2:8-2:11|0|2|2", + "extent": "2:3-2:16|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc new file mode 100644 index 000000000..d445744fa --- /dev/null +++ b/index_tests/multi_file/funky_enum.cc @@ -0,0 +1,97 @@ +enum Foo { +#include "funky_enum.h" +}; + +/* +// TODO: In the future try to have better support for types defined across +// multiple files. + +OUTPUT: funky_enum.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 439339022761937396, + "detailed_name": "Foo::A", + "short_name": "A", + "hover": "Foo::A = 0", + "declarations": [], + "spell": "4:1-4:2|0|2|2", + "extent": "4:1-4:2|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "short_name": "B", + "hover": "Foo::B = 1", + "declarations": [], + "spell": "5:1-5:2|0|2|2", + "extent": "5:1-5:2|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 2, + "usr": 8524995777615948802, + "detailed_name": "Foo::C", + "short_name": "C", + "hover": "Foo::C = 2", + "declarations": [], + "spell": "6:1-6:2|0|2|2", + "extent": "6:1-6:2|0|2|0", + "type": 0, + "uses": [], + "kind": 22, + "storage": 0 + }] +} +OUTPUT: funky_enum.cc +{ + "includes": [{ + "line": 1, + "resolved_path": "&funky_enum.h" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 16985894625255407295, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 10, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [] +} +*/ \ No newline at end of file diff --git a/index_tests/multi_file/funky_enum.h b/index_tests/multi_file/funky_enum.h new file mode 100644 index 000000000..b11cc4419 --- /dev/null +++ b/index_tests/multi_file/funky_enum.h @@ -0,0 +1,6 @@ +// This file cannot be built directory. It is included in an enum definition of +// another file. + +A, +B, +C \ No newline at end of file diff --git a/index_tests/multi_file/header.h b/index_tests/multi_file/header.h new file mode 100644 index 000000000..717ef8213 --- /dev/null +++ b/index_tests/multi_file/header.h @@ -0,0 +1,18 @@ +#pragma once + +struct Base {}; + +struct SameFileDerived : Base {}; + +using Foo0 = SameFileDerived; + +template +void Foo1() {} + +template +struct Foo2 {}; + +enum Foo3 { A, B, C }; + +int Foo4; +static int Foo5; \ No newline at end of file diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc new file mode 100644 index 000000000..1e3fb85cf --- /dev/null +++ b/index_tests/multi_file/impl.cc @@ -0,0 +1,229 @@ +#include "header.h" + +void Impl() { + Foo1(); +} + +/* +OUTPUT: header.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 8420119006782424779, + "detailed_name": "Base", + "short_name": "Base", + "kind": 23, + "declarations": ["5:26-5:30|-1|1|4"], + "spell": "3:8-3:12|-1|1|2", + "extent": "3:1-3:15|-1|1|0", + "bases": [], + "derived": [1], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:26-5:30|-1|1|4"] + }, { + "id": 1, + "usr": 16750616846959666305, + "detailed_name": "SameFileDerived", + "short_name": "SameFileDerived", + "kind": 23, + "declarations": [], + "spell": "5:8-5:23|-1|1|2", + "extent": "5:1-5:33|-1|1|0", + "bases": [0], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:14-7:29|-1|1|4"] + }, { + "id": 2, + "usr": 619345544228965342, + "detailed_name": "Foo0", + "short_name": "Foo0", + "kind": 252, + "hover": "using Foo0 = SameFileDerived", + "declarations": [], + "spell": "7:7-7:11|-1|1|2", + "extent": "7:1-7:29|-1|1|0", + "alias_of": 1, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:7-7:11|-1|1|4"] + }, { + "id": 3, + "usr": 529393482671181129, + "detailed_name": "Foo2", + "short_name": "Foo2", + "kind": 5, + "declarations": [], + "spell": "13:8-13:12|-1|1|2", + "extent": "13:1-13:15|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 4, + "usr": 4481210672785600703, + "detailed_name": "Foo3", + "short_name": "Foo3", + "kind": 10, + "declarations": [], + "spell": "15:6-15:10|-1|1|2", + "extent": "15:1-15:22|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 5, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [3, 4], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 11650481237659640387, + "detailed_name": "void Foo1()", + "short_name": "Foo1", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "10:6-10:10|-1|1|2", + "extent": "10:1-10:15|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 6141718166919284735, + "detailed_name": "Foo3::A", + "short_name": "A", + "hover": "Foo3::A = 0", + "declarations": [], + "spell": "15:13-15:14|4|2|2", + "extent": "15:13-15:14|4|2|0", + "type": 4, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 1, + "usr": 17716334512218775320, + "detailed_name": "Foo3::B", + "short_name": "B", + "hover": "Foo3::B = 1", + "declarations": [], + "spell": "15:16-15:17|4|2|2", + "extent": "15:16-15:17|4|2|0", + "type": 4, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 2, + "usr": 7285646116511901840, + "detailed_name": "Foo3::C", + "short_name": "C", + "hover": "Foo3::C = 2", + "declarations": [], + "spell": "15:19-15:20|4|2|2", + "extent": "15:19-15:20|4|2|0", + "type": 4, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 3, + "usr": 2638219001294786365, + "detailed_name": "int Foo4", + "short_name": "Foo4", + "declarations": [], + "spell": "17:5-17:9|-1|1|2", + "extent": "17:1-17:9|-1|1|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 4, + "usr": 8395885290297540138, + "detailed_name": "int Foo5", + "short_name": "Foo5", + "declarations": [], + "spell": "18:12-18:16|-1|1|2", + "extent": "18:1-18:16|-1|1|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 3 + }] +} +OUTPUT: impl.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&header.h" + }], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 5817708529036841195, + "detailed_name": "void Impl()", + "short_name": "Impl", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:10|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["4:3-4:7|1|3|32"] + }, { + "id": 1, + "usr": 11650481237659640387, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["4:3-4:7|0|3|32"], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/multi_file/simple_header.h b/index_tests/multi_file/simple_header.h new file mode 100644 index 000000000..3bdf008ae --- /dev/null +++ b/index_tests/multi_file/simple_header.h @@ -0,0 +1,3 @@ +#pragma once + +void header(); \ No newline at end of file diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc new file mode 100644 index 000000000..d322603a4 --- /dev/null +++ b/index_tests/multi_file/simple_impl.cc @@ -0,0 +1,71 @@ +#include "simple_header.h" + +void impl() { + header(); +} + +/* +OUTPUT: simple_header.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 16236105532929924676, + "detailed_name": "void header()", + "short_name": "header", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "3:6-3:12|-1|1|1", + "param_spellings": [] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +OUTPUT: simple_impl.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&simple_header.h" + }], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 3373269392705484958, + "detailed_name": "void impl()", + "short_name": "impl", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:10|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["4:3-4:9|1|3|32"] + }, { + "id": 1, + "usr": 16236105532929924676, + "detailed_name": "", + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": ["4:3-4:9|0|3|32"], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc new file mode 100644 index 000000000..8ad0f72de --- /dev/null +++ b/index_tests/multi_file/static.cc @@ -0,0 +1,88 @@ +#include "static.h" + +void Buffer::CreateSharedBuffer() {} + +/* +OUTPUT: static.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 9411323049603567600, + "detailed_name": "Buffer", + "short_name": "Buffer", + "kind": 23, + "declarations": [], + "spell": "3:8-3:14|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 14576076421851654759, + "detailed_name": "void Buffer::CreateSharedBuffer()", + "short_name": "CreateSharedBuffer", + "kind": 254, + "storage": 3, + "declarations": [{ + "spell": "4:15-4:33|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +OUTPUT: static.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&static.h" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 9411323049603567600, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["3:6-3:12|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 14576076421851654759, + "detailed_name": "void Buffer::CreateSharedBuffer()", + "short_name": "CreateSharedBuffer", + "kind": 254, + "storage": 1, + "declarations": [], + "spell": "3:14-3:32|0|2|2", + "extent": "3:1-3:37|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ \ No newline at end of file diff --git a/index_tests/multi_file/static.h b/index_tests/multi_file/static.h new file mode 100644 index 000000000..4204f7859 --- /dev/null +++ b/index_tests/multi_file/static.h @@ -0,0 +1,5 @@ +#pragma once + +struct Buffer { + static void CreateSharedBuffer(); +}; diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc new file mode 100644 index 000000000..17905fe29 --- /dev/null +++ b/index_tests/namespaces/anonymous_function.cc @@ -0,0 +1,45 @@ +namespace { +void foo(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 7144845543074395457, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 5010253035933134245, + "detailed_name": "void (anon)::foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "2:6-2:9|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc new file mode 100644 index 000000000..7c6ba361d --- /dev/null +++ b/index_tests/namespaces/function_declaration.cc @@ -0,0 +1,61 @@ +namespace hello { +void foo(int a, int b); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 2029211996748007610, + "detailed_name": "hello", + "short_name": "hello", + "kind": 3, + "declarations": [], + "spell": "1:11-1:16|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["1:11-1:16|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 18343102288837190527, + "detailed_name": "void hello::foo(int a, int b)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "2:6-2:9|0|2|1", + "param_spellings": ["2:14-2:15", "2:21-2:22"] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc new file mode 100644 index 000000000..5ccd8254f --- /dev/null +++ b/index_tests/namespaces/function_definition.cc @@ -0,0 +1,60 @@ +namespace hello { +void foo() {} +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 2029211996748007610, + "detailed_name": "hello", + "short_name": "hello", + "kind": 3, + "declarations": [], + "spell": "1:11-1:16|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["1:11-1:16|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 243328841292951622, + "detailed_name": "void hello::foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "2:6-2:9|0|2|2", + "extent": "2:1-2:14|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc new file mode 100644 index 000000000..37687fd38 --- /dev/null +++ b/index_tests/namespaces/method_declaration.cc @@ -0,0 +1,79 @@ +namespace hello { +class Foo { + void foo(); +}; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 2029211996748007610, + "detailed_name": "hello", + "short_name": "hello", + "kind": 3, + "declarations": [], + "spell": "1:11-1:16|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:11-1:16|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 4508214972876735896, + "detailed_name": "hello::Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:7-2:10|0|2|2", + "extent": "2:1-4:2|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "3:8-3:11|2|2|1", + "param_spellings": [] + }], + "declaring_type": 2, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc new file mode 100644 index 000000000..4df6edf13 --- /dev/null +++ b/index_tests/namespaces/method_definition.cc @@ -0,0 +1,83 @@ +namespace hello { +class Foo { + void foo(); +}; + +void Foo::foo() {} +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 2029211996748007610, + "detailed_name": "hello", + "short_name": "hello", + "kind": 3, + "declarations": [], + "spell": "1:11-1:16|-1|1|2", + "extent": "1:1-7:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:11-1:16|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 4508214972876735896, + "detailed_name": "hello::Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:7-2:10|0|2|2", + "extent": "2:1-4:2|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["6:6-6:9|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "3:8-3:11|2|2|1", + "param_spellings": [] + }], + "spell": "6:11-6:14|2|2|2", + "extent": "6:1-6:19|0|2|0", + "declaring_type": 2, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc new file mode 100644 index 000000000..9d0b940fc --- /dev/null +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -0,0 +1,78 @@ +namespace hello { +class Foo { + void foo() {} +}; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 2029211996748007610, + "detailed_name": "hello", + "short_name": "hello", + "kind": 3, + "declarations": [], + "spell": "1:11-1:16|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:11-1:16|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 4508214972876735896, + "detailed_name": "hello::Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:7-2:10|0|2|2", + "extent": "2:1-4:2|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "3:8-3:11|2|2|2", + "extent": "3:3-3:16|2|2|0", + "declaring_type": 2, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc new file mode 100644 index 000000000..9a92b8081 --- /dev/null +++ b/index_tests/namespaces/namespace_alias.cc @@ -0,0 +1,171 @@ +namespace foo { + namespace bar { + namespace baz { + int qux = 42; + } + } +} + +namespace fbz = foo::bar::baz; + +void func() { + int a = foo::bar::baz::qux; + int b = fbz::qux; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 926793467007732869, + "detailed_name": "foo", + "short_name": "foo", + "kind": 3, + "declarations": [], + "spell": "1:11-1:14|-1|1|2", + "extent": "1:1-7:2|-1|1|0", + "bases": [1], + "derived": [2], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:11-1:14|-1|1|4", "9:17-9:20|-1|1|4", "12:11-12:14|0|3|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 17805385787823406700, + "detailed_name": "foo::bar", + "short_name": "bar", + "kind": 3, + "declarations": [], + "spell": "2:15-2:18|0|2|2", + "extent": "2:5-6:6|0|2|0", + "bases": [0], + "derived": [3], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:15-2:18|0|2|4", "9:22-9:25|-1|1|4", "12:16-12:19|0|3|4"] + }, { + "id": 3, + "usr": 14450849931009540802, + "detailed_name": "foo::bar::baz", + "short_name": "baz", + "kind": 3, + "declarations": [], + "spell": "3:20-3:23|2|2|2", + "extent": "3:10-5:11|2|2|0", + "bases": [2], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": ["3:20-3:23|2|2|4", "9:27-9:30|-1|1|4", "12:21-12:24|0|3|4"] + }, { + "id": 4, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2], + "uses": [] + }, { + "id": 5, + "usr": 11879713791858506216, + "detailed_name": "fbz", + "short_name": "fbz", + "kind": 0, + "declarations": [], + "spell": "9:11-9:14|-1|1|2", + "extent": "9:1-9:30|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["13:11-13:14|0|3|4"] + }], + "funcs": [{ + "id": 0, + "usr": 10818727483146447186, + "detailed_name": "void func()", + "short_name": "func", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "11:6-11:10|-1|1|2", + "extent": "11:1-14:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [1, 2], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 15042442838933090518, + "detailed_name": "int foo::bar::baz::qux", + "short_name": "qux", + "hover": "int foo::bar::baz::qux = 42", + "declarations": [], + "spell": "4:18-4:21|3|2|2", + "extent": "4:14-4:26|3|2|0", + "type": 4, + "uses": ["12:26-12:29|-1|1|4", "13:16-13:19|-1|1|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 107714981785063096, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = foo::bar::baz::qux", + "declarations": [], + "spell": "12:7-12:8|0|3|2", + "extent": "12:3-12:29|0|3|0", + "type": 4, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 1200087780658383286, + "detailed_name": "int b", + "short_name": "b", + "hover": "int b = fbz::qux", + "declarations": [], + "spell": "13:7-13:8|0|3|2", + "extent": "13:3-13:19|0|3|0", + "type": 4, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc new file mode 100644 index 000000000..235ebaeeb --- /dev/null +++ b/index_tests/namespaces/namespace_reference.cc @@ -0,0 +1,123 @@ +namespace ns { + int Foo; + void Accept(int a) {} +} + +void Runner() { + ns::Accept(ns::Foo); + using namespace ns; + Accept(Foo); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [0], + "vars": [0], + "instances": [], + "uses": ["1:11-1:13|-1|1|4", "7:3-7:5|1|3|4", "7:14-7:16|1|3|4", "8:19-8:21|1|3|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17328473273923617489, + "detailed_name": "void ns::Accept(int a)", + "short_name": "Accept", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:8-3:14|0|2|2", + "extent": "3:3-3:24|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [1], + "uses": ["7:7-7:13|1|3|32", "9:3-9:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 631910859630953711, + "detailed_name": "void Runner()", + "short_name": "Runner", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "6:6-6:12|-1|1|2", + "extent": "6:1-10:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["7:7-7:13|0|3|32", "9:3-9:9|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 12898699035586282159, + "detailed_name": "int ns::Foo", + "short_name": "Foo", + "declarations": [], + "spell": "2:7-2:10|0|2|2", + "extent": "2:3-2:10|0|2|0", + "type": 2, + "uses": ["7:18-7:21|1|3|4", "9:10-9:13|1|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 7976909968919750794, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "3:19-3:20|0|3|2", + "extent": "3:15-3:20|0|3|0", + "type": 2, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ + + + diff --git a/index_tests/objective-c/class.m b/index_tests/objective-c/class.m new file mode 100644 index 000000000..4736cadef --- /dev/null +++ b/index_tests/objective-c/class.m @@ -0,0 +1,184 @@ +@interface AClass + + (void)test; + - (void)anInstanceMethod; + @property (nonatomic) int aProp; +@end + +@implementation AClass ++ (void)test {} +- (void)anInstanceMethod {} +@end + +int main(void) +{ + AClass *instance = [AClass init]; + [instance anInstanceMethod]; + instance.aProp = 12; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11832280568361305387, + "detailed_name": "AClass", + "short_name": "AClass", + "kind": 7, + "spell": "7:17-7:23|-1|1|2", + "extent": "7:1-10:2|-1|1|0", + "parents": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["14:3-14:9|-1|1|4", "14:23-14:29|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "parents": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 12775970426728664910, + "detailed_name": "AClass::test", + "short_name": "test", + "kind": 17, + "storage": 0, + "declarations": [{ + "spelling": "2:11-2:15", + "extent": "2:3-2:16", + "content": "+ (void)test;", + "param_spellings": [] + }], + "spell": "8:9-8:13|-1|1|2", + "extent": "8:1-8:16|-1|1|0", + "base": [], + "derived": [], + "locals": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 4096877434426330804, + "detailed_name": "AClass::anInstanceMethod", + "short_name": "anInstanceMethod", + "kind": 16, + "storage": 0, + "declarations": [{ + "spelling": "3:11-3:27", + "extent": "3:3-3:28", + "content": "- (void)anInstanceMethod;", + "param_spellings": [] + }], + "spell": "9:9-9:25|-1|1|2", + "extent": "9:1-9:28|-1|1|0", + "base": [], + "derived": [], + "locals": [], + "uses": ["15:13-15:29|4|3|64"], + "callees": [] + }, { + "id": 2, + "usr": 12774569141855220778, + "detailed_name": "AClass::aProp", + "short_name": "aProp", + "kind": 16, + "storage": 0, + "declarations": [{ + "spelling": "0:0-0:0", + "extent": "4:29-4:34", + "content": "aProp", + "param_spellings": [] + }], + "extent": "4:29-4:34|-1|1|0", + "base": [], + "derived": [], + "locals": [], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 17992064398538597892, + "detailed_name": "AClass::setAProp:", + "short_name": "setAProp:", + "kind": 16, + "storage": 0, + "declarations": [{ + "spelling": "0:0-0:0", + "extent": "4:29-4:34", + "content": "aProp", + "param_spellings": ["4:29-4:34"] + }], + "extent": "4:29-4:34|-1|1|0", + "base": [], + "derived": [], + "locals": [], + "uses": ["0:0-0:0|4|3|64"], + "callees": [] + }, { + "id": 4, + "usr": 7033269674615638282, + "detailed_name": "int main()", + "short_name": "main", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "12:5-12:9|-1|1|2", + "extent": "12:1-17:2|-1|1|0", + "base": [], + "derived": [], + "locals": [], + "uses": [], + "callees": ["15:13-15:29|1|3|64", "0:0-0:0|3|3|64"] + }], + "vars": [{ + "id": 0, + "usr": 14842397373703114213, + "detailed_name": "int AClass::aProp", + "short_name": "aProp", + "declarations": ["4:29-4:34|-1|1|1"], + "type": 1, + "uses": ["16:12-16:17|4|3|4"], + "kind": 19, + "storage": 0 + }, { + "id": 1, + "usr": 17112602610366149042, + "detailed_name": "int AClass::_aProp", + "short_name": "_aProp", + "declarations": [], + "spell": "4:29-4:34|-1|1|2", + "extent": "4:29-4:34|-1|1|0", + "type": 1, + "uses": [], + "kind": 14, + "storage": 0 + }, { + "id": 2, + "usr": 6849095699869081177, + "detailed_name": "AClass *instance", + "short_name": "instance", + "hover": "AClass *instance = [AClass init]", + "declarations": [], + "spell": "14:11-14:19|4|3|2", + "extent": "14:3-14:35|4|3|2", + "type": 0, + "uses": ["15:4-15:12|4|3|4", "16:3-16:11|4|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc new file mode 100644 index 000000000..dc8151b0f --- /dev/null +++ b/index_tests/operators/operator.cc @@ -0,0 +1,100 @@ +class Foo { + void operator()(int) { } + void operator()(bool); + int operator()(int a, int b); +}; + +Foo &operator += (const Foo&, const int&); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0, 1, 2], + "vars": [], + "instances": [], + "uses": ["7:1-7:4|-1|1|4", "7:25-7:28|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 7874436189163837815, + "detailed_name": "void Foo::operator()(int)", + "short_name": "operator()", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "2:8-2:18|0|2|2", + "extent": "2:3-2:27|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 3545323327609582678, + "detailed_name": "void Foo::operator()(bool)", + "short_name": "operator()", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "3:8-3:18|0|2|1", + "param_spellings": ["3:23-3:23"] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 3986818119971932909, + "detailed_name": "int Foo::operator()(int a, int b)", + "short_name": "operator()", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "4:7-4:17|0|2|1", + "param_spellings": ["4:22-4:23", "4:29-4:30"] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 8288368475529136092, + "detailed_name": "Foo &operator+=(const Foo &, const int &)", + "short_name": "operator+=", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "7:6-7:17|-1|1|1", + "param_spellings": ["7:29-7:29", "7:41-7:41"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/outline/outline.cc b/index_tests/outline/outline.cc new file mode 100644 index 000000000..08b07313e --- /dev/null +++ b/index_tests/outline/outline.cc @@ -0,0 +1,120 @@ +#include + +struct MergeableUpdate { + int a; + int b; + std::vector to_add; +}; + +/* +TEXT_REPLACE: +std::__1::vector <===> std::vector +c:@N@std@ST>2#T#T@vector <===> c:@N@std@N@__1@ST>2#T#T@vector +10956461108384510180 <===> 9178760565669096175 + +OUTPUT: +{ + "includes": [{ + "line": 0, + "resolved_path": "&vector" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 14399919566014425846, + "detailed_name": "MergeableUpdate", + "short_name": "MergeableUpdate", + "kind": 23, + "declarations": [], + "spell": "3:8-3:23|-1|1|2", + "extent": "3:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1, 2], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }, { + "id": 2, + "usr": 9178760565669096175, + "detailed_name": "std::vector", + "short_name": "vector", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["6:8-6:14|-1|1|4"] + }, { + "id": 3, + "usr": 5401847601697785946, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:3-6:6|0|2|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 11633578660978286467, + "detailed_name": "int MergeableUpdate::a", + "short_name": "a", + "declarations": [], + "spell": "4:7-4:8|0|2|2", + "extent": "4:3-4:8|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 14949552147532317793, + "detailed_name": "int MergeableUpdate::b", + "short_name": "b", + "declarations": [], + "spell": "5:7-5:8|0|2|2", + "extent": "5:3-5:8|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 9003350345237582363, + "detailed_name": "std::vector MergeableUpdate::to_add", + "short_name": "to_add", + "declarations": [], + "spell": "6:20-6:26|0|2|2", + "extent": "6:3-6:26|0|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/outline/outline2.cc b/index_tests/outline/outline2.cc new file mode 100644 index 000000000..c5a318615 --- /dev/null +++ b/index_tests/outline/outline2.cc @@ -0,0 +1,158 @@ +//#pragma once + +#include +#include + +struct CompilationEntry { + std::string directory; + std::string filename; + std::vector args; +}; + +std::vector LoadCompilationEntriesFromDirectory(const std::string& project_directory); + +/* +TEXT_REPLACE: +std::__1::vector <===> std::vector +std::__1::string <===> std::string +std::__cxx11::string <===> std::string +c:@N@std@string <===> c:@N@std@N@__1@T@string +c:@N@std@T@string <===> c:@N@std@N@__1@T@string +c:@N@std@N@__cxx11@T@string <===> c:@N@std@N@__1@T@string +c:@N@std@ST>2#T#T@vector <===> c:@N@std@N@__1@ST>2#T#T@vector +c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@N@__1@S@basic_string>#C#$@N@std@N@__1@S@char_traits>#C#$@N@std@N@__1@S@allocator>#C# <===> c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# +c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@N@__cxx11@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# <===> c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# +4160338041907786 <===> 14151982074805896770 +7543170857910783654 <===> 14151982074805896770 +9802818309312685221 <===> 11244864715202245734 +7636646237071509980 <===> 14151982074805896770 +9178760565669096175 <===> 10956461108384510180 +10468929532989002392 <===> 11244864715202245734 +4160338041907786 <===> 14151982074805896770 +9802818309312685221 <===> 11244864715202245734 + +OUTPUT: +{ + "includes": [{ + "line": 2, + "resolved_path": "&string" + }, { + "line": 3, + "resolved_path": "&vector" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 4992269036372211530, + "detailed_name": "CompilationEntry", + "short_name": "CompilationEntry", + "kind": 23, + "declarations": [], + "spell": "6:8-6:24|-1|1|2", + "extent": "6:1-10:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1, 2], + "instances": [], + "uses": ["12:13-12:29|-1|1|4"] + }, { + "id": 1, + "usr": 14151982074805896770, + "detailed_name": "std::string", + "short_name": "string", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["7:8-7:14|-1|1|4", "8:8-8:14|-1|1|4", "9:20-9:26|-1|1|4", "12:78-12:84|-1|1|4"] + }, { + "id": 2, + "usr": 5401847601697785946, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:3-7:6|0|2|4", "8:3-8:6|0|2|4", "9:3-9:6|0|2|4", "9:15-9:18|0|2|4", "12:1-12:4|-1|1|4", "12:73-12:76|-1|1|4"] + }, { + "id": 3, + "usr": 10956461108384510180, + "detailed_name": "std::vector", + "short_name": "vector", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["9:8-9:14|-1|1|4", "12:6-12:12|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 11244864715202245734, + "detailed_name": "std::vector LoadCompilationEntriesFromDirectory(const std::string &project_directory)", + "short_name": "LoadCompilationEntriesFromDirectory", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "12:31-12:66|-1|1|1", + "param_spellings": ["12:86-12:103"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 1153224798516629792, + "detailed_name": "std::string CompilationEntry::directory", + "short_name": "directory", + "declarations": [], + "spell": "7:15-7:24|0|2|2", + "extent": "7:3-7:24|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 2255668374222866345, + "detailed_name": "std::string CompilationEntry::filename", + "short_name": "filename", + "declarations": [], + "spell": "8:15-8:23|0|2|2", + "extent": "8:3-8:23|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 12616880765274259414, + "detailed_name": "std::vector CompilationEntry::args", + "short_name": "args", + "declarations": [], + "spell": "9:28-9:32|0|2|2", + "extent": "9:3-9:32|0|2|0", + "type": 3, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc new file mode 100644 index 000000000..2bcf1f767 --- /dev/null +++ b/index_tests/outline/static_function_in_type.cc @@ -0,0 +1,192 @@ +#include "static_function_in_type.h" + +namespace ns { +// static +void Foo::Register(Manager* m) { +} +} + +/* +OUTPUT: static_function_in_type.h +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|-1|1|2", + "extent": "1:1-9:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:11-1:13|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 1972401196751872203, + "detailed_name": "ns::Manager", + "short_name": "Manager", + "kind": 5, + "declarations": ["3:7-3:14|0|2|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:24-6:31|-1|1|4"] + }, { + "id": 3, + "usr": 17262466801709381811, + "detailed_name": "ns::Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "5:8-5:11|0|2|2", + "extent": "5:1-7:2|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17019747379608639279, + "detailed_name": "void ns::Foo::Register(ns::Manager *)", + "short_name": "Register", + "kind": 254, + "storage": 3, + "declarations": [{ + "spell": "6:15-6:23|3|2|1", + "param_spellings": ["6:32-6:32"] + }], + "declaring_type": 3, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +OUTPUT: static_function_in_type.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&static_function_in_type.h" + }], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "3:11-3:13|-1|1|2", + "extent": "3:1-7:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["3:11-3:13|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 17262466801709381811, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["5:6-5:9|-1|1|4"] + }, { + "id": 3, + "usr": 1972401196751872203, + "detailed_name": "ns::Manager", + "short_name": "Manager", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["5:20-5:27|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 17019747379608639279, + "detailed_name": "void ns::Foo::Register(ns::Manager *m)", + "short_name": "Register", + "kind": 254, + "storage": 1, + "declarations": [], + "spell": "5:11-5:19|2|2|2", + "extent": "5:1-6:2|0|2|0", + "declaring_type": 2, + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 9285345059965948351, + "detailed_name": "ns::Manager *m", + "short_name": "m", + "declarations": [], + "spell": "5:29-5:30|0|3|2", + "extent": "5:20-5:30|0|3|0", + "type": 3, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ \ No newline at end of file diff --git a/index_tests/outline/static_function_in_type.h b/index_tests/outline/static_function_in_type.h new file mode 100644 index 000000000..013aa70e5 --- /dev/null +++ b/index_tests/outline/static_function_in_type.h @@ -0,0 +1,9 @@ +namespace ns { + +class Manager; + +struct Foo { + static void Register(Manager*); +}; + +} // namespace ns \ No newline at end of file diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc new file mode 100644 index 000000000..4ae27e172 --- /dev/null +++ b/index_tests/preprocessor/include_guard.cc @@ -0,0 +1,27 @@ +#ifndef FOO +#define FOO + +#endif + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 13076155634261037336, + "detailed_name": "FOO", + "short_name": "FOO", + "hover": "#define FOO", + "declarations": [], + "spell": "2:9-2:12|-1|1|2", + "extent": "2:9-2:12|-1|1|0", + "uses": [], + "kind": 255, + "storage": 0 + }] +} +*/ diff --git a/index_tests/preprocessor/skipped.cc b/index_tests/preprocessor/skipped.cc new file mode 100644 index 000000000..41cb3c341 --- /dev/null +++ b/index_tests/preprocessor/skipped.cc @@ -0,0 +1,25 @@ + +#ifdef FOOBAR +void hello(); +#endif + +#if false + + + +#endif + +#if defined(OS_FOO) + +#endif + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": ["2:1-4:7", "6:1-10:7", "12:1-14:7"], + "types": [], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc new file mode 100644 index 000000000..cdcb516c9 --- /dev/null +++ b/index_tests/templates/func_specialized_template_param.cc @@ -0,0 +1,70 @@ +template +class Template {}; + +struct Foo { + void Bar(Template&); +}; + +void Foo::Bar(Template&) {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17107291254533526269, + "detailed_name": "Template", + "short_name": "Template", + "kind": 5, + "declarations": [], + "spell": "2:7-2:15|-1|1|2", + "extent": "2:1-2:18|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:12-5:20|-1|1|4", "8:15-8:23|-1|1|4"] + }, { + "id": 1, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "4:8-4:11|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["8:6-8:9|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 8412238651648388423, + "detailed_name": "void Foo::Bar(Template &)", + "short_name": "Bar", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "5:8-5:11|1|2|1", + "param_spellings": ["5:29-5:29"] + }], + "spell": "8:11-8:14|1|2|2", + "extent": "8:1-8:36|-1|1|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc new file mode 100644 index 000000000..3301266f2 --- /dev/null +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -0,0 +1,155 @@ +namespace ns { + enum VarType {}; + + template + struct Holder { + static constexpr VarType static_var = (VarType)0x0; + }; + + template + const typename VarType Holder<_>::static_var; + + + int Foo = Holder::static_var; + int Foo2 = Holder::static_var; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|-1|1|2", + "extent": "1:1-15:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [1, 2], + "instances": [], + "uses": ["1:11-1:13|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 1532099849728741556, + "detailed_name": "ns::VarType", + "short_name": "VarType", + "kind": 10, + "declarations": [], + "spell": "2:8-2:15|0|2|2", + "extent": "2:3-2:18|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["6:22-6:29|-1|1|4", "6:44-6:51|-1|1|4", "10:18-10:25|-1|1|4"] + }, { + "id": 3, + "usr": 12688716854043726585, + "detailed_name": "ns::Holder", + "short_name": "Holder", + "kind": 5, + "declarations": [], + "spell": "5:10-5:16|0|2|2", + "extent": "5:3-7:4|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"] + }, { + "id": 4, + "usr": 14511917000226829276, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["10:33-10:34|-1|1|4"] + }, { + "id": 5, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1, 2], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 4731849186641714451, + "detailed_name": "const ns::VarType ns::Holder::static_var", + "short_name": "static_var", + "hover": "const ns::VarType ns::Holder::static_var = (VarType)0x0", + "declarations": ["6:30-6:40|3|2|1"], + "spell": "10:37-10:47|3|2|2", + "extent": "9:3-10:47|0|2|0", + "type": 2, + "uses": ["13:26-13:36|-1|1|4", "14:27-14:37|-1|1|4"], + "kind": 8, + "storage": 1 + }, { + "id": 1, + "usr": 12898699035586282159, + "detailed_name": "int ns::Foo", + "short_name": "Foo", + "hover": "int ns::Foo = Holder::static_var", + "declarations": [], + "spell": "13:7-13:10|0|2|2", + "extent": "13:3-13:36|0|2|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 9008550860229740818, + "detailed_name": "int ns::Foo2", + "short_name": "Foo2", + "hover": "int ns::Foo2 = Holder::static_var", + "declarations": [], + "spell": "14:7-14:11|0|2|2", + "extent": "14:3-14:37|0|2|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc new file mode 100644 index 000000000..7044a041a --- /dev/null +++ b/index_tests/templates/member_ref_in_template.cc @@ -0,0 +1,107 @@ +template +struct C { + T x; + void bar(); +}; + +template +void foo() { + C d; + d.x; // spelling range is empty, use cursor extent for range + d.bar(); // spelling range is empty, use cursor extent for range + + auto e = new C; + e->x; // `x` seems not exposed by libclang + e->bar(); // `bar` seems not exposed by libclang +} + +/* +EXTRA_FLAGS: +-fms-extensions +-fms-compatibility +-fdelayed-template-parsing + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 8402783583255987702, + "detailed_name": "C", + "short_name": "C", + "kind": 5, + "declarations": [], + "spell": "2:8-2:9|-1|1|2", + "extent": "2:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [0], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 14750650276757822712, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "1:17-1:18|-1|1|2", + "extent": "1:11-1:18|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["3:3-3:4|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 8905286151237717330, + "detailed_name": "void C::bar()", + "short_name": "bar", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "4:8-4:11|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 6875364467121018690, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:9|-1|1|2", + "extent": "8:1-8:11|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 5866801090710377175, + "detailed_name": "T C::x", + "short_name": "x", + "declarations": [], + "spell": "3:5-3:6|0|2|2", + "extent": "3:3-3:6|0|2|0", + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc new file mode 100644 index 000000000..c7e77d6e7 --- /dev/null +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -0,0 +1,125 @@ +namespace ns { + template + struct Foo { + template + static int foo() { + return 3; + } + }; + + int a = Foo::foo(); + int b = Foo::foo(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|-1|1|2", + "extent": "1:1-12:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [], + "uses": ["1:11-1:13|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 14042997404480181958, + "detailed_name": "ns::Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "3:10-3:13|0|2|2", + "extent": "3:3-8:4|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["10:11-10:14|-1|1|4", "11:11-11:14|-1|1|4"] + }, { + "id": 3, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 8221803074608342407, + "detailed_name": "int ns::Foo::foo()", + "short_name": "foo", + "kind": 254, + "storage": 3, + "declarations": [], + "spell": "5:16-5:19|2|2|2", + "extent": "5:5-7:6|2|2|0", + "declaring_type": 2, + "bases": [], + "derived": [], + "vars": [], + "uses": ["10:21-10:24|0|2|32", "11:22-11:25|0|2|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 15768138241775955040, + "detailed_name": "int ns::a", + "short_name": "a", + "hover": "int ns::a = Foo::foo()", + "declarations": [], + "spell": "10:7-10:8|0|2|2", + "extent": "10:3-10:33|0|2|0", + "type": 3, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 3182917058194750998, + "detailed_name": "int ns::b", + "short_name": "b", + "hover": "int ns::b = Foo::foo()", + "declarations": [], + "spell": "11:7-11:8|0|2|2", + "extent": "11:3-11:35|0|2|0", + "type": 3, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc new file mode 100644 index 000000000..61a53f894 --- /dev/null +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -0,0 +1,88 @@ +namespace ns { + template + class Foo {}; + + Foo a; + Foo b; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 11072669167287398027, + "detailed_name": "ns", + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|-1|1|2", + "extent": "1:1-7:2|-1|1|0", + "bases": [1], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [], + "uses": ["1:11-1:13|-1|1|4"] + }, { + "id": 1, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [0], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 14042997404480181958, + "detailed_name": "ns::Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "3:9-3:12|0|2|2", + "extent": "3:3-3:15|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["5:3-5:6|-1|1|4", "6:3-6:6|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 15768138241775955040, + "detailed_name": "Foo ns::a", + "short_name": "a", + "declarations": [], + "spell": "5:12-5:13|0|2|2", + "extent": "5:3-5:13|0|2|0", + "type": 2, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 3182917058194750998, + "detailed_name": "Foo ns::b", + "short_name": "b", + "declarations": [], + "spell": "6:13-6:14|0|2|2", + "extent": "6:3-6:14|0|2|0", + "type": 2, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc new file mode 100644 index 000000000..5a545a486 --- /dev/null +++ b/index_tests/templates/specialization.cc @@ -0,0 +1,436 @@ +template +class function; + +template +class function {}; + +function f; + +template class allocator; + +template > +class vector { + void clear(); +}; + +template +class vector {}; + +struct Z1 {}; + +template class vector; + +struct Z2 {}; + +template<> +class vector { + void clear(); +}; + +vector vc; +vector vip; +vector vz1; +vector vz2; + +enum Enum { + Enum0, Enum1 +}; +template +void foo(T Value) {} + +static const int kOnst = 7; +template <> +void foo(float Value); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15019211479263750068, + "detailed_name": "function", + "short_name": "function", + "kind": 5, + "declarations": ["2:7-2:15|-1|1|1", "5:7-5:15|-1|1|4"], + "spell": "2:7-2:15|-1|1|2", + "extent": "1:1-2:15|-1|1|0", + "bases": [], + "derived": [1], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:1-7:9|-1|1|4"] + }, { + "id": 1, + "usr": 218068462278884837, + "detailed_name": "function", + "short_name": "function", + "kind": 5, + "declarations": [], + "spell": "5:7-5:15|-1|1|2", + "extent": "4:1-5:30|-1|1|0", + "bases": [0], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["7:1-7:9|-1|1|4"] + }, { + "id": 2, + "usr": 10862637711685426953, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "4:19-4:20|-1|1|2", + "extent": "4:10-4:20|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:16-5:17|-1|1|4"] + }, { + "id": 3, + "usr": 756188769017350739, + "detailed_name": "Args", + "short_name": "Args", + "kind": 26, + "declarations": [], + "spell": "4:34-4:38|-1|1|2", + "extent": "4:22-4:38|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:18-5:22|-1|1|4"] + }, { + "id": 4, + "usr": 15695704394170757108, + "detailed_name": "allocator", + "short_name": "allocator", + "kind": 5, + "declarations": ["9:28-9:37|-1|1|1", "11:39-11:48|-1|1|4"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 5, + "usr": 7440942986741176606, + "detailed_name": "vector", + "short_name": "vector", + "kind": 5, + "declarations": ["17:7-17:13|-1|1|4", "26:7-26:13|-1|1|4"], + "spell": "12:7-12:13|-1|1|2", + "extent": "12:1-14:2|-1|1|0", + "bases": [], + "derived": [6, 10], + "types": [], + "funcs": [0], + "vars": [], + "instances": [1, 3, 4], + "uses": ["30:1-30:7|-1|1|4", "31:1-31:7|-1|1|4", "32:1-32:7|-1|1|4", "33:1-33:7|-1|1|4"] + }, { + "id": 6, + "usr": 16155717907537731864, + "detailed_name": "vector", + "short_name": "vector", + "kind": 5, + "declarations": [], + "spell": "17:7-17:13|-1|1|2", + "extent": "16:1-17:20|-1|1|0", + "bases": [5], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["31:1-31:7|-1|1|4"] + }, { + "id": 7, + "usr": 3421332160420436276, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "16:19-16:20|-1|1|2", + "extent": "16:10-16:20|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["17:14-17:15|-1|1|4"] + }, { + "id": 8, + "usr": 5760043510674081814, + "detailed_name": "Z1", + "short_name": "Z1", + "kind": 23, + "declarations": [], + "spell": "19:8-19:10|-1|1|2", + "extent": "19:1-19:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["32:8-32:10|-1|1|4"] + }, { + "id": 9, + "usr": 10124869160135436852, + "detailed_name": "Z2", + "short_name": "Z2", + "kind": 23, + "declarations": ["26:14-26:16|-1|1|4"], + "spell": "23:8-23:10|-1|1|2", + "extent": "23:1-23:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["33:8-33:10|-1|1|4"] + }, { + "id": 10, + "usr": 1663022413889915338, + "detailed_name": "vector", + "short_name": "vector", + "kind": 5, + "declarations": [], + "spell": "26:7-26:13|-1|1|2", + "extent": "25:1-28:2|-1|1|0", + "bases": [5], + "derived": [], + "types": [], + "funcs": [1], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 11, + "usr": 9201299975592934124, + "detailed_name": "Enum", + "short_name": "Enum", + "kind": 10, + "declarations": [], + "spell": "35:6-35:10|-1|1|2", + "extent": "35:1-37:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 12, + "usr": 2461355892344618654, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "38:20-38:21|2|3|2", + "extent": "38:11-38:21|2|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["39:10-39:11|-1|1|4"] + }, { + "id": 13, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [8], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 18107614608385228556, + "detailed_name": "void vector::clear()", + "short_name": "clear", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "13:8-13:13|5|2|1", + "param_spellings": [] + }], + "declaring_type": 5, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 6113470698424012876, + "detailed_name": "void vector::clear()", + "short_name": "clear", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "27:8-27:13|10|2|1", + "param_spellings": [] + }], + "declaring_type": 10, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 17498190318698490707, + "detailed_name": "void foo(T Value)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "43:6-43:9|-1|1|1", + "param_spellings": ["43:44-43:49"] + }], + "spell": "39:6-39:9|-1|1|2", + "extent": "39:1-39:21|-1|1|0", + "bases": [], + "derived": [], + "vars": [7], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 2933643612409209903, + "detailed_name": "function f", + "short_name": "f", + "declarations": [], + "spell": "7:21-7:22|-1|1|2", + "extent": "7:1-7:22|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 5792869548777559988, + "detailed_name": "vector vc", + "short_name": "vc", + "declarations": [], + "spell": "30:14-30:16|-1|1|2", + "extent": "30:1-30:16|-1|1|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 86949563628772958, + "detailed_name": "vector vip", + "short_name": "vip", + "declarations": [], + "spell": "31:14-31:17|-1|1|2", + "extent": "31:1-31:17|-1|1|0", + "type": 6, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 3, + "usr": 3566687051827176322, + "detailed_name": "vector vz1", + "short_name": "vz1", + "declarations": [], + "spell": "32:12-32:15|-1|1|2", + "extent": "32:1-32:15|-1|1|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 4, + "usr": 15931696253641284761, + "detailed_name": "vector vz2", + "short_name": "vz2", + "declarations": [], + "spell": "33:12-33:15|-1|1|2", + "extent": "33:1-33:15|-1|1|0", + "type": 5, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 5, + "usr": 15477793821005285152, + "detailed_name": "Enum::Enum0", + "short_name": "Enum0", + "hover": "Enum::Enum0 = 0", + "declarations": [], + "spell": "36:3-36:8|11|2|2", + "extent": "36:3-36:8|11|2|0", + "type": 11, + "uses": ["43:20-43:25|-1|1|4"], + "kind": 22, + "storage": 0 + }, { + "id": 6, + "usr": 4917621020431490070, + "detailed_name": "Enum::Enum1", + "short_name": "Enum1", + "hover": "Enum::Enum1 = 1", + "declarations": [], + "spell": "36:10-36:15|11|2|2", + "extent": "36:10-36:15|11|2|0", + "type": 11, + "uses": [], + "kind": 22, + "storage": 0 + }, { + "id": 7, + "usr": 10307767688451422448, + "detailed_name": "T Value", + "short_name": "Value", + "declarations": [], + "spell": "39:12-39:17|2|3|2", + "extent": "39:10-39:17|2|3|0", + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 8, + "usr": 13914496963221806870, + "detailed_name": "const int kOnst", + "short_name": "kOnst", + "hover": "const int kOnst = 7", + "declarations": [], + "spell": "41:18-41:23|-1|1|2", + "extent": "41:1-41:27|-1|1|0", + "type": 13, + "uses": ["43:27-43:32|-1|1|4"], + "kind": 13, + "storage": 3 + }] +} +*/ diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc new file mode 100644 index 000000000..e39308f9f --- /dev/null +++ b/index_tests/templates/specialized_func_definition.cc @@ -0,0 +1,81 @@ +template +class Template { + void Foo(); +}; + +template +void Template::Foo() {} + +template<> +void Template::Foo() {} + + +/* +// TODO: usage information on Template is bad. +// TODO: Foo() should have multiple definitions. + +EXTRA_FLAGS: +-fms-compatibility +-fdelayed-template-parsing + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17107291254533526269, + "detailed_name": "Template", + "short_name": "Template", + "kind": 5, + "declarations": [], + "spell": "2:7-2:15|-1|1|2", + "extent": "2:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["7:6-7:14|-1|1|4", "10:6-10:14|-1|1|4"] + }, { + "id": 1, + "usr": 17649312483543982122, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 11994188353303124840, + "detailed_name": "void Template::Foo()", + "short_name": "Foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "3:8-3:11|0|2|1", + "param_spellings": [] + }, { + "spell": "10:22-10:25|-1|1|1", + "param_spellings": [] + }], + "spell": "7:19-7:22|0|2|2", + "extent": "6:1-7:24|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc new file mode 100644 index 000000000..733db96f3 --- /dev/null +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -0,0 +1,92 @@ +template +struct Foo { + static int foo() { + return 3; + } +}; + +int a = Foo::foo(); +int b = Foo::foo(); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:8-2:11|-1|1|2", + "extent": "2:1-6:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["8:9-8:12|-1|1|4", "9:9-9:12|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 8340731781048851399, + "detailed_name": "int Foo::foo()", + "short_name": "foo", + "kind": 254, + "storage": 3, + "declarations": [], + "spell": "3:14-3:17|0|2|2", + "extent": "3:3-5:4|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:19-8:22|-1|1|32", "9:20-9:23|-1|1|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = Foo::foo()", + "declarations": [], + "spell": "8:5-8:6|-1|1|2", + "extent": "8:1-8:24|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "int b", + "short_name": "b", + "hover": "int b = Foo::foo()", + "declarations": [], + "spell": "9:5-9:6|-1|1|2", + "extent": "9:1-9:25|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc new file mode 100644 index 000000000..7ee252b42 --- /dev/null +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -0,0 +1,93 @@ +template +struct Foo { + template + static int foo() { + return 3; + } +}; + +int a = Foo::foo(); +int b = Foo::foo(); + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:8-2:11|-1|1|2", + "extent": "2:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["9:9-9:12|-1|1|4", "10:9-10:12|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 9034026360701857235, + "detailed_name": "int Foo::foo()", + "short_name": "foo", + "kind": 254, + "storage": 3, + "declarations": [], + "spell": "4:14-4:17|0|2|2", + "extent": "4:3-6:4|0|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["9:19-9:22|-1|1|32", "10:20-10:23|-1|1|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = Foo::foo()", + "declarations": [], + "spell": "9:5-9:6|-1|1|2", + "extent": "9:1-9:31|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "int b", + "short_name": "b", + "hover": "int b = Foo::foo()", + "declarations": [], + "spell": "10:5-10:6|-1|1|2", + "extent": "10:1-10:33|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc new file mode 100644 index 000000000..c0b611ce8 --- /dev/null +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -0,0 +1,127 @@ +enum A {}; +enum B {}; + +template +struct Foo { + struct Inner {}; +}; + +Foo::Inner a; +Foo::Inner b; + +#if false +EnumDecl A +EnumDecl B +ClassTemplate Foo + TemplateTypeParameter T + StructDecl Inner +VarDecl a + TemplateRef Foo + TypeRef enum A + TypeRef struct Foo::Inner + CallExpr Inner +VarDecl b + TemplateRef Foo + TypeRef enum B + TypeRef struct Foo::Inner + CallExpr Inner +#endif + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": ["12:1-28:7"], + "types": [{ + "id": 0, + "usr": 6697181287623958829, + "detailed_name": "A", + "short_name": "A", + "kind": 10, + "declarations": [], + "spell": "1:6-1:7|-1|1|2", + "extent": "1:1-1:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:5-9:6|-1|1|4"] + }, { + "id": 1, + "usr": 13892793056005362145, + "detailed_name": "B", + "short_name": "B", + "kind": 10, + "declarations": [], + "spell": "2:6-2:7|-1|1|2", + "extent": "2:1-2:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["10:5-10:6|-1|1|4"] + }, { + "id": 2, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "5:8-5:11|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:1-9:4|-1|1|4", "10:1-10:4|-1|1|4"] + }, { + "id": 3, + "usr": 13938528237873543349, + "detailed_name": "Foo::Inner", + "short_name": "Inner", + "kind": 23, + "declarations": [], + "spell": "6:10-6:15|2|2|2", + "extent": "6:3-6:18|2|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["9:9-9:14|-1|1|4", "10:9-10:14|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "Foo::Inner a", + "short_name": "a", + "declarations": [], + "spell": "9:15-9:16|-1|1|2", + "extent": "9:1-9:16|-1|1|0", + "type": 3, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "Foo::Inner b", + "short_name": "b", + "declarations": [], + "spell": "10:15-10:16|-1|1|2", + "extent": "10:1-10:16|-1|1|0", + "type": 3, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc new file mode 100644 index 000000000..fa19a31db --- /dev/null +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -0,0 +1,85 @@ +template +struct Foo { + static constexpr int var = 3; +}; + +int a = Foo::var; +int b = Foo::var; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:8-2:11|-1|1|2", + "extent": "2:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:9-6:12|-1|1|4", "7:9-7:12|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 13545144895171991916, + "detailed_name": "const int Foo::var", + "short_name": "var", + "hover": "const int Foo::var = 3", + "declarations": ["3:24-3:27|0|2|1"], + "type": 1, + "uses": ["6:19-6:22|-1|1|4", "7:20-7:23|-1|1|4"], + "kind": 8, + "storage": 3 + }, { + "id": 1, + "usr": 16721564935990383768, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = Foo::var", + "declarations": [], + "spell": "6:5-6:6|-1|1|2", + "extent": "6:1-6:22|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 12028309045033782423, + "detailed_name": "int b", + "short_name": "b", + "hover": "int b = Foo::var", + "declarations": [], + "spell": "7:5-7:6|-1|1|2", + "extent": "7:1-7:23|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc new file mode 100644 index 000000000..79bca7211 --- /dev/null +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -0,0 +1,76 @@ +template +static int foo() { + return 3; +} + +int a = foo(); +int b = foo(); + +// TODO: put template foo inside a namespace +// TODO: put template foo inside a template class inside a namespace + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 326583651986177228, + "detailed_name": "int foo()", + "short_name": "foo", + "kind": 12, + "storage": 3, + "declarations": [], + "spell": "2:12-2:15|-1|1|2", + "extent": "2:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:9-6:12|-1|1|32", "7:9-7:12|-1|1|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = foo()", + "declarations": [], + "spell": "6:5-6:6|-1|1|2", + "extent": "6:1-6:19|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "int b", + "short_name": "b", + "hover": "int b = foo()", + "declarations": [], + "spell": "7:5-7:6|-1|1|2", + "extent": "7:1-7:20|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc new file mode 100644 index 000000000..0cc76af94 --- /dev/null +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -0,0 +1,56 @@ +template +class Foo {}; + +Foo a; +Foo b; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "2:7-2:10|-1|1|2", + "extent": "2:1-2:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["4:1-4:4|-1|1|4", "5:1-5:4|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "Foo a", + "short_name": "a", + "declarations": [], + "spell": "4:10-4:11|-1|1|2", + "extent": "4:1-4:11|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 12028309045033782423, + "detailed_name": "Foo b", + "short_name": "b", + "declarations": [], + "spell": "5:11-5:12|-1|1|2", + "extent": "5:1-5:12|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc new file mode 100644 index 000000000..8c8fed789 --- /dev/null +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -0,0 +1,125 @@ +enum A {}; +enum B {}; + +template +T var = T(); + +A a = var; +B b = var; + +// NOTE: libclang before 4.0 doesn't expose template usage on |var|. + +#if false +EnumDecl A +EnumDecl B +UnexposedDecl var +VarDecl a + UnexposedExpr var + UnexposedExpr var + DeclRefExpr var + TypeRef enum A +UnexposedDecl var +VarDecl b + UnexposedExpr var + UnexposedExpr var + DeclRefExpr var + TypeRef enum B +UnexposedDecl var +#endif + +/* +EXTRA_FLAGS: +-std=c++14 + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": ["12:1-28:7"], + "types": [{ + "id": 0, + "usr": 6697181287623958829, + "detailed_name": "A", + "short_name": "A", + "kind": 10, + "declarations": [], + "spell": "1:6-1:7|-1|1|2", + "extent": "1:1-1:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": ["7:1-7:2|-1|1|4", "7:11-7:12|-1|1|4"] + }, { + "id": 1, + "usr": 13892793056005362145, + "detailed_name": "B", + "short_name": "B", + "kind": 10, + "declarations": [], + "spell": "2:6-2:7|-1|1|2", + "extent": "2:1-2:10|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2], + "uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"] + }, { + "id": 2, + "usr": 8864163146308556810, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:1-5:2|-1|1|4", "5:9-5:10|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 8096973118640070624, + "detailed_name": "T var", + "short_name": "var", + "declarations": [], + "spell": "5:3-5:6|-1|1|2", + "extent": "5:1-5:12|-1|1|0", + "uses": ["7:7-7:10|-1|1|4", "8:7-8:10|-1|1|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 16721564935990383768, + "detailed_name": "A a", + "short_name": "a", + "hover": "A a = var", + "declarations": [], + "spell": "7:3-7:4|-1|1|2", + "extent": "7:1-7:13|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 2, + "usr": 12028309045033782423, + "detailed_name": "B b", + "short_name": "b", + "hover": "B b = var", + "declarations": [], + "spell": "8:3-8:4|-1|1|2", + "extent": "8:1-8:13|-1|1|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc new file mode 100644 index 000000000..8a975693c --- /dev/null +++ b/index_tests/types/anonymous_struct.cc @@ -0,0 +1,109 @@ +union vector3 { + struct { float x, y, z; }; + float v[3]; +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17937907487590875128, + "detailed_name": "vector3", + "short_name": "vector3", + "kind": 23, + "declarations": [], + "spell": "1:7-1:14|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [3], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 1428566502523368801, + "detailed_name": "vector3::(anon struct)", + "short_name": "(anon struct)", + "kind": 23, + "declarations": [], + "spell": "2:3-2:9|0|2|2", + "extent": "2:3-2:28|0|2|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1, 2], + "instances": [], + "uses": [] + }, { + "id": 2, + "usr": 21, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2, 3], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 3348817847649945564, + "detailed_name": "float vector3::(anon struct)::x", + "short_name": "x", + "declarations": [], + "spell": "2:18-2:19|1|2|2", + "extent": "2:12-2:19|1|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 4821094820988543895, + "detailed_name": "float vector3::(anon struct)::y", + "short_name": "y", + "declarations": [], + "spell": "2:21-2:22|1|2|2", + "extent": "2:12-2:22|1|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 15292551660437765731, + "detailed_name": "float vector3::(anon struct)::z", + "short_name": "z", + "declarations": [], + "spell": "2:24-2:25|1|2|2", + "extent": "2:12-2:25|1|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 3, + "usr": 1963212417280098348, + "detailed_name": "float [3] vector3::v", + "short_name": "v", + "declarations": [], + "spell": "3:9-3:10|0|2|2", + "extent": "3:3-3:13|0|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc new file mode 100644 index 000000000..b11c9eee9 --- /dev/null +++ b/index_tests/types/typedefs.cc @@ -0,0 +1,61 @@ +typedef int (func)(const int *a, const int *b); +static func g; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13838176792705659279, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 10383876566159302459, + "detailed_name": "func", + "short_name": "func", + "kind": 252, + "hover": "typedef int (func)(const int *a, const int *b)", + "declarations": [], + "spell": "1:14-1:18|-1|1|2", + "extent": "1:1-1:47|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["1:14-1:18|-1|1|4", "2:8-2:12|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 8105378401105136463, + "detailed_name": "func g", + "short_name": "g", + "kind": 12, + "storage": 3, + "declarations": [{ + "spell": "2:13-2:14|-1|1|1", + "param_spellings": ["2:13-2:13", "2:13-2:13"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ \ No newline at end of file diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc new file mode 100644 index 000000000..e3e0c5014 --- /dev/null +++ b/index_tests/unions/union_decl.cc @@ -0,0 +1,83 @@ +union Foo { + int a; + bool b; +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 8501689086387244262, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }, { + "id": 2, + "usr": 3, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 9529311430721959843, + "detailed_name": "int Foo::a", + "short_name": "a", + "declarations": [], + "spell": "2:7-2:8|0|2|2", + "extent": "2:3-2:8|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 8804696910588009104, + "detailed_name": "bool Foo::b", + "short_name": "b", + "declarations": [], + "spell": "3:8-3:9|0|2|2", + "extent": "3:3-3:9|0|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc new file mode 100644 index 000000000..bdc57e034 --- /dev/null +++ b/index_tests/unions/union_usage.cc @@ -0,0 +1,120 @@ +union Foo { + int a : 5; + bool b : 3; +}; + +Foo f; + +void act(Foo*) { + f.a = 3; +} + +/* +// TODO: instantiations on Foo should include parameter? + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 8501689086387244262, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [2], + "uses": ["6:1-6:4|-1|1|4", "8:10-8:13|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }, { + "id": 2, + "usr": 3, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 13982179977217945200, + "detailed_name": "void act(Foo *)", + "short_name": "act", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:9|-1|1|2", + "extent": "8:1-10:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 9529311430721959843, + "detailed_name": "int Foo::a", + "short_name": "a", + "hover": "int Foo::a : 5", + "declarations": [], + "spell": "2:7-2:8|0|2|2", + "extent": "2:3-2:12|0|2|0", + "type": 1, + "uses": ["9:5-9:6|0|3|4"], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 8804696910588009104, + "detailed_name": "bool Foo::b", + "short_name": "b", + "hover": "bool Foo::b : 3", + "declarations": [], + "spell": "3:8-3:9|0|2|2", + "extent": "3:3-3:13|0|2|0", + "type": 2, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 2933643612409209903, + "detailed_name": "Foo f", + "short_name": "f", + "declarations": [], + "spell": "6:5-6:6|-1|1|2", + "extent": "6:1-6:6|-1|1|0", + "type": 0, + "uses": ["9:3-9:4|0|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc new file mode 100644 index 000000000..92cc92620 --- /dev/null +++ b/index_tests/usage/func_called_from_constructor.cc @@ -0,0 +1,70 @@ +void called() {} + +struct Foo { + Foo(); +}; + +Foo::Foo() { + called(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["4:3-4:6|-1|1|4", "7:6-7:9|-1|1|4"], + "spell": "3:8-3:11|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [1], + "vars": [], + "instances": [], + "uses": ["4:3-4:6|0|2|4", "7:6-7:9|-1|1|4", "7:1-7:4|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 468307235068920063, + "detailed_name": "void called()", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:12|-1|1|2", + "extent": "1:1-1:17|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:3-8:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 3385168158331140247, + "detailed_name": "void Foo::Foo()", + "short_name": "Foo", + "kind": 9, + "storage": 1, + "declarations": [{ + "spell": "4:3-4:6|0|2|1", + "param_spellings": [] + }], + "spell": "7:6-7:9|0|2|2", + "extent": "7:1-9:2|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["8:3-8:9|0|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc new file mode 100644 index 000000000..42adc3258 --- /dev/null +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -0,0 +1,61 @@ +#define MACRO_CALL(e) e + +bool called(bool a, bool b); + +void caller() { + MACRO_CALL(called(true, true)); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 3787803219955606747, + "detailed_name": "bool called(bool a, bool b)", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "3:6-3:12|-1|1|1", + "param_spellings": ["3:18-3:19", "3:26-3:27"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:14-6:20|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 11404881820527069090, + "detailed_name": "void caller()", + "short_name": "caller", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:12|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["6:14-6:20|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 1290746656694198202, + "detailed_name": "MACRO_CALL", + "short_name": "MACRO_CALL", + "hover": "#define MACRO_CALL(e) e", + "declarations": [], + "spell": "1:9-1:19|-1|1|2", + "extent": "1:9-1:24|-1|1|0", + "uses": ["6:3-6:13|-1|1|4"], + "kind": 255, + "storage": 0 + }] +} +*/ \ No newline at end of file diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc new file mode 100644 index 000000000..14e8e3069 --- /dev/null +++ b/index_tests/usage/func_called_from_template.cc @@ -0,0 +1,69 @@ +void called(); + +template +void caller() { + called(); +} + +void foo() { + caller(); +} + +/* +// NOTE: without caller() instantation caller() is never visited so +// called() is never referenced. +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 468307235068920063, + "detailed_name": "void called()", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:12|-1|1|1", + "param_spellings": [] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["5:3-5:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 10177235824697315808, + "detailed_name": "void caller()", + "short_name": "caller", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:12|-1|1|2", + "extent": "4:1-6:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["9:3-9:9|2|3|32"], + "callees": ["5:3-5:9|0|3|32"] + }, { + "id": 2, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:9|-1|1|2", + "extent": "8:1-10:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["9:3-9:9|1|3|32"] + }], + "vars": [] +} +*/ \ No newline at end of file diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc new file mode 100644 index 000000000..d22528e67 --- /dev/null +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -0,0 +1,83 @@ +struct Wrapper { + Wrapper(int i); +}; + +int called() { return 1; } + +Wrapper caller() { + return called(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13611487872560323389, + "detailed_name": "Wrapper", + "short_name": "Wrapper", + "kind": 23, + "declarations": ["2:3-2:10|-1|1|4"], + "spell": "1:8-1:15|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["2:3-2:10|0|2|4", "7:1-7:8|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 10544127002917214589, + "detailed_name": "void Wrapper::Wrapper(int i)", + "short_name": "Wrapper", + "kind": 9, + "storage": 1, + "declarations": [{ + "spell": "2:3-2:10|0|2|1", + "param_spellings": ["2:15-2:16"] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:10-8:18|2|3|288"], + "callees": [] + }, { + "id": 1, + "usr": 468307235068920063, + "detailed_name": "int called()", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:5-5:11|-1|1|2", + "extent": "5:1-5:27|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:10-8:16|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 11404881820527069090, + "detailed_name": "Wrapper caller()", + "short_name": "caller", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "7:9-7:15|-1|1|2", + "extent": "7:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["8:10-8:18|0|3|288", "8:10-8:16|1|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc new file mode 100644 index 000000000..6e5d8f316 --- /dev/null +++ b/index_tests/usage/func_usage_addr_func.cc @@ -0,0 +1,75 @@ +void consume(void (*)()) {} + +void used() {} + +void user() { + void (*x)() = &used; + consume(&used); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 12924914488846929470, + "detailed_name": "void consume(void (*)())", + "short_name": "consume", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:13|-1|1|2", + "extent": "1:1-1:28|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["7:3-7:10|2|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 5264867802674151787, + "detailed_name": "void used()", + "short_name": "used", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:10|-1|1|2", + "extent": "3:1-3:15|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:18-6:22|2|3|32", "7:12-7:16|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 9376923949268137283, + "detailed_name": "void user()", + "short_name": "user", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:10|-1|1|2", + "extent": "5:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["6:18-6:22|1|3|32", "6:18-6:22|1|3|32", "7:3-7:10|0|3|32", "7:12-7:16|1|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 13681544683892648258, + "detailed_name": "void (*)() x", + "short_name": "x", + "declarations": [], + "spell": "6:10-6:11|2|3|2", + "extent": "6:3-6:22|2|3|0", + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc new file mode 100644 index 000000000..faeec595e --- /dev/null +++ b/index_tests/usage/func_usage_addr_method.cc @@ -0,0 +1,78 @@ +struct Foo { + void Used(); +}; + +void user() { + auto x = &Foo::Used; +} + + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [], + "uses": ["6:13-6:16|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 18417145003926999463, + "detailed_name": "void Foo::Used()", + "short_name": "Used", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:12|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:18-6:22|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 9376923949268137283, + "detailed_name": "void user()", + "short_name": "user", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:10|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["6:18-6:22|0|3|32", "6:18-6:22|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 8436636043513449412, + "detailed_name": "void (Foo::*)() x", + "short_name": "x", + "declarations": [], + "spell": "6:8-6:9|1|3|2", + "extent": "6:3-6:22|1|3|0", + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc new file mode 100644 index 000000000..574108532 --- /dev/null +++ b/index_tests/usage/func_usage_call_func.cc @@ -0,0 +1,45 @@ +void called() {} +void caller() { + called(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 468307235068920063, + "detailed_name": "void called()", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:12|-1|1|2", + "extent": "1:1-1:17|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["3:3-3:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 11404881820527069090, + "detailed_name": "void caller()", + "short_name": "caller", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "2:6-2:12|-1|1|2", + "extent": "2:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["3:3-3:9|0|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc new file mode 100644 index 000000000..088a737ab --- /dev/null +++ b/index_tests/usage/func_usage_call_method.cc @@ -0,0 +1,80 @@ +struct Foo { + void Used(); +}; + +void user() { + Foo* f = nullptr; + f->Used(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [0], + "uses": ["6:3-6:6|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 18417145003926999463, + "detailed_name": "void Foo::Used()", + "short_name": "Used", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:12|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["7:6-7:10|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 9376923949268137283, + "detailed_name": "void user()", + "short_name": "user", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:10|-1|1|2", + "extent": "5:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["7:6-7:10|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 3014406561587537195, + "detailed_name": "Foo *f", + "short_name": "f", + "hover": "Foo *f = nullptr", + "declarations": [], + "spell": "6:8-6:9|1|3|2", + "extent": "6:3-6:19|1|3|0", + "type": 0, + "uses": ["7:3-7:4|1|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc new file mode 100644 index 000000000..c3f1b85cc --- /dev/null +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -0,0 +1,76 @@ +static int helper() { + return 5; +} + +class Foo { + int x = helper(); +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "5:7-5:10|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 9630503130605430498, + "detailed_name": "int helper()", + "short_name": "helper", + "kind": 12, + "storage": 3, + "declarations": [], + "spell": "1:12-1:18|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:11-6:17|0|2|32"], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 4220150017963593039, + "detailed_name": "int Foo::x", + "short_name": "x", + "hover": "int Foo::x = helper()", + "declarations": [], + "spell": "6:7-6:8|0|2|2", + "extent": "6:3-6:19|0|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc new file mode 100644 index 000000000..caec7c49c --- /dev/null +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -0,0 +1,46 @@ +void foo(); + +void usage() { + foo(); +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:9|-1|1|1", + "param_spellings": [] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["4:3-4:6|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 6767773193109753523, + "detailed_name": "void usage()", + "short_name": "usage", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:11|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["4:3-4:6|0|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc new file mode 100644 index 000000000..b34f9875c --- /dev/null +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -0,0 +1,79 @@ +struct Foo { + void foo(); +}; + +void usage() { + Foo* f = nullptr; + f->foo(); +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [0], + "uses": ["6:3-6:6|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 17922201480358737771, + "detailed_name": "void Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:11|0|2|1", + "param_spellings": [] + }], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["7:6-7:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 6767773193109753523, + "detailed_name": "void usage()", + "short_name": "usage", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:11|-1|1|2", + "extent": "5:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["7:6-7:9|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 12410753116854389823, + "detailed_name": "Foo *f", + "short_name": "f", + "hover": "Foo *f = nullptr", + "declarations": [], + "spell": "6:8-6:9|1|3|2", + "extent": "6:3-6:19|1|3|0", + "type": 0, + "uses": ["7:3-7:4|1|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc new file mode 100644 index 000000000..ddfe668a5 --- /dev/null +++ b/index_tests/usage/func_usage_template_func.cc @@ -0,0 +1,65 @@ +template +void accept(T); + +void foo() { + accept(1); + accept(true); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13420564603121289209, + "detailed_name": "T", + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "1:19-1:20|0|3|2", + "extent": "1:10-1:20|0|3|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:13-2:14|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 10585861037135727329, + "detailed_name": "void accept(T)", + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "2:6-2:12|-1|1|1", + "param_spellings": ["2:14-2:14"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["5:3-5:9|1|3|32", "6:3-6:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|-1|1|2", + "extent": "4:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["5:3-5:9|0|3|32", "6:3-6:9|0|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc new file mode 100644 index 000000000..5752413ba --- /dev/null +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -0,0 +1,105 @@ +template +class unique_ptr {}; + +struct S {}; + +static unique_ptr f0; +static unique_ptr f1; + +unique_ptr* return_type() { + unique_ptr* local; + return nullptr; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 3286534761799572592, + "detailed_name": "unique_ptr", + "short_name": "unique_ptr", + "kind": 5, + "declarations": [], + "spell": "2:7-2:17|-1|1|2", + "extent": "2:1-2:20|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2], + "uses": ["6:8-6:18|-1|1|4", "7:8-7:18|-1|1|4", "9:1-9:11|-1|1|4", "10:3-10:13|-1|1|4"] + }, { + "id": 1, + "usr": 4750332761459066907, + "detailed_name": "S", + "short_name": "S", + "kind": 23, + "declarations": [], + "spell": "4:8-4:9|-1|1|2", + "extent": "4:1-4:12|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["7:19-7:20|-1|1|4", "9:12-9:13|-1|1|4", "10:14-10:15|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 16359708726068806331, + "detailed_name": "unique_ptr *return_type()", + "short_name": "return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "9:16-9:27|-1|1|2", + "extent": "9:1-12:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [2], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 12857919739649552168, + "detailed_name": "unique_ptr f0", + "short_name": "f0", + "declarations": [], + "spell": "6:25-6:27|-1|1|2", + "extent": "6:1-6:27|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 3 + }, { + "id": 1, + "usr": 18075066956054788088, + "detailed_name": "unique_ptr f1", + "short_name": "f1", + "declarations": [], + "spell": "7:22-7:24|-1|1|2", + "extent": "7:1-7:24|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 3 + }, { + "id": 2, + "usr": 2462000803278878465, + "detailed_name": "unique_ptr *local", + "short_name": "local", + "declarations": [], + "spell": "10:18-10:23|0|3|2", + "extent": "10:3-10:23|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc new file mode 100644 index 000000000..50e7690d1 --- /dev/null +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -0,0 +1,234 @@ +template +class unique_ptr; + +struct S1; +struct S2; + +#if false +VarDecl f + TemplateRef unique_ptr + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 + TypeRef struct S2 +#endif +extern unique_ptr, S2> f; + +#if false +FunctionDecl as_return_type + TemplateRef unique_ptr + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 + TypeRef struct S2 + ParmDecl + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 + CompoundStmt + ReturnStmt + UnexposedExpr + CXXNullPtrLiteralExpr +#endif +unique_ptr, S2>* as_return_type(unique_ptr*) { return nullptr; } + +#if false +FunctionDecl no_return_type + ParmDecl + CompoundStmt +#endif +void no_return_type(int) {} + +#if false +FunctionDecl empty + CompoundStmt + DeclStmt + VarDecl local + TemplateRef unique_ptr + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 + TypeRef struct S2 +#endif +void empty() { + unique_ptr, S2>* local; +} + +#if false +ClassDecl Foo + CXXMethod foo + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 +#endif +class Foo { + unique_ptr* foo(); +}; + +#if false +CXXMethod foo + TemplateRef unique_ptr + TypeRef struct S1 + TypeRef struct S2 + TypeRef class Foo + CompoundStmt + ReturnStmt + UnexposedExpr + CXXNullPtrLiteralExpr +#endif +unique_ptr* Foo::foo() { return nullptr; } + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": ["7:1-14:7", "17:1-32:7", "35:1-39:7", "42:1-52:7", "57:1-63:7", "68:1-78:7"], + "types": [{ + "id": 0, + "usr": 14209198335088845323, + "detailed_name": "unique_ptr", + "short_name": "unique_ptr", + "kind": 5, + "declarations": ["2:7-2:17|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["15:8-15:18|-1|1|4", "15:19-15:29|-1|1|4", "33:1-33:11|-1|1|4", "33:12-33:22|-1|1|4", "33:52-33:62|-1|1|4", "54:3-54:13|-1|1|4", "54:14-54:24|-1|1|4", "65:3-65:13|-1|1|4", "79:1-79:11|-1|1|4"] + }, { + "id": 1, + "usr": 4310164820010458371, + "detailed_name": "S1", + "short_name": "S1", + "kind": 23, + "declarations": ["4:8-4:10|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["15:30-15:32|-1|1|4", "33:23-33:25|-1|1|4", "33:63-33:65|-1|1|4", "54:25-54:27|-1|1|4", "65:14-65:16|-1|1|4", "79:12-79:14|-1|1|4"] + }, { + "id": 2, + "usr": 12728490517004312484, + "detailed_name": "S2", + "short_name": "S2", + "kind": 23, + "declarations": ["5:8-5:10|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["15:34-15:36|-1|1|4", "15:39-15:41|-1|1|4", "33:27-33:29|-1|1|4", "33:32-33:34|-1|1|4", "33:67-33:69|-1|1|4", "54:29-54:31|-1|1|4", "54:34-54:36|-1|1|4", "65:18-65:20|-1|1|4", "79:16-79:18|-1|1|4"] + }, { + "id": 3, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "64:7-64:10|-1|1|2", + "extent": "64:1-66:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [3], + "vars": [], + "instances": [], + "uses": ["79:21-79:24|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 1246637699196435450, + "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", + "short_name": "as_return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "33:37-33:51|-1|1|2", + "extent": "33:1-33:92|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 13067214284561914253, + "detailed_name": "void no_return_type(int)", + "short_name": "no_return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "40:6-40:20|-1|1|2", + "extent": "40:1-40:28|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 18320186404467436976, + "detailed_name": "void empty()", + "short_name": "empty", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "53:6-53:11|-1|1|2", + "extent": "53:1-55:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [1], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 17922201480358737771, + "detailed_name": "unique_ptr *Foo::foo()", + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "65:23-65:26|3|2|1", + "param_spellings": [] + }], + "spell": "79:26-79:29|3|2|2", + "extent": "79:1-79:51|-1|1|0", + "declaring_type": 3, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 2933643612409209903, + "detailed_name": "unique_ptr, S2> f", + "short_name": "f", + "declarations": ["15:43-15:44|-1|1|1"], + "type": 0, + "uses": [], + "kind": 13, + "storage": 2 + }, { + "id": 1, + "usr": 11547294959889394856, + "detailed_name": "unique_ptr, S2> *local", + "short_name": "local", + "declarations": [], + "spell": "54:39-54:44|2|3|2", + "extent": "54:3-54:44|2|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc new file mode 100644 index 000000000..20ee51d34 --- /dev/null +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -0,0 +1,59 @@ +template +class unique_ptr {}; + +struct S; + +static unique_ptr foo; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 3286534761799572592, + "detailed_name": "unique_ptr", + "short_name": "unique_ptr", + "kind": 5, + "declarations": [], + "spell": "2:7-2:17|-1|1|2", + "extent": "2:1-2:20|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["6:8-6:18|-1|1|4"] + }, { + "id": 1, + "usr": 4750332761459066907, + "detailed_name": "S", + "short_name": "S", + "kind": 23, + "declarations": ["4:8-4:9|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:19-6:20|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 3398408600781120939, + "detailed_name": "unique_ptr foo", + "short_name": "foo", + "declarations": [], + "spell": "6:22-6:25|-1|1|2", + "extent": "6:1-6:25|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 3 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc new file mode 100644 index 000000000..a89d10647 --- /dev/null +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -0,0 +1,39 @@ +struct T {}; + +extern T t; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 5673439900521455039, + "detailed_name": "T", + "short_name": "T", + "kind": 23, + "declarations": [], + "spell": "1:8-1:9|-1|1|2", + "extent": "1:1-1:12|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["3:8-3:9|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 1346710425945444872, + "detailed_name": "T t", + "short_name": "t", + "declarations": ["3:10-3:11|-1|1|1"], + "type": 0, + "uses": [], + "kind": 13, + "storage": 2 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc new file mode 100644 index 000000000..5876efe63 --- /dev/null +++ b/index_tests/usage/type_usage_declare_field.cc @@ -0,0 +1,88 @@ +struct ForwardType; +struct ImplementedType {}; + +struct Foo { + ForwardType* a; + ImplementedType b; +}; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["5:3-5:14|-1|1|4"] + }, { + "id": 1, + "usr": 8508299082070213750, + "detailed_name": "ImplementedType", + "short_name": "ImplementedType", + "kind": 23, + "declarations": [], + "spell": "2:8-2:23|-1|1|2", + "extent": "2:1-2:26|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": ["6:3-6:18|-1|1|4"] + }, { + "id": 2, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "4:8-4:11|-1|1|2", + "extent": "4:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 14314859014962085433, + "detailed_name": "ForwardType *Foo::a", + "short_name": "a", + "declarations": [], + "spell": "5:16-5:17|2|2|2", + "extent": "5:3-5:17|2|2|0", + "type": 0, + "uses": [], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 14727441168849658842, + "detailed_name": "ImplementedType Foo::b", + "short_name": "b", + "declarations": [], + "spell": "6:19-6:20|2|2|2", + "extent": "6:3-6:20|2|2|0", + "type": 1, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc new file mode 100644 index 000000000..0503fbc6e --- /dev/null +++ b/index_tests/usage/type_usage_declare_local.cc @@ -0,0 +1,87 @@ +struct ForwardType; +struct ImplementedType {}; + +void Foo() { + ForwardType* a; + ImplementedType b; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["5:3-5:14|-1|1|4"] + }, { + "id": 1, + "usr": 8508299082070213750, + "detailed_name": "ImplementedType", + "short_name": "ImplementedType", + "kind": 23, + "declarations": [], + "spell": "2:8-2:23|-1|1|2", + "extent": "2:1-2:26|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": ["6:3-6:18|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 4654328188330986029, + "detailed_name": "void Foo()", + "short_name": "Foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|-1|1|2", + "extent": "4:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 11033478034711123650, + "detailed_name": "ForwardType *a", + "short_name": "a", + "declarations": [], + "spell": "5:16-5:17|0|3|2", + "extent": "5:3-5:17|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 8949902309768550158, + "detailed_name": "ImplementedType b", + "short_name": "b", + "declarations": [], + "spell": "6:19-6:20|0|3|2", + "extent": "6:3-6:20|0|3|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc new file mode 100644 index 000000000..24fd0927f --- /dev/null +++ b/index_tests/usage/type_usage_declare_param.cc @@ -0,0 +1,84 @@ +struct ForwardType; +struct ImplementedType {}; + +void foo(ForwardType* f, ImplementedType a) {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["4:10-4:21|-1|1|4"] + }, { + "id": 1, + "usr": 8508299082070213750, + "detailed_name": "ImplementedType", + "short_name": "ImplementedType", + "kind": 23, + "declarations": [], + "spell": "2:8-2:23|-1|1|2", + "extent": "2:1-2:26|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [1], + "uses": ["4:26-4:41|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 1699390678058422036, + "detailed_name": "void foo(ForwardType *f, ImplementedType a)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|-1|1|2", + "extent": "4:1-4:47|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 2584795197111552890, + "detailed_name": "ForwardType *f", + "short_name": "f", + "declarations": [], + "spell": "4:23-4:24|0|3|2", + "extent": "4:10-4:24|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 5136230284979460117, + "detailed_name": "ImplementedType a", + "short_name": "a", + "declarations": [], + "spell": "4:42-4:43|0|3|2", + "extent": "4:26-4:43|0|3|0", + "type": 1, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc new file mode 100644 index 000000000..711054df3 --- /dev/null +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -0,0 +1,64 @@ +struct Foo; + +void foo(Foo* f, Foo*); +void foo(Foo* f, Foo*) {} + +/* +// TODO: No interesting usage on prototype. But maybe that's ok! +// TODO: We should have the same variable declared for both prototype and +// declaration. So it should have a usage marker on both. Then we could +// rename parameters! + +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["3:10-3:13|-1|1|4", "3:18-3:21|-1|1|4", "4:10-4:13|-1|1|4", "4:18-4:21|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 8908726657907936744, + "detailed_name": "void foo(Foo *f, Foo *)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "3:6-3:9|-1|1|1", + "param_spellings": ["3:15-3:16", "3:22-3:22"] + }], + "spell": "4:6-4:9|-1|1|2", + "extent": "4:1-4:26|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 2161866804398917919, + "detailed_name": "Foo *f", + "short_name": "f", + "declarations": [], + "spell": "4:15-4:16|0|3|2", + "extent": "4:10-4:16|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc new file mode 100644 index 000000000..2af6a1927 --- /dev/null +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -0,0 +1,41 @@ +struct ForwardType; +void foo(ForwardType*) {} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:10-2:21|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 15327735280790448926, + "detailed_name": "void foo(ForwardType *)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "2:6-2:9|-1|1|2", + "extent": "2:1-2:26|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc new file mode 100644 index 000000000..5c31c5e17 --- /dev/null +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -0,0 +1,122 @@ +struct Type {}; + +void foo(Type& a0, const Type& a1) { + Type a2; + Type* a3; + const Type* a4; + const Type* const a5 = nullptr; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13487927231218873822, + "detailed_name": "Type", + "short_name": "Type", + "kind": 23, + "declarations": [], + "spell": "1:8-1:12|-1|1|2", + "extent": "1:1-1:15|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2, 3, 4, 5], + "uses": ["3:10-3:14|-1|1|4", "3:26-3:30|-1|1|4", "4:3-4:7|-1|1|4", "5:3-5:7|-1|1|4", "6:9-6:13|-1|1|4", "7:9-7:13|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 16858540520096802573, + "detailed_name": "void foo(Type &a0, const Type &a1)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1, 2, 3, 4, 5], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 16414210592877294238, + "detailed_name": "Type &a0", + "short_name": "a0", + "declarations": [], + "spell": "3:16-3:18|0|3|2", + "extent": "3:10-3:18|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 11558141642862804306, + "detailed_name": "const Type &a1", + "short_name": "a1", + "declarations": [], + "spell": "3:32-3:34|0|3|2", + "extent": "3:20-3:34|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 2, + "usr": 1536316608590232194, + "detailed_name": "Type a2", + "short_name": "a2", + "declarations": [], + "spell": "4:8-4:10|0|3|2", + "extent": "4:3-4:10|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 3, + "usr": 316760354845869406, + "detailed_name": "Type *a3", + "short_name": "a3", + "declarations": [], + "spell": "5:9-5:11|0|3|2", + "extent": "5:3-5:11|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 4, + "usr": 12321730890779907974, + "detailed_name": "const Type *a4", + "short_name": "a4", + "declarations": [], + "spell": "6:15-6:17|0|3|2", + "extent": "6:3-6:17|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 5, + "usr": 4771437488905761633, + "detailed_name": "const Type *const a5", + "short_name": "a5", + "hover": "const Type *const a5 = nullptr", + "declarations": [], + "spell": "7:21-7:23|0|3|2", + "extent": "7:3-7:33|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc new file mode 100644 index 000000000..0e570fee3 --- /dev/null +++ b/index_tests/usage/type_usage_declare_static.cc @@ -0,0 +1,40 @@ +struct Type {}; +static Type t; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13487927231218873822, + "detailed_name": "Type", + "short_name": "Type", + "kind": 23, + "declarations": [], + "spell": "1:8-1:12|-1|1|2", + "extent": "1:1-1:15|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["2:8-2:12|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 6601831367240627080, + "detailed_name": "Type t", + "short_name": "t", + "declarations": [], + "spell": "2:13-2:14|-1|1|2", + "extent": "2:1-2:14|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 3 + }] +} +*/ diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc new file mode 100644 index 000000000..cdd5c0906 --- /dev/null +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -0,0 +1,152 @@ +struct Type; + +Type* foo(); +Type* foo(); +Type* foo() { return nullptr; } + +class Foo { + Type* Get(int); + void Empty(); +}; + +Type* Foo::Get(int) { return nullptr; } +void Foo::Empty() {} + +extern const Type& external(); + +static Type* bar(); +static Type* bar() { return nullptr; } + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 13487927231218873822, + "detailed_name": "Type", + "short_name": "Type", + "kind": 23, + "declarations": ["1:8-1:12|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["3:1-3:5|-1|1|4", "4:1-4:5|-1|1|4", "5:1-5:5|-1|1|4", "8:3-8:7|-1|1|4", "12:1-12:5|-1|1|4", "15:14-15:18|-1|1|4", "17:8-17:12|-1|1|4", "18:8-18:12|-1|1|4"] + }, { + "id": 1, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "7:7-7:10|-1|1|2", + "extent": "7:1-10:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [1, 2], + "vars": [], + "instances": [], + "uses": ["12:7-12:10|-1|1|4", "13:6-13:9|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "Type *foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "3:7-3:10|-1|1|1", + "param_spellings": [] + }, { + "spell": "4:7-4:10|-1|1|1", + "param_spellings": [] + }], + "spell": "5:7-5:10|-1|1|2", + "extent": "5:1-5:32|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 13402221340333431092, + "detailed_name": "Type *Foo::Get(int)", + "short_name": "Get", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "8:9-8:12|1|2|1", + "param_spellings": ["8:16-8:16"] + }], + "spell": "12:12-12:15|1|2|2", + "extent": "12:1-12:40|-1|1|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 4240751906910175539, + "detailed_name": "void Foo::Empty()", + "short_name": "Empty", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "9:8-9:13|1|2|1", + "param_spellings": [] + }], + "spell": "13:11-13:16|1|2|2", + "extent": "13:1-13:21|-1|1|0", + "declaring_type": 1, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 7746867874366499515, + "detailed_name": "const Type &external()", + "short_name": "external", + "kind": 12, + "storage": 2, + "declarations": [{ + "spell": "15:20-15:28|-1|1|1", + "param_spellings": [] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 4, + "usr": 18408440185620243373, + "detailed_name": "Type *bar()", + "short_name": "bar", + "kind": 12, + "storage": 3, + "declarations": [{ + "spell": "17:14-17:17|-1|1|1", + "param_spellings": [] + }], + "spell": "18:14-18:17|-1|1|2", + "extent": "18:1-18:39|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc new file mode 100644 index 000000000..a732a4f6b --- /dev/null +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -0,0 +1,181 @@ +struct Foo; +using Foo1 = Foo*; +typedef Foo Foo2; +using Foo3 = Foo1; +using Foo4 = int; + +void accept(Foo*) {} +void accept1(Foo1*) {} +void accept2(Foo2*) {} +void accept3(Foo3*) {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:14-2:17|-1|1|4", "3:9-3:12|-1|1|4", "7:13-7:16|-1|1|4"] + }, { + "id": 1, + "usr": 1544499294580512394, + "detailed_name": "Foo1", + "short_name": "Foo1", + "kind": 252, + "hover": "using Foo1 = Foo*", + "declarations": [], + "spell": "2:7-2:11|-1|1|2", + "extent": "2:1-2:18|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:7-2:11|-1|1|4", "4:14-4:18|-1|1|4", "8:14-8:18|-1|1|4"] + }, { + "id": 2, + "usr": 15466821155413653804, + "detailed_name": "Foo2", + "short_name": "Foo2", + "kind": 252, + "hover": "typedef Foo Foo2", + "declarations": [], + "spell": "3:13-3:17|-1|1|2", + "extent": "3:1-3:17|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["3:13-3:17|-1|1|4", "9:14-9:18|-1|1|4"] + }, { + "id": 3, + "usr": 17897026942631673064, + "detailed_name": "Foo3", + "short_name": "Foo3", + "kind": 252, + "hover": "using Foo3 = Foo1", + "declarations": [], + "spell": "4:7-4:11|-1|1|2", + "extent": "4:1-4:18|-1|1|0", + "alias_of": 1, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:7-4:11|-1|1|4", "10:14-10:18|-1|1|4"] + }, { + "id": 4, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 5, + "usr": 2638219001294786365, + "detailed_name": "Foo4", + "short_name": "Foo4", + "kind": 252, + "hover": "using Foo4 = int", + "declarations": [], + "spell": "5:7-5:11|-1|1|2", + "extent": "5:1-5:17|-1|1|0", + "alias_of": 4, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:7-5:11|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 9119341505144503905, + "detailed_name": "void accept(Foo *)", + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "7:6-7:12|-1|1|2", + "extent": "7:1-7:21|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 1, + "usr": 558620830317390922, + "detailed_name": "void accept1(Foo1 *)", + "short_name": "accept1", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:13|-1|1|2", + "extent": "8:1-8:23|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 2, + "usr": 10523262907746124479, + "detailed_name": "void accept2(Foo2 *)", + "short_name": "accept2", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "9:6-9:13|-1|1|2", + "extent": "9:1-9:23|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "id": 3, + "usr": 14986366321326974406, + "detailed_name": "void accept3(Foo3 *)", + "short_name": "accept3", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "10:6-10:13|-1|1|2", + "extent": "10:1-10:23|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc new file mode 100644 index 000000000..fb536eaba --- /dev/null +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -0,0 +1,66 @@ +template +struct Foo; + +using Foo1 = Foo; +typedef Foo Foo2; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 10528472276654770367, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": ["2:8-2:11|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:14-4:17|-1|1|4", "5:9-5:12|-1|1|4"] + }, { + "id": 1, + "usr": 1544499294580512394, + "detailed_name": "Foo1", + "short_name": "Foo1", + "kind": 252, + "hover": "using Foo1 = Foo", + "declarations": [], + "spell": "4:7-4:11|-1|1|2", + "extent": "4:1-4:22|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:7-4:11|-1|1|4", "5:13-5:17|-1|1|4"] + }, { + "id": 2, + "usr": 15933698173231330933, + "detailed_name": "Foo2", + "short_name": "Foo2", + "kind": 252, + "hover": "typedef Foo Foo2", + "declarations": [], + "spell": "5:19-5:23|-1|1|2", + "extent": "5:1-5:23|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:19-5:23|-1|1|4"] + }], + "funcs": [], + "vars": [] +} +*/ diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc new file mode 100644 index 000000000..ba72ffad3 --- /dev/null +++ b/index_tests/usage/type_usage_various.cc @@ -0,0 +1,78 @@ +class Foo { + Foo* make(); +}; + +Foo* Foo::make() { + Foo f; + return nullptr; +} + +extern Foo foo; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [0], + "vars": [], + "instances": [0, 1], + "uses": ["2:3-2:6|-1|1|4", "5:1-5:4|-1|1|4", "5:6-5:9|-1|1|4", "6:3-6:6|-1|1|4", "10:8-10:11|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 9488177941273031343, + "detailed_name": "Foo *Foo::make()", + "short_name": "make", + "kind": 6, + "storage": 1, + "declarations": [{ + "spell": "2:8-2:12|0|2|1", + "param_spellings": [] + }], + "spell": "5:11-5:15|0|2|2", + "extent": "5:1-8:2|-1|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 14873619387499024780, + "detailed_name": "Foo f", + "short_name": "f", + "declarations": [], + "spell": "6:7-6:8|0|3|2", + "extent": "6:3-6:8|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 14455976355866885943, + "detailed_name": "Foo foo", + "short_name": "foo", + "declarations": ["10:12-10:15|-1|1|1"], + "type": 0, + "uses": [], + "kind": 13, + "storage": 2 + }] +} +*/ diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc new file mode 100644 index 000000000..2bec1cb68 --- /dev/null +++ b/index_tests/usage/usage_inside_of_call.cc @@ -0,0 +1,141 @@ +void called(int a); + +int gen(); + +struct Foo { + static int static_var; + int field_var; +}; + +int Foo::static_var = 0; + +void foo() { + int a = 5; + called(a + gen() + Foo().field_var + Foo::static_var); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "5:8-5:11|-1|1|2", + "extent": "5:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [1, 0], + "instances": [], + "uses": ["10:5-10:8|-1|1|4", "14:22-14:25|-1|1|4", "14:40-14:43|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1, 2], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 18319417758892371313, + "detailed_name": "void called(int a)", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:12|-1|1|1", + "param_spellings": ["1:17-1:18"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["14:3-14:9|2|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 11404602816585117695, + "detailed_name": "int gen()", + "short_name": "gen", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "3:5-3:8|-1|1|1", + "param_spellings": [] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["14:14-14:17|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "12:6-12:9|-1|1|2", + "extent": "12:1-15:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [2], + "uses": [], + "callees": ["14:3-14:9|0|3|32", "14:14-14:17|1|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 11489549839875479478, + "detailed_name": "int Foo::static_var", + "short_name": "static_var", + "hover": "int Foo::static_var = 0", + "declarations": ["6:14-6:24|0|2|1"], + "spell": "10:10-10:20|0|2|2", + "extent": "10:1-10:24|-1|1|0", + "type": 1, + "uses": ["14:45-14:55|2|3|4"], + "kind": 8, + "storage": 1 + }, { + "id": 1, + "usr": 9648311402855509901, + "detailed_name": "int Foo::field_var", + "short_name": "field_var", + "declarations": [], + "spell": "7:7-7:16|0|2|2", + "extent": "7:3-7:16|0|2|0", + "type": 1, + "uses": ["14:28-14:37|2|3|4"], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 13284113377394221067, + "detailed_name": "int a", + "short_name": "a", + "hover": "int a = 5", + "declarations": [], + "spell": "13:7-13:8|2|3|2", + "extent": "13:3-13:12|2|3|0", + "type": 1, + "uses": ["14:10-14:11|2|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc new file mode 100644 index 000000000..b5336d116 --- /dev/null +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -0,0 +1,64 @@ +void called(int a); + +int gen() { return 1; } + +void foo() { + called(gen() * gen()); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 18319417758892371313, + "detailed_name": "void called(int a)", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "1:6-1:12|-1|1|1", + "param_spellings": ["1:17-1:18"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:3-6:9|2|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 11404602816585117695, + "detailed_name": "int gen()", + "short_name": "gen", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:5-3:8|-1|1|2", + "extent": "3:1-3:24|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:10-6:13|2|3|32", "6:18-6:21|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:9|-1|1|2", + "extent": "5:1-7:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["6:3-6:9|0|3|32", "6:10-6:13|1|3|32", "6:18-6:21|1|3|32"] + }], + "vars": [] +} +*/ diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc new file mode 100644 index 000000000..e5cbf4236 --- /dev/null +++ b/index_tests/usage/var_usage_call_function.cc @@ -0,0 +1,60 @@ +void called() {} + +void caller() { + auto x = &called; + x(); + + called(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 468307235068920063, + "detailed_name": "void called()", + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:12|-1|1|2", + "extent": "1:1-1:17|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": ["4:13-4:19|1|3|32", "7:3-7:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 11404881820527069090, + "detailed_name": "void caller()", + "short_name": "caller", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:12|-1|1|2", + "extent": "3:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": ["4:13-4:19|0|3|32", "4:13-4:19|0|3|32", "7:3-7:9|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 3510529098767253033, + "detailed_name": "void (*)() x", + "short_name": "x", + "declarations": [], + "spell": "4:8-4:9|1|3|2", + "extent": "4:3-4:19|1|3|0", + "uses": ["5:3-5:4|1|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc new file mode 100644 index 000000000..37a097610 --- /dev/null +++ b/index_tests/usage/var_usage_class_member.cc @@ -0,0 +1,142 @@ +class Foo { +public: + int x; + int y; +}; + +void accept(int); +void accept(int*); + +void foo() { + Foo f; + f.x = 3; + f.x += 5; + accept(f.x); + accept(f.x + 20); + accept(&f.x); + accept(f.y); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0, 1], + "instances": [2], + "uses": ["11:3-11:6|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17175780305784503374, + "detailed_name": "void accept(int)", + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "7:6-7:12|-1|1|1", + "param_spellings": ["7:16-7:16"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["14:3-14:9|2|3|32", "15:3-15:9|2|3|32", "17:3-17:9|2|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 12086644540399881766, + "detailed_name": "void accept(int *)", + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "8:6-8:12|-1|1|1", + "param_spellings": ["8:17-8:17"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["16:3-16:9|2|3|32"], + "callees": [] + }, { + "id": 2, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "10:6-10:9|-1|1|2", + "extent": "10:1-18:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [2], + "uses": [], + "callees": ["14:3-14:9|0|3|32", "15:3-15:9|0|3|32", "16:3-16:9|1|3|32", "17:3-17:9|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 4220150017963593039, + "detailed_name": "int Foo::x", + "short_name": "x", + "declarations": [], + "spell": "3:7-3:8|0|2|2", + "extent": "3:3-3:8|0|2|0", + "type": 1, + "uses": ["12:5-12:6|2|3|4", "13:5-13:6|2|3|4", "14:12-14:13|2|3|4", "15:12-15:13|2|3|4", "16:13-16:14|2|3|4"], + "kind": 8, + "storage": 0 + }, { + "id": 1, + "usr": 3873837747174060388, + "detailed_name": "int Foo::y", + "short_name": "y", + "declarations": [], + "spell": "4:7-4:8|0|2|2", + "extent": "4:3-4:8|0|2|0", + "type": 1, + "uses": ["17:12-17:13|2|3|4"], + "kind": 8, + "storage": 0 + }, { + "id": 2, + "usr": 16303259148898744165, + "detailed_name": "Foo f", + "short_name": "f", + "declarations": [], + "spell": "11:7-11:8|2|3|2", + "extent": "11:3-11:8|2|3|0", + "type": 0, + "uses": ["12:3-12:4|2|3|4", "13:3-13:4|2|3|4", "14:10-14:11|2|3|4", "15:10-15:11|2|3|4", "16:11-16:12|2|3|4", "17:10-17:11|2|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc new file mode 100644 index 000000000..1ad13233f --- /dev/null +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -0,0 +1,91 @@ +struct Foo { + static int x; +}; + +void accept(int); + +void foo() { + accept(Foo::x); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": [], + "spell": "1:8-1:11|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["8:10-8:13|-1|1|4"] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 17175780305784503374, + "detailed_name": "void accept(int)", + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": [{ + "spell": "5:6-5:12|-1|1|1", + "param_spellings": ["5:16-5:16"] + }], + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:3-8:9|1|3|32"], + "callees": [] + }, { + "id": 1, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "7:6-7:9|-1|1|2", + "extent": "7:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["8:3-8:9|0|3|32"] + }], + "vars": [{ + "id": 0, + "usr": 8599782646965457351, + "detailed_name": "int Foo::x", + "short_name": "x", + "declarations": ["2:14-2:15|0|2|1"], + "type": 1, + "uses": ["8:15-8:16|1|3|4"], + "kind": 8, + "storage": 3 + }] +} +*/ diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc new file mode 100644 index 000000000..ecf609308 --- /dev/null +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -0,0 +1,133 @@ +enum VarType {}; + +struct Holder { + static constexpr VarType static_var = (VarType)0x0; +}; + +const VarType Holder::static_var; + + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 5792006888140599735, + "detailed_name": "VarType", + "short_name": "VarType", + "kind": 10, + "declarations": [], + "spell": "1:6-1:13|-1|1|2", + "extent": "1:1-1:16|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["4:20-4:27|-1|1|4", "4:42-4:49|-1|1|4", "7:7-7:14|-1|1|4"] + }, { + "id": 1, + "usr": 10028537921178202800, + "detailed_name": "Holder", + "short_name": "Holder", + "kind": 23, + "declarations": [], + "spell": "3:8-3:14|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [], + "uses": ["7:15-7:21|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 7057400933868440116, + "detailed_name": "const VarType Holder::static_var", + "short_name": "static_var", + "hover": "const VarType Holder::static_var = (VarType)0x0", + "declarations": ["4:28-4:38|1|2|1"], + "spell": "7:23-7:33|1|2|2", + "extent": "7:1-7:33|-1|1|0", + "type": 0, + "uses": [], + "kind": 8, + "storage": 1 + }] +} +*/ + + + + + + + + + + + + + + + + + + + + + + + + + +//#include +//#include + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc new file mode 100644 index 000000000..412c85518 --- /dev/null +++ b/index_tests/usage/var_usage_extern.cc @@ -0,0 +1,54 @@ +extern int a; + +void foo() { + a = 5; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 16721564935990383768, + "detailed_name": "int a", + "short_name": "a", + "declarations": ["1:12-1:13|-1|1|1"], + "type": 0, + "uses": ["4:3-4:4|0|3|4"], + "kind": 13, + "storage": 2 + }] +} +*/ diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc new file mode 100644 index 000000000..26341c493 --- /dev/null +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -0,0 +1,54 @@ +void foo(int a) { + a += 10; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 11998306017310352355, + "detailed_name": "void foo(int a)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 10063793875496522529, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "1:14-1:15|0|3|2", + "extent": "1:10-1:15|0|3|0", + "type": 0, + "uses": ["2:3-2:4|0|3|4"], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc new file mode 100644 index 000000000..f9c0124ea --- /dev/null +++ b/index_tests/usage/var_usage_local.cc @@ -0,0 +1,55 @@ +void foo() { + int x; + x = 3; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-4:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 8534460107894911680, + "detailed_name": "int x", + "short_name": "x", + "declarations": [], + "spell": "2:7-2:8|0|3|2", + "extent": "2:3-2:8|0|3|0", + "type": 0, + "uses": ["3:3-3:4|0|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc new file mode 100644 index 000000000..db8572066 --- /dev/null +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -0,0 +1,72 @@ +void foo() { + int a; + a = 1; + { + int a; + a = 2; + } + a = 3; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 17941402366659878910, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "2:7-2:8|0|3|2", + "extent": "2:3-2:8|0|3|0", + "type": 0, + "uses": ["3:3-3:4|0|3|4", "8:3-8:4|0|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 11094102496276744608, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "5:9-5:10|0|3|2", + "extent": "5:5-5:10|0|3|0", + "type": 0, + "uses": ["6:5-6:6|0|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc new file mode 100644 index 000000000..e5c784acf --- /dev/null +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -0,0 +1,72 @@ +void foo(int a) { + a = 1; + { + int a; + a = 2; + } + a = 3; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 11998306017310352355, + "detailed_name": "void foo(int a)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-8:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 11608231465452906059, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "1:14-1:15|0|3|2", + "extent": "1:10-1:15|0|3|0", + "type": 0, + "uses": ["2:3-2:4|0|3|4", "7:3-7:4|0|3|4"], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 8011559936501990179, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "4:9-4:10|0|3|2", + "extent": "4:5-4:10|0|3|0", + "type": 0, + "uses": ["5:5-5:6|0|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc new file mode 100644 index 000000000..ab456631f --- /dev/null +++ b/index_tests/usage/var_usage_static.cc @@ -0,0 +1,57 @@ +static int a; + +void foo() { + a = 3; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 11823161916242867318, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "1:12-1:13|-1|1|2", + "extent": "1:1-1:13|-1|1|0", + "type": 0, + "uses": ["4:3-4:4|0|3|4"], + "kind": 13, + "storage": 3 + }] +} +*/ diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc new file mode 100644 index 000000000..cf676c635 --- /dev/null +++ b/index_tests/vars/class_member.cc @@ -0,0 +1,41 @@ +class Foo { + Foo* member; +}; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [0], + "uses": ["2:3-2:6|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 13799811842374292251, + "detailed_name": "Foo *Foo::member", + "short_name": "member", + "declarations": [], + "spell": "2:8-2:14|0|2|2", + "extent": "2:3-2:14|0|2|0", + "type": 0, + "uses": [], + "kind": 8, + "storage": 0 + }] +} +*/ diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc new file mode 100644 index 000000000..6b5d12081 --- /dev/null +++ b/index_tests/vars/class_static_member.cc @@ -0,0 +1,44 @@ +class Foo { + static Foo* member; +}; +Foo* Foo::member = nullptr; + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [0], + "instances": [0], + "uses": ["2:10-2:13|-1|1|4", "4:1-4:4|-1|1|4", "4:6-4:9|-1|1|4"] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 5844987037615239736, + "detailed_name": "Foo *Foo::member", + "short_name": "member", + "hover": "Foo *Foo::member = nullptr", + "declarations": ["2:15-2:21|0|2|1"], + "spell": "4:11-4:17|0|2|2", + "extent": "4:1-4:27|-1|1|0", + "type": 0, + "uses": [], + "kind": 8, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc new file mode 100644 index 000000000..a7ea0afae --- /dev/null +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -0,0 +1,53 @@ +class Foo { + static int member; +}; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] + }, { + "id": 1, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 5844987037615239736, + "detailed_name": "int Foo::member", + "short_name": "member", + "declarations": ["2:14-2:20|0|2|1"], + "type": 1, + "uses": [], + "kind": 8, + "storage": 3 + }] +} +*/ diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc new file mode 100644 index 000000000..42f6d581b --- /dev/null +++ b/index_tests/vars/deduce_auto_type.cc @@ -0,0 +1,71 @@ +class Foo {}; +void f() { + auto x = new Foo(); + auto* y = new Foo(); +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|-1|1|2", + "extent": "1:1-1:13|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["3:16-3:19|-1|1|4", "4:17-4:20|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 880549676430489861, + "detailed_name": "void f()", + "short_name": "f", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "2:6-2:7|-1|1|2", + "extent": "2:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 9275666070987716270, + "detailed_name": "Foo *x", + "short_name": "x", + "declarations": [], + "spell": "3:8-3:9|0|3|2", + "extent": "3:3-3:21|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 16202433437488621027, + "detailed_name": "Foo *y", + "short_name": "y", + "declarations": [], + "spell": "4:9-4:10|0|3|2", + "extent": "4:3-4:22|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc new file mode 100644 index 000000000..6f0adec7b --- /dev/null +++ b/index_tests/vars/function_local.cc @@ -0,0 +1,57 @@ +struct Foo; + +void foo() { + Foo* a; +} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["4:3-4:6|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 10782632605670042066, + "detailed_name": "Foo *a", + "short_name": "a", + "declarations": [], + "spell": "4:8-4:9|0|3|2", + "extent": "4:3-4:9|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc new file mode 100644 index 000000000..cc61eff72 --- /dev/null +++ b/index_tests/vars/function_param.cc @@ -0,0 +1,67 @@ +struct Foo; + +void foo(Foo* p0, Foo* p1) {} + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|-1|1|1"], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": ["3:10-3:13|-1|1|4", "3:19-3:22|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 8908726657907936744, + "detailed_name": "void foo(Foo *p0, Foo *p1)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-3:30|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 4580260577538694711, + "detailed_name": "Foo *p0", + "short_name": "p0", + "declarations": [], + "spell": "3:15-3:17|0|3|2", + "extent": "3:10-3:17|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 12071725611268840435, + "detailed_name": "Foo *p1", + "short_name": "p1", + "declarations": [], + "spell": "3:24-3:26|0|3|2", + "extent": "3:19-3:26|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc new file mode 100644 index 000000000..aa3fd2a70 --- /dev/null +++ b/index_tests/vars/function_param_unnamed.cc @@ -0,0 +1,26 @@ +void foo(int, int) {} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [], + "funcs": [{ + "id": 0, + "usr": 2747674671862363334, + "detailed_name": "void foo(int, int)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-1:22|-1|1|0", + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "vars": [] +} +*/ diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc new file mode 100644 index 000000000..0c4fa4a14 --- /dev/null +++ b/index_tests/vars/function_shadow_local.cc @@ -0,0 +1,72 @@ +void foo() { + int a; + a = 1; + { + int a; + a = 2; + } + a = 3; +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-9:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 3440226937504376525, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "2:7-2:8|0|3|2", + "extent": "2:3-2:8|0|3|0", + "type": 0, + "uses": ["3:3-3:4|0|3|4", "8:3-8:4|0|3|4"], + "kind": 13, + "storage": 1 + }, { + "id": 1, + "usr": 14700715011944976607, + "detailed_name": "int a", + "short_name": "a", + "declarations": [], + "spell": "5:9-5:10|0|3|2", + "extent": "5:5-5:10|0|3|0", + "type": 0, + "uses": ["6:5-6:6|0|3|4"], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc new file mode 100644 index 000000000..5f8a99882 --- /dev/null +++ b/index_tests/vars/function_shadow_param.cc @@ -0,0 +1,67 @@ +void foo(int p) { + { int p = 0; } +} +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0, 1], + "uses": [] + }], + "funcs": [{ + "id": 0, + "usr": 11998306017310352355, + "detailed_name": "void foo(int p)", + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|-1|1|2", + "extent": "1:1-3:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0, 1], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 5875271969926422921, + "detailed_name": "int p", + "short_name": "p", + "declarations": [], + "spell": "1:14-1:15|0|3|2", + "extent": "1:10-1:15|0|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 1 + }, { + "id": 1, + "usr": 2147918703972955240, + "detailed_name": "int p", + "short_name": "p", + "hover": "int p = 0", + "declarations": [], + "spell": "2:9-2:10|0|3|2", + "extent": "2:5-2:14|0|3|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc new file mode 100644 index 000000000..5d061ff7d --- /dev/null +++ b/index_tests/vars/global_variable.cc @@ -0,0 +1,38 @@ +static int global = 0; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 6834525061342585382, + "detailed_name": "int global", + "short_name": "global", + "hover": "int global = 0", + "declarations": [], + "spell": "1:12-1:18|-1|1|2", + "extent": "1:1-1:22|-1|1|0", + "type": 0, + "uses": [], + "kind": 13, + "storage": 3 + }] +} +*/ diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc new file mode 100644 index 000000000..f70c21bc9 --- /dev/null +++ b/index_tests/vars/global_variable_decl_only.cc @@ -0,0 +1,35 @@ +extern int global; +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 17, + "detailed_name": "", + "short_name": "", + "kind": 0, + "declarations": [], + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": [] + }], + "funcs": [], + "vars": [{ + "id": 0, + "usr": 9937941849651546906, + "detailed_name": "int global", + "short_name": "global", + "declarations": ["1:12-1:18|-1|1|1"], + "type": 0, + "uses": [], + "kind": 13, + "storage": 2 + }] +} +*/ diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc new file mode 100644 index 000000000..7d01422b8 --- /dev/null +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -0,0 +1,79 @@ +struct S {}; +using F = S; +void Foo() { + F a; +} + +// TODO: Should we also add a usage to |S|? + +/* +OUTPUT: +{ + "includes": [], + "skipped_by_preprocessor": [], + "types": [{ + "id": 0, + "usr": 4750332761459066907, + "detailed_name": "S", + "short_name": "S", + "kind": 23, + "declarations": [], + "spell": "1:8-1:9|-1|1|2", + "extent": "1:1-1:12|-1|1|0", + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:11-2:12|-1|1|4"] + }, { + "id": 1, + "usr": 7434820806199665424, + "detailed_name": "F", + "short_name": "F", + "kind": 252, + "hover": "using F = S", + "declarations": [], + "spell": "2:7-2:8|-1|1|2", + "extent": "2:1-2:12|-1|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [0], + "uses": ["2:7-2:8|-1|1|4", "4:3-4:4|-1|1|4"] + }], + "funcs": [{ + "id": 0, + "usr": 4654328188330986029, + "detailed_name": "void Foo()", + "short_name": "Foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|-1|1|2", + "extent": "3:1-5:2|-1|1|0", + "bases": [], + "derived": [], + "vars": [0], + "uses": [], + "callees": [] + }], + "vars": [{ + "id": 0, + "usr": 7730100248624586522, + "detailed_name": "F a", + "short_name": "a", + "declarations": [], + "spell": "4:5-4:6|0|3|2", + "extent": "4:3-4:6|0|3|0", + "type": 1, + "uses": [], + "kind": 13, + "storage": 1 + }] +} +*/ diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 520e9dcf8..4ae4e55b4 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -25,15 +25,15 @@ struct RealCacheManager : ICacheManager { WriteToFile(AppendSerializationFormat(cache_path), indexed_content); } - optional LoadCachedFileContents( + std::optional LoadCachedFileContents( const std::string& path) override { return ReadContent(GetCachePath(path)); } std::unique_ptr RawCacheLoad(const std::string& path) override { std::string cache_path = GetCachePath(path); - optional file_content = ReadContent(cache_path); - optional serialized_indexed_content = + std::optional file_content = ReadContent(cache_path); + std::optional serialized_indexed_content = ReadContent(AppendSerializationFormat(cache_path)); if (!file_content || !serialized_indexed_content) return nullptr; @@ -77,7 +77,7 @@ struct FakeCacheManager : ICacheManager { void WriteToCache(IndexFile& file) override { assert(false); } - optional LoadCachedFileContents( + std::optional LoadCachedFileContents( const std::string& path) override { for (const FakeCacheEntry& entry : entries_) { if (entry.path == path) { @@ -85,14 +85,14 @@ struct FakeCacheManager : ICacheManager { } } - return nullopt; + return std::nullopt; } std::unique_ptr RawCacheLoad(const std::string& path) override { for (const FakeCacheEntry& entry : entries_) { if (entry.path == path) { return Deserialize(SerializeFormat::Json, path, entry.json, "", - nullopt); + std::nullopt); } } diff --git a/src/cache_manager.h b/src/cache_manager.h index e5fd96720..f175544b7 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -38,7 +38,7 @@ struct ICacheManager { virtual void WriteToCache(IndexFile& file) = 0; - virtual optional LoadCachedFileContents( + virtual std::optional LoadCachedFileContents( const std::string& path) = 0; // Iterate over all loaded caches. diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 8584b5ad3..1ac65e46d 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -29,7 +29,7 @@ unsigned Flags() { unsigned GetCompletionPriority(const CXCompletionString& str, CXCursorKind result_kind, - const optional& typedText) { + const std::optional& typedText) { unsigned priority = clang_getCompletionPriority(str); // XXX: What happens if priority overflows? @@ -396,7 +396,7 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, std::vector ls_diagnostics; unsigned num_diagnostics = clang_getNumDiagnostics((*tu)->cx_tu); for (unsigned i = 0; i < num_diagnostics; ++i) { - optional diagnostic = BuildAndDisposeDiagnostic( + std::optional diagnostic = BuildAndDisposeDiagnostic( clang_getDiagnostic((*tu)->cx_tu, i), session->file.filename); // Filter messages like "too many errors emitted, stopping now // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after @@ -501,7 +501,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { { if (request->on_complete) { std::vector ls_result; - // this is a guess but can be larger in case of optional parameters, + // this is a guess but can be larger in case of std::optional parameters, // as they may be expanded into multiple items ls_result.reserve(cx_results->NumResults); @@ -605,7 +605,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { ls_diagnostics.reserve(num_diagnostics); for (unsigned i = 0; i < num_diagnostics; ++i) { CXDiagnostic cx_diag = clang_getDiagnostic(session->tu->cx_tu, i); - optional diagnostic = + std::optional diagnostic = BuildAndDisposeDiagnostic(cx_diag, path); // Filter messages like "too many errors emitted, stopping now // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after diff --git a/src/clang_complete.h b/src/clang_complete.h index 03197a602..0ed458962 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -23,7 +23,7 @@ struct CompletionSession ClangIndex index; // When |tu| was last parsed. - optional> + std::optional> tu_last_parsed_at; // Acquired when |tu| is being used. @@ -67,7 +67,7 @@ struct ClangCompleteManager { lsRequestId id; lsTextDocumentIdentifier document; - optional position; + std::optional position; OnComplete on_complete; // May be null/empty. bool emit_diagnostics = false; }; diff --git a/src/clang_cursor.h b/src/clang_cursor.h index 23eed1bb1..53f94cfaa 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -4,7 +4,7 @@ #include "position.h" #include -#include +#include #include #include diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index fbbdf396e..f4240df3c 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -212,7 +212,7 @@ struct ConstructorCache { // Tries to lookup a constructor in |type_usr| that takes arguments most // closely aligned to |param_type_desc|. - optional TryFindConstructorUsr( + std::optional TryFindConstructorUsr( Usr type_usr, const std::vector& param_type_desc) { auto count_matching_prefix_length = [](const char* a, const char* b) { @@ -235,10 +235,10 @@ struct ConstructorCache { // available, return an empty result. auto ctors_it = constructors_.find(type_usr); if (ctors_it == constructors_.end()) - return nullopt; + return std::nullopt; const std::vector& ctors = ctors_it->second; if (ctors.empty()) - return nullopt; + return std::nullopt; Usr best_usr = ctors[0].usr; int best_score = INT_MIN; @@ -352,7 +352,7 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { param->seen_files.push_back(file_name); // Set modification time. - optional modification_time = GetLastModificationTime(file_name); + std::optional modification_time = GetLastModificationTime(file_name); LOG_IF_S(ERROR, !modification_time) << "Failed fetching modification time for " << file_name; if (modification_time) @@ -426,7 +426,7 @@ std::string GetDocumentContentInRange(CXTranslationUnit cx_tu, unsigned num_tokens; clang_tokenize(cx_tu, range, &tokens, &num_tokens); - optional previous_token_range; + std::optional previous_token_range; for (unsigned i = 0; i < num_tokens; ++i) { // Add whitespace between the previous token and this one. @@ -537,7 +537,7 @@ void SetTypeName(IndexType* type, // strips // qualifies from |cursor| (ie, Foo* => Foo) and removes template arguments // (ie, Foo => Foo<*,*>). -optional ResolveToDeclarationType(IndexFile* db, +std::optional ResolveToDeclarationType(IndexFile* db, ClangCursor cursor, IndexParam* param) { ClangType type = cursor.get_type(); @@ -561,7 +561,7 @@ optional ResolveToDeclarationType(IndexFile* db, const char* str_usr = clang_getCString(cx_usr); if (!str_usr || str_usr[0] == '\0') { clang_disposeString(cx_usr); - return nullopt; + return std::nullopt; } Usr usr = HashUsr(str_usr); clang_disposeString(cx_usr); @@ -633,8 +633,8 @@ void SetVarDetail(IndexVar* var, clang_getResultType(deref).kind == CXType_Invalid && clang_getElementType(deref).kind == CXType_Invalid) { const FileContents& fc = param->file_contents[db->path]; - optional spell_end = fc.ToOffset(cursor.get_spell().end); - optional extent_end = fc.ToOffset(cursor.get_extent().end); + std::optional spell_end = fc.ToOffset(cursor.get_spell().end); + std::optional extent_end = fc.ToOffset(cursor.get_extent().end); if (extent_end && *spell_end < *extent_end) def.hover = std::string(def.detailed_name.c_str()) + fc.content.substr(*spell_end, *extent_end - *spell_end); @@ -649,7 +649,7 @@ void SetVarDetail(IndexVar* var, def.short_name_size = short_name.size(); if (is_first_seen) { - optional var_type = + std::optional var_type = ResolveToDeclarationType(db, cursor, param); if (var_type) { // Don't treat enum definition variables as instantiations. @@ -844,7 +844,7 @@ void OnIndexDiagnostic(CXClientData client_data, continue; // Build diagnostic. - optional ls_diagnostic = + std::optional ls_diagnostic = BuildAndDisposeDiagnostic(diagnostic, db->path); if (ls_diagnostic) db->diagnostics_.push_back(*ls_diagnostic); @@ -898,14 +898,14 @@ void Dump(ClangCursor cursor) { struct FindChildOfKindParam { CXCursorKind target_kind; - optional result; + std::optional result; FindChildOfKindParam(CXCursorKind target_kind) : target_kind(target_kind) {} }; ClangCursor::VisitResult FindTypeVisitor(ClangCursor cursor, ClangCursor parent, - optional* result) { + std::optional* result) { switch (cursor.get_kind()) { case CXCursor_TypeRef: case CXCursor_TemplateRef: @@ -918,8 +918,8 @@ ClangCursor::VisitResult FindTypeVisitor(ClangCursor cursor, return ClangCursor::VisitResult::Recurse; } -optional FindType(ClangCursor cursor) { - optional result; +std::optional FindType(ClangCursor cursor) { + std::optional result; cursor.VisitChildren(&FindTypeVisitor, &result); return result; } @@ -932,12 +932,12 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) { struct VisitDeclForTypeUsageParam { IndexFile* db; - optional toplevel_type; + std::optional toplevel_type; int has_processed_any = false; - optional previous_cursor; - optional initial_type; + std::optional previous_cursor; + std::optional initial_type; - VisitDeclForTypeUsageParam(IndexFile* db, optional toplevel_type) + VisitDeclForTypeUsageParam(IndexFile* db, std::optional toplevel_type) : db(db), toplevel_type(toplevel_type) {} }; @@ -964,7 +964,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, std::string name = cursor.get_referenced().get_spell_name(); if (name == ref_type->def.ShortName()) { AddUseSpell(db, ref_type->uses, cursor); - param->toplevel_type = nullopt; + param->toplevel_type = std::nullopt; return; } } @@ -1035,10 +1035,10 @@ ClangCursor::VisitResult VisitDeclForTypeUsageVisitor( // template. // We use |toplevel_type| to attribute the use to the specialized template // instead of the primary template. -optional AddDeclTypeUsages( +std::optional AddDeclTypeUsages( IndexFile* db, ClangCursor decl_cursor, - optional toplevel_type, + std::optional toplevel_type, const CXIdxContainerInfo* semantic_container, const CXIdxContainerInfo* lexical_container) { // @@ -1161,7 +1161,7 @@ optional AddDeclTypeUsages( return param.initial_type; CXType cx_under = clang_getTypedefDeclUnderlyingType(decl_cursor.cx_cursor); if (cx_under.kind == CXType_Invalid) - return nullopt; + return std::nullopt; return db->ToTypeId(ClangType(cx_under).strip_qualifiers().get_usr_hash()); } @@ -1320,7 +1320,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, // The cursor extent includes `type name`, not just `name`. There // seems no way to extract the spelling range of `type` and we do // not want to do subtraction here. - // See https://github.com/jacobdufault/cquery/issues/252 + // See https://github.com/cquery-project/cquery/issues/252 AddUse(db, ref_type_index->uses, ref_cursor.get_extent(), ref_cursor.get_lexical_parent()); } @@ -1555,7 +1555,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetVarDetail(var, std::string(decl->entityInfo->name), decl->cursor, decl->semanticContainer, !decl->isRedeclaration, db, param); - // FIXME https://github.com/jacobdufault/cquery/issues/239 + // FIXME https://github.com/jacobdufault/ccls/issues/239 var->def.kind = GetSymbolKind(decl->entityInfo->kind); if (var->def.kind == lsSymbolKind::Variable && decl->cursor.kind == CXCursor_ParmDecl) @@ -1631,7 +1631,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // We don't actually need to know the return type, but we need to mark it // as an interesting usage. - AddDeclTypeUsages(db, cursor, nullopt, decl->semanticContainer, + AddDeclTypeUsages(db, cursor, std::nullopt, decl->semanticContainer, decl->lexicalContainer); // Add definition or declaration. This is a bit tricky because we treat @@ -1753,8 +1753,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // Note we want to fetch the first TypeRef. Running // ResolveCursorType(decl->cursor) would return // the type of the typedef/using, not the type of the referenced type. - optional alias_of = AddDeclTypeUsages( - db, cursor, nullopt, decl->semanticContainer, decl->lexicalContainer); + std::optional alias_of = AddDeclTypeUsages( + db, cursor, std::nullopt, decl->semanticContainer, decl->lexicalContainer); IndexTypeId type_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); IndexType* type = db->Resolve(type_id); @@ -1777,11 +1777,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. // TODO Think how to display multi-line declaration like `typedef struct { - // ... } foo;` https://github.com/jacobdufault/cquery/issues/29 + // ... } foo;` https://github.com/jacobdufault/ccls/issues/29 if (extent.end.line - extent.start.line < kMaxLinesDisplayTypeAliasDeclarations) { FileContents& fc = param->file_contents[db->path]; - optional extent_start = fc.ToOffset(extent.start), + std::optional extent_start = fc.ToOffset(extent.start), spell_start = fc.ToOffset(spell.start), spell_end = fc.ToOffset(spell.end), extent_end = fc.ToOffset(extent.end); @@ -1863,7 +1863,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { origin->def.kind = type->def.kind; } // TODO The name may be assigned in |ResolveToDeclarationType| but - // |spell| is nullopt. + // |spell| is std::nullopt. CXFile origin_file; Range origin_spell = origin_cursor.get_spell(&origin_file); if (!origin->def.spell && file == origin_file) { @@ -1905,9 +1905,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { for (unsigned int i = 0; i < class_info->numBases; ++i) { const CXIdxBaseClassInfo* base_class = class_info->bases[i]; - AddDeclTypeUsages(db, base_class->cursor, nullopt, + AddDeclTypeUsages(db, base_class->cursor, std::nullopt, decl->semanticContainer, decl->lexicalContainer); - optional parent_type_id = + std::optional parent_type_id = ResolveToDeclarationType(db, base_class->cursor, param); // type_def ptr could be invalidated by ResolveToDeclarationType and // TemplateVisitor. @@ -1924,7 +1924,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { } } -// https://github.com/jacobdufault/cquery/issues/174 +// https://github.com/jacobdufault/ccls/issues/174 // Type-dependent member access expressions do not have accurate spelling // ranges. // @@ -1946,7 +1946,7 @@ void CheckTypeDependentMemberRefExpr(Range* spell, cursor.get_spell_name().empty()) { *spell = cursor.get_extent().RemovePrefix(spell->end); const FileContents& fc = param->file_contents[db->path]; - optional maybe_period = fc.ToOffset(spell->start); + std::optional maybe_period = fc.ToOffset(spell->start); if (maybe_period) { int i = *maybe_period; if (fc.content[i] == '.') @@ -2114,7 +2114,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { str_begin("make", ref->referencedEntity->name)) { // Try to find the return type of called function. That type will have // the constructor function we add a usage to. - optional opt_found_type = FindType(ref->cursor); + std::optional opt_found_type = FindType(ref->cursor); if (opt_found_type) { Usr ctor_type_usr = opt_found_type->get_referenced().get_usr_hash(); ClangCursor call_cursor = ref->cursor; @@ -2129,7 +2129,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } // Try to find the constructor and add a reference. - optional ctor_usr = + std::optional ctor_usr = param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc); if (ctor_usr) { IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr)); @@ -2164,7 +2164,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } } -optional>> Parse( +std::optional>> Parse( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -2174,7 +2174,7 @@ optional>> Parse( ClangIndex* index, bool dump_ast) { if (!config->index.enabled) - return nullopt; + return std::nullopt; file = NormalizePath(file); @@ -2194,7 +2194,7 @@ optional>> Parse( CXTranslationUnit_KeepGoing | CXTranslationUnit_DetailedPreprocessingRecord); if (!tu) - return nullopt; + return std::nullopt; perf->index_parse = timer.ElapsedMicrosecondsAndReset(); @@ -2205,7 +2205,7 @@ optional>> Parse( args, unsaved_files); } -optional>> ParseWithTu( +std::optional>> ParseWithTu( Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, @@ -2250,7 +2250,7 @@ optional>> ParseWithTu( if (index_result != CXError_Success) { LOG_S(ERROR) << "Indexing " << file << " failed with errno=" << index_result; - return nullopt; + return std::nullopt; } clang_IndexAction_dispose(index_action); diff --git a/src/clang_translation_unit.cc b/src/clang_translation_unit.cc index 88365f23a..6062e4178 100644 --- a/src/clang_translation_unit.cc +++ b/src/clang_translation_unit.cc @@ -87,7 +87,7 @@ std::unique_ptr ClangTranslationUnit::Create( // -fsyntax-only so they don't do a full compile. 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 " + "issue, and report a bug. ccls will then filter the flag for you " " automatically:\n$ " + StringJoin(args, " ") + " -fsyntax-only"; }; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 03a35d754..d89f78567 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -23,7 +23,7 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) { } // namespace // See clang_formatDiagnostic -optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, +std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, const std::string& path) { // Get diagnostic location. CXFile file; @@ -33,7 +33,7 @@ optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, if (file && path != FileName(file)) { clang_disposeDiagnostic(diagnostic); - return nullopt; + return std::nullopt; } unsigned end_line = start_line, end_column = start_column, diff --git a/src/clang_utils.h b/src/clang_utils.h index 24175efd8..652368761 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -6,11 +6,11 @@ #if USE_CLANG_CXX #include #endif -#include +#include #include -optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, +std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, const std::string& path); // Returns the absolute path to |file|. diff --git a/src/code_complete_cache.h b/src/code_complete_cache.h index 76ed61049..39696f1bc 100644 --- a/src/code_complete_cache.h +++ b/src/code_complete_cache.h @@ -2,7 +2,7 @@ #include "lsp_completion.h" -#include +#include #include @@ -11,8 +11,8 @@ // that happens. struct CodeCompleteCache { // NOTE: Make sure to access these variables under |WithLock|. - optional cached_path_; - optional cached_completion_position_; + std::optional cached_path_; + std::optional cached_completion_position_; std::vector cached_results_; std::mutex mutex_; diff --git a/src/command_line.cc b/src/command_line.cc index 91f96e0d8..700e5b10d 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -61,18 +61,18 @@ std::vector kEmptyArgs; bool ShouldDisplayMethodTiming(MethodType type) { return type != kMethodType_TextDocumentPublishDiagnostics && - type != kMethodType_CqueryPublishInactiveRegions && + type != kMethodType_CclsPublishInactiveRegions && type != kMethodType_Unknown; } void PrintHelp() { std::cout - << R"help(cquery is a low-latency C/C++/Objective-C language server. + << R"help(ccls is a low-latency C/C++/Objective-C language server. Mode: --clang-sanity-check Run a simple index test. Verifies basic clang functionality. - Needs to be executed from the cquery root checkout directory. + Needs to be executed from the ccls root checkout directory. --test-unit Run unit tests. --test-index Run index tests. opt_filter_path can be used to specify which @@ -281,7 +281,7 @@ void LaunchStdinLoop(Config* config, auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; - optional err = + std::optional err = MessageRegistry::instance()->ReadMessageFromStdin(&message); // Message parsing can fail if we don't recognize the method. diff --git a/src/config.h b/src/config.h index 9030a9031..d7353f81a 100644 --- a/src/config.h +++ b/src/config.h @@ -6,12 +6,12 @@ /* The language client plugin needs to send initialization options in the -`initialize` request to the cquery language server. The only required option is +`initialize` request to the ccls language server. The only required option is `cacheDirectory`, which is where index files will be stored. { "initializationOptions": { - "cacheDirectory": "/tmp/cquery" + "cacheDirectory": "/tmp/ccls" } } @@ -42,11 +42,11 @@ struct Config { // takes only 60% of the corresponding JSON size, but is difficult to inspect. // msgpack does not store map keys and you need to re-index whenever a struct // member has changed. - SerializeFormat cacheFormat = SerializeFormat::Json; + SerializeFormat cacheFormat = SerializeFormat::MessagePack; // Value to use for clang -resource-dir if not present in // compile_commands.json. // - // cquery includes a resource directory, this should not need to be configured + // ccls includes a resource directory, this should not need to be configured // unless you're using an esoteric configuration. Consider reporting a bug and // fixing upstream instead of configuring this. // @@ -56,8 +56,8 @@ struct Config { // Additional arguments to pass to clang. std::vector extraClangArguments; - // If true, cquery will send progress reports while indexing - // How often should cquery send progress report messages? + // If true, ccls will send progress reports while indexing + // How often should ccls send progress report messages? // -1: never // 0: as often as possible // xxx: at most every xxx milliseconds @@ -66,7 +66,7 @@ struct Config { // available and may exceed this value. // // This does not guarantee a progress report will be delivered every - // interval; it could take significantly longer if cquery is completely idle. + // interval; it could take significantly longer if ccls is completely idle. int progressReportFrequencyMs = 500; // If true, document links are reported for #include directives. @@ -74,7 +74,7 @@ struct Config { // Version of the client. If undefined the version check is skipped. Used to // inform users their vscode client is too old and needs to be updated. - optional clientVersion; + std::optional clientVersion; struct ClientCapability { // TextDocumentClientCapabilities.completion.completionItem.snippetSupport @@ -107,13 +107,13 @@ struct Config { // items can end up truncated by the UIs. bool detailedLabel = false; - // On large projects, completion can take a long time. By default if cquery + // On large projects, completion can take a long time. By default if ccls // receives multiple completion requests while completion is still running // it will only service the newest request. If this is set to false then all // completion requests will be serviced. bool dropOldRequests = true; - // If true, filter and sort completion response. cquery filters and sorts + // If true, filter and sort completion response. ccls filters and sorts // completions to try to be nicer to clients that can't handle big numbers // of completion candidates. This behaviour can be disabled by specifying // false for the option. This option is the most useful for LSP clients @@ -146,7 +146,7 @@ struct Config { // blacklisted files. std::vector blacklist; - // How often should cquery publish diagnostics in completion? + // How often should ccls publish diagnostics in completion? // -1: never // 0: as often as possible // xxx: at most every xxx milliseconds @@ -172,7 +172,7 @@ struct Config { // hueristics. // // For example, this will show constructor calls for std::make_unique - // invocations. Specifically, cquery will try to attribute a ctor call + // invocations. Specifically, ccls will try to attribute a ctor call // whenever the function name starts with make (ignoring case). bool attributeMakeCallsToCtor = true; diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 13042d795..3b1d6759a 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -9,11 +9,11 @@ namespace { -optional GetFileContents(const std::string& path, +std::optional GetFileContents(const std::string& path, FileContentsMap* file_contents) { auto it = file_contents->find(path); if (it == file_contents->end()) { - optional content = ReadContent(path); + std::optional content = ReadContent(path); if (content) (*file_contents)[path] = FileContents(path, *content); return content; @@ -75,7 +75,7 @@ IndexFile* FileConsumer::TryConsumeFile(CXFile file, } // Read the file contents, if we fail then we cannot index the file. - optional contents = + std::optional contents = GetFileContents(file_name, file_contents_map); if (!contents) { *is_first_ownership = false; diff --git a/src/file_contents.cc b/src/file_contents.cc index 4e716e65a..5a7bc0f44 100644 --- a/src/file_contents.cc +++ b/src/file_contents.cc @@ -11,19 +11,19 @@ FileContents::FileContents(const std::string& path, const std::string& content) } } -optional FileContents::ToOffset(Position p) const { +std::optional FileContents::ToOffset(Position p) const { if (0 <= p.line && size_t(p.line) < line_offsets_.size()) { int ret = line_offsets_[p.line] + p.column; if (size_t(ret) < content.size()) return ret; } - return nullopt; + return std::nullopt; } -optional FileContents::ContentsInRange(Range range) const { - optional start_offset = ToOffset(range.start), +std::optional FileContents::ContentsInRange(Range range) const { + std::optional start_offset = ToOffset(range.start), end_offset = ToOffset(range.end); if (start_offset && end_offset && *start_offset < *end_offset) return content.substr(*start_offset, *end_offset - *start_offset); - return nullopt; + return std::nullopt; } diff --git a/src/file_contents.h b/src/file_contents.h index 0a6cffb51..21c484d40 100644 --- a/src/file_contents.h +++ b/src/file_contents.h @@ -2,9 +2,8 @@ #include "position.h" -#include "optional.h" - #include +#include #include #include @@ -12,8 +11,8 @@ struct FileContents { FileContents(); FileContents(const std::string& path, const std::string& content); - optional ToOffset(Position p) const; - optional ContentsInRange(Range range) const; + std::optional ToOffset(Position p) const; + std::optional ContentsInRange(Range range) const; std::string path; std::string content; diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 336815b72..52a89986f 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/src/iindexer.cc b/src/iindexer.cc index e07584100..16085bc38 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -6,7 +6,7 @@ namespace { struct ClangIndexer : IIndexer { ~ClangIndexer() override = default; - optional>> Index( + std::optional>> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -50,7 +50,7 @@ struct TestIndexer : IIndexer { ~TestIndexer() override = default; - optional>> Index( + std::optional>> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -61,7 +61,7 @@ struct TestIndexer : IIndexer { if (it == indexes.end()) { // Don't return any indexes for unexpected data. assert(false && "no indexes"); - return nullopt; + return std::nullopt; } // FIXME: allow user to control how many times we return the index for a diff --git a/src/iindexer.h b/src/iindexer.h index f8a453472..d66489906 100644 --- a/src/iindexer.h +++ b/src/iindexer.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -34,7 +34,7 @@ struct IIndexer { std::initializer_list entries); virtual ~IIndexer() = default; - virtual optional>> Index( + virtual std::optional>> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 4c0102ba6..9c087ef46 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -33,7 +33,7 @@ struct Out_Progress : public lsOutMessage { int onIndexedCount = 0; int activeThreads = 0; }; - std::string method = "$cquery/progress"; + std::string method = "$ccls/progress"; Params params; }; MAKE_REFLECT_STRUCT(Out_Progress::Params, @@ -63,23 +63,23 @@ struct IterationLoop { struct IModificationTimestampFetcher { virtual ~IModificationTimestampFetcher() = default; - virtual optional GetModificationTime(const std::string& path) = 0; + virtual std::optional GetModificationTime(const std::string& path) = 0; }; struct RealModificationTimestampFetcher : IModificationTimestampFetcher { ~RealModificationTimestampFetcher() override = default; // IModificationTimestamp: - optional GetModificationTime(const std::string& path) override { + std::optional GetModificationTime(const std::string& path) override { return GetLastModificationTime(path); } }; struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { - std::unordered_map> entries; + std::unordered_map> entries; ~FakeModificationTimestampFetcher() override = default; // IModificationTimestamp: - optional GetModificationTime(const std::string& path) override { + std::optional GetModificationTime(const std::string& path) override { auto it = entries.find(path); assert(it != entries.end()); return it->second; @@ -159,8 +159,8 @@ ShouldParse FileNeedsParse( IndexFile* opt_previous_index, const std::string& path, const std::vector& args, - const optional& from) { - auto unwrap_opt = [](const optional& opt) -> std::string { + const std::optional& from) { + auto unwrap_opt = [](const std::optional& opt) -> std::string { if (opt) return " (via " + *opt + ")"; return ""; @@ -173,14 +173,14 @@ ShouldParse FileNeedsParse( return ShouldParse::No; } - optional modification_timestamp = + std::optional modification_timestamp = modification_timestamp_fetcher->GetModificationTime(path); // Cannot find file. if (!modification_timestamp) return ShouldParse::NoSuchFile; - optional last_cached_modification = + std::optional last_cached_modification = timestamp_manager->GetLastCachedModificationTime(cache_manager.get(), path); @@ -236,7 +236,7 @@ CacheLoadResult TryLoadFromCache( ShouldParse path_state = FileNeedsParse( is_interactive, timestamp_manager, modification_timestamp_fetcher, import_manager, cache_manager, previous_index, path_to_index, entry.args, - nullopt); + std::nullopt); if (path_state == ShouldParse::Yes) file_consumer_shared->Reset(path_to_index); @@ -327,14 +327,14 @@ std::vector PreloadFileContents( // still valid. if so, we can use it, otherwise we need to load from disk. auto get_latest_content = [](const std::string& path, int64_t cached_time, const std::string& cached) -> std::string { - optional mod_time = GetLastModificationTime(path); + std::optional mod_time = GetLastModificationTime(path); if (!mod_time) return ""; if (*mod_time == cached_time) return cached; - optional fresh_content = ReadContent(path); + std::optional fresh_content = ReadContent(path); if (!fresh_content) { LOG_S(ERROR) << "Failed to load content for " << path; return ""; @@ -437,7 +437,7 @@ bool IndexMain_DoParse( ImportManager* import_manager, IIndexer* indexer) { auto* queue = QueueManager::instance(); - optional request = queue->index_request.TryPopFront(); + std::optional request = queue->index_request.TryPopFront(); if (!request) return false; @@ -456,7 +456,7 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { bool did_work = false; IterationLoop loop; while (loop.Next()) { - optional response = queue->on_id_mapped.TryPopFront(); + std::optional response = queue->on_id_mapped.TryPopFront(); if (!response) return did_work; @@ -524,7 +524,7 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { bool IndexMain_LoadPreviousIndex() { auto* queue = QueueManager::instance(); - optional response = queue->load_previous_index.TryPopFront(); + std::optional response = queue->load_previous_index.TryPopFront(); if (!response) return false; @@ -540,14 +540,14 @@ bool IndexMain_LoadPreviousIndex() { bool IndexMergeIndexUpdates() { auto* queue = QueueManager::instance(); - optional root = queue->on_indexed.TryPopBack(); + std::optional root = queue->on_indexed.TryPopBack(); if (!root) return false; bool did_merge = false; IterationLoop loop; while (loop.Next()) { - optional to_join = queue->on_indexed.TryPopBack(); + std::optional to_join = queue->on_indexed.TryPopBack(); if (!to_join) break; did_merge = true; @@ -767,7 +767,7 @@ bool QueryDb_ImportMain(Config* config, IterationLoop loop; while (loop.Next()) { - optional request = queue->do_id_map.TryPopFront(); + std::optional request = queue->do_id_map.TryPopFront(); if (!request) break; did_work = true; @@ -776,7 +776,7 @@ bool QueryDb_ImportMain(Config* config, loop.Reset(); while (loop.Next()) { - optional response = queue->on_indexed.TryPopFront(); + std::optional response = queue->on_indexed.TryPopFront(); if (!response) break; did_work = true; @@ -839,7 +839,7 @@ TEST_SUITE("ImportPipeline") { opt_previous_index = std::make_unique("---.cc", ""); opt_previous_index->args = old_args; } - optional from; + std::optional from; if (is_dependency) from = std::string("---.cc"); return FileNeedsParse(is_interactive /*is_interactive*/, @@ -850,7 +850,7 @@ TEST_SUITE("ImportPipeline") { // A file with no timestamp is not imported, since this implies the file no // longer exists on disk. - modification_timestamp_fetcher.entries["bar.h"] = nullopt; + modification_timestamp_fetcher.entries["bar.h"] = std::nullopt; REQUIRE(check("bar.h", false /*is_dependency*/) == ShouldParse::NoSuchFile); // A dependency is only imported once. diff --git a/src/include_complete.cc b/src/include_complete.cc index f063d6d6e..19f48c8ec 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -211,12 +211,12 @@ void IncludeComplete::InsertStlIncludes() { } } -optional IncludeComplete::FindCompletionItemForAbsolutePath( +std::optional IncludeComplete::FindCompletionItemForAbsolutePath( const std::string& absolute_path) { std::lock_guard lock(completion_items_mutex); auto it = absolute_path_to_completion_item.find(absolute_path); if (it == absolute_path_to_completion_item.end()) - return nullopt; + return std::nullopt; return completion_items[it->second]; } diff --git a/src/include_complete.h b/src/include_complete.h index 9806cffe7..474381132 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -24,7 +24,7 @@ struct IncludeComplete { bool use_angle_brackets); void InsertStlIncludes(); - optional FindCompletionItemForAbsolutePath( + std::optional FindCompletionItemForAbsolutePath( const std::string& absolute_path); // Insert item to |completion_items|. diff --git a/src/indexer.h b/src/indexer.h index 922e75249..025a27127 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -16,8 +16,8 @@ #include "symbol.h" #include "utils.h" -#include -#include +#include +#include #include #include @@ -192,7 +192,7 @@ struct TypeDefDefinitionData { return std::string_view(detailed_name.c_str() + short_name_offset, short_name_size); } - // Used by cquery_inheritance_hierarchy.cc:Expand generic lambda + // Used by ccls_inheritance_hierarchy.cc:Expand generic lambda std::string_view DetailedName(bool) const { return detailed_name; } }; template @@ -464,7 +464,7 @@ struct IndexFile { // For MessagePack cache files. // JSON has good forward compatibility because field addition/deletion do not // harm but currently no efforts have been made to make old MessagePack cache - // files accepted by newer cquery. + // files accepted by newer ccls. static const int kMinorVersion; std::string path; @@ -519,7 +519,7 @@ struct NamespaceHelper { // |desired_index_file| is the (h or cc) file which has actually changed. // |dependencies| are the existing dependencies of |import_file| if this is a // reparse. -optional>> Parse( +std::optional>> Parse( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -528,7 +528,7 @@ optional>> Parse( PerformanceImportFile* perf, ClangIndex* index, bool dump_ast = false); -optional>> ParseWithTu( +std::optional>> ParseWithTu( Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, diff --git a/src/lex_utils.cc b/src/lex_utils.cc index ebbe496a6..ff0406885 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -47,7 +47,7 @@ lsPosition CharPos(std::string_view search, } // TODO: eliminate |line_number| param. -optional ExtractQuotedRange(int line_number, const std::string& line) { +std::optional ExtractQuotedRange(int line_number, const std::string& line) { // Find starting and ending quote. int start = 0; while (start < (int)line.size()) { @@ -57,7 +57,7 @@ optional ExtractQuotedRange(int line_number, const std::string& line) { break; } if (start == (int)line.size()) - return nullopt; + return std::nullopt; int end = (int)line.size(); while (end > 0) { @@ -68,14 +68,14 @@ optional ExtractQuotedRange(int line_number, const std::string& line) { } if (start >= end) - return nullopt; + return std::nullopt; return lsRange(lsPosition(line_number, start), lsPosition(line_number, end)); } void LexFunctionDeclaration(const std::string& buffer_content, lsPosition declaration_spelling, - optional type_name, + std::optional type_name, std::string* insert_text, int* newlines_after_name) { int name_start = GetOffsetForPosition(declaration_spelling, buffer_content); @@ -245,7 +245,7 @@ TEST_SUITE("LexFunctionDeclaration") { std::string insert_text; int newlines_after_name = 0; - LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text, + LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, &newlines_after_name); REQUIRE(insert_text == "void Foo() {\n}"); REQUIRE(newlines_after_name == 0); @@ -286,7 +286,7 @@ TEST_SUITE("LexFunctionDeclaration") { std::string insert_text; int newlines_after_name = 0; - LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text, + LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, &newlines_after_name); REQUIRE(insert_text == "std::vector Foo() {\n}"); REQUIRE(newlines_after_name == 0); @@ -303,7 +303,7 @@ TEST_SUITE("LexFunctionDeclaration") { std::string insert_text; int newlines_after_name = 0; - LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text, + LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, &newlines_after_name); REQUIRE(insert_text == "std::function < int() > \n Foo() {\n}"); REQUIRE(newlines_after_name == 0); @@ -320,7 +320,7 @@ TEST_SUITE("LexFunctionDeclaration") { std::string insert_text; int newlines_after_name = 0; - LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text, + LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, &newlines_after_name); REQUIRE(insert_text == "void Foo(int a,\n\n int b) {\n}"); REQUIRE(newlines_after_name == 2); diff --git a/src/lex_utils.h b/src/lex_utils.h index 7d860aced..6fbc68645 100644 --- a/src/lex_utils.h +++ b/src/lex_utils.h @@ -2,7 +2,7 @@ #include "lsp.h" -#include +#include #include #include @@ -15,11 +15,11 @@ lsPosition CharPos(std::string_view search, int character_offset = 0); // TODO: eliminate |line_number| param. -optional ExtractQuotedRange(int line_number, const std::string& line); +std::optional ExtractQuotedRange(int line_number, const std::string& line); void LexFunctionDeclaration(const std::string& buffer_content, lsPosition declaration_spelling, - optional type_name, + std::optional type_name, std::string* insert_text, int* newlines_after_name); diff --git a/src/lsp.cc b/src/lsp.cc index 07daebe67..bebe3cf8b 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -20,16 +20,16 @@ lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { } // Reads a JsonRpc message. |read| returns the next input character. -optional ReadJsonRpcContentFrom( - std::function()> read) { +std::optional ReadJsonRpcContentFrom( + std::function()> read) { // Read the content length. It is terminated by the "\r\n" sequence. int exit_seq = 0; std::string stringified_content_length; while (true) { - optional opt_c = read(); + std::optional opt_c = read(); if (!opt_c) { LOG_S(INFO) << "No more input when reading content length header"; - return nullopt; + return std::nullopt; } char c = *opt_c; @@ -47,22 +47,22 @@ optional ReadJsonRpcContentFrom( // There is always a "\r\n" sequence before the actual content. auto expect_char = [&](char expected) { - optional opt_c = read(); + std::optional opt_c = read(); return opt_c && *opt_c == expected; }; if (!expect_char('\r') || !expect_char('\n')) { LOG_S(INFO) << "Unexpected token (expected \r\n sequence)"; - return nullopt; + return std::nullopt; } // Read content. std::string content; content.reserve(content_length); for (int i = 0; i < content_length; ++i) { - optional c = read(); + std::optional c = read(); if (!c) { LOG_S(INFO) << "No more input when reading content body"; - return nullopt; + return std::nullopt; } content += *c; } @@ -72,13 +72,13 @@ optional ReadJsonRpcContentFrom( return content; } -std::function()> MakeContentReader(std::string* content, +std::function()> MakeContentReader(std::string* content, bool can_be_empty) { - return [content, can_be_empty]() -> optional { + return [content, can_be_empty]() -> std::optional { if (!can_be_empty) REQUIRE(!content->empty()); if (content->empty()) - return nullopt; + return std::nullopt; char c = (*content)[0]; content->erase(content->begin()); return c; @@ -94,7 +94,7 @@ TEST_SUITE("FindIncludeLine") { return got.value(); }; - auto parse_incorrect = [](std::string content) -> optional { + auto parse_incorrect = [](std::string content) -> std::optional { auto reader = MakeContentReader(&content, true /*can_be_empty*/); return ReadJsonRpcContentFrom(reader); }; @@ -103,15 +103,15 @@ TEST_SUITE("FindIncludeLine") { REQUIRE(parse_correct("Content-Length: 1\r\n\r\na") == "a"); REQUIRE(parse_correct("Content-Length: 4\r\n\r\nabcd") == "abcd"); - REQUIRE(parse_incorrect("ggg") == optional()); + REQUIRE(parse_incorrect("ggg") == std::optional()); REQUIRE(parse_incorrect("Content-Length: 0\r\n") == - optional()); + std::optional()); REQUIRE(parse_incorrect("Content-Length: 5\r\n\r\nab") == - optional()); + std::optional()); } } -optional ReadCharFromStdinBlocking() { +std::optional ReadCharFromStdinBlocking() { // We do not use std::cin because it does not read bytes once stuck in // cin.bad(). We can call cin.clear() but C++ iostream has other annoyance // like std::{cin,cout} is tied by default, which causes undesired cout flush @@ -119,12 +119,12 @@ optional ReadCharFromStdinBlocking() { int c = getchar(); if (c >= 0) return c; - return nullopt; + return std::nullopt; } -optional MessageRegistry::ReadMessageFromStdin( +std::optional MessageRegistry::ReadMessageFromStdin( std::unique_ptr* message) { - optional content = + std::optional content = ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking); if (!content) { LOG_S(ERROR) << "Failed to read JsonRpc input; exiting"; @@ -139,7 +139,7 @@ optional MessageRegistry::ReadMessageFromStdin( return Parse(json_reader, message); } -optional MessageRegistry::Parse( +std::optional MessageRegistry::Parse( Reader& visitor, std::unique_ptr* message) { if (!visitor.HasMember("jsonrpc") || @@ -158,7 +158,7 @@ optional MessageRegistry::Parse( Allocator& allocator = allocators[method]; try { allocator(visitor, message); - return nullopt; + return std::nullopt; } catch (std::invalid_argument& e) { // *message is partially deserialized but some field (e.g. |id|) are likely // available. diff --git a/src/lsp.h b/src/lsp.h index 88e06358d..32692db30 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -35,9 +35,9 @@ struct MessageRegistry { std::function*)>; std::unordered_map allocators; - optional ReadMessageFromStdin( + std::optional ReadMessageFromStdin( std::unique_ptr* message); - optional Parse(Reader& visitor, + std::optional Parse(Reader& visitor, std::unique_ptr* message); }; @@ -196,7 +196,7 @@ enum class lsSymbolKind : uint8_t { // non-type template parameters). TypeParameter = 26, - // cquery extensions + // ccls extensions // See also https://github.com/Microsoft/language-server-protocol/issues/344 // for new SymbolKind clang/Index/IndexSymbol.h clang::index::SymbolKind TypeAlias = 252, @@ -206,12 +206,12 @@ enum class lsSymbolKind : uint8_t { }; MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); -// cquery extension +// ccls extension struct lsLocationEx : lsLocation { - optional containerName; - optional parentKind; + std::optional containerName; + std::optional parentKind; // Avoid circular dependency on symbol.h - optional role; + std::optional role; }; MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role); @@ -240,7 +240,7 @@ struct lsCodeLens { // The range in which this code lens is valid. Should only span a single line. lsRange range; // The command this code lens represents. - optional> command; + std::optional> command; // A data entry field that is preserved on a code lens item between // a code lens and a code lens resolve request. TData data; @@ -337,7 +337,7 @@ MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); // MarkedString can be used to render human readable text. It is either a // markdown string or a code-block that provides a language and a code snippet. -// The language identifier is sematically equal to the optional language +// The language identifier is sematically equal to the std::optional language // identifier in fenced code blocks in GitHub issues. See // https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting // @@ -357,9 +357,9 @@ MAKE_REFLECT_STRUCT(lsMarkedString1, language, value); struct lsTextDocumentContentChangeEvent { // The range of the document that changed. - optional range; + std::optional range; // The length of the range that got replaced. - optional rangeLength; + std::optional rangeLength; // The new text of the range/document. std::string text; }; diff --git a/src/lsp_code_action.h b/src/lsp_code_action.h index 30c049a86..44aa13814 100644 --- a/src/lsp_code_action.h +++ b/src/lsp_code_action.h @@ -19,7 +19,7 @@ struct lsCodeLensCommandArguments { std::vector locations; }; -// FIXME Don't use array in vscode-cquery +// FIXME Don't use array in vscode-ccls inline void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) { visitor.StartArray(3); Reflect(visitor, value.uri); diff --git a/src/lsp_completion.h b/src/lsp_completion.h index 04105f2c2..1e49b39db 100644 --- a/src/lsp_completion.h +++ b/src/lsp_completion.h @@ -69,7 +69,7 @@ struct lsCompletionItem { std::string detail; // A human-readable string that represents a doc-comment. - optional documentation; + std::optional documentation; // Internal information to order candidates. int score_; @@ -84,7 +84,7 @@ struct lsCompletionItem { // A string that should be used when filtering a set of // completion items. When `falsy` the label is used. - optional filterText; + std::optional filterText; // A string that should be inserted a document when selecting // this completion. When `falsy` the label is used. @@ -99,14 +99,14 @@ struct lsCompletionItem { // // *Note:* The range of the edit must be a single line range and it must // contain the position at which completion has been requested. - optional textEdit; + std::optional textEdit; - // An optional array of additional text edits that are applied when + // An std::optional array of additional text edits that are applied when // selecting this completion. Edits must not overlap with the main edit // nor with themselves. // std::vector additionalTextEdits; - // An optional command that is executed *after* inserting this completion. + // An std::optional command that is executed *after* inserting this completion. // *Note* that additional modifications to the current document should be // described with the additionalTextEdits-property. Command command; diff --git a/src/lsp_diagnostic.h b/src/lsp_diagnostic.h index 000980cdb..535047d58 100644 --- a/src/lsp_diagnostic.h +++ b/src/lsp_diagnostic.h @@ -20,14 +20,14 @@ struct lsDiagnostic { // The diagnostic's severity. Can be omitted. If omitted it is up to the // client to interpret diagnostics as error, warning, info or hint. - optional severity; + std::optional severity; // The diagnostic's code. Can be omitted. int code = 0; // A human-readable string describing the source of this // diagnostic, e.g. 'typescript' or 'super lint'. - std::string source = "cquery"; + std::string source = "ccls"; // The diagnostic's message. std::string message; @@ -63,7 +63,7 @@ struct Out_Error : public lsOutMessage { // A Primitive or Structured value that contains additional // information about the error. Can be omitted. - // optional data; + // std::optional data; }; lsRequestId id; diff --git a/src/match.cc b/src/match.cc index 21f0b55fb..6f6bda56f 100644 --- a/src/match.cc +++ b/src/match.cc @@ -6,7 +6,7 @@ #include // static -optional Matcher::Create(const std::string& search) { +std::optional Matcher::Create(const std::string& search) { /* std::string real_search; real_search.reserve(search.size() * 3 + 2); @@ -30,10 +30,10 @@ optional Matcher::Create(const std::string& search) { Out_ShowLogMessage out; out.display_type = Out_ShowLogMessage::DisplayType::Show; out.params.type = lsMessageType::Error; - out.params.message = "cquery: Parsing EMCAScript regex \"" + search + + out.params.message = "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); QueueManager::WriteStdout(kMethodType_Unknown, out); - return nullopt; + return std::nullopt; } } @@ -46,12 +46,12 @@ bool Matcher::IsMatch(const std::string& value) const { GroupMatch::GroupMatch(const std::vector& whitelist, const std::vector& blacklist) { for (const std::string& entry : whitelist) { - optional m = Matcher::Create(entry); + std::optional m = Matcher::Create(entry); if (m) this->whitelist.push_back(*m); } for (const std::string& entry : blacklist) { - optional m = Matcher::Create(entry); + std::optional m = Matcher::Create(entry); if (m) this->blacklist.push_back(*m); } diff --git a/src/match.h b/src/match.h index 6e7be8f97..46b8610c1 100644 --- a/src/match.h +++ b/src/match.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include #include #include struct Matcher { - static optional Create(const std::string& search); + static std::optional Create(const std::string& search); bool IsMatch(const std::string& value) const; diff --git a/src/maybe.h b/src/maybe.h index 09d07f8f9..c26c97084 100644 --- a/src/maybe.h +++ b/src/maybe.h @@ -1,10 +1,10 @@ #pragma once -#include +#include #include -// Like optional, but the stored data is responsible for containing the empty +// Like std::optional, but the stored data is responsible for containing the empty // state. T should define a function `bool T::HasValueForMaybe_()`. template class Maybe { @@ -30,13 +30,13 @@ class Maybe { bool HasValue() const { return storage.HasValueForMaybe_(); } explicit operator bool() const { return HasValue(); } - operator optional() const { + operator std::optional() const { if (HasValue()) return storage; - return nullopt; + return std::nullopt; } - void operator=(optional&& o) { storage = o ? *o : T(); } + void operator=(std::optional&& o) { storage = o ? *o : T(); } // Does not test if has_value() bool operator==(const Maybe& o) const { return storage == o.storage; } diff --git a/src/message_handler.cc b/src/message_handler.cc index e06e9f4da..bcb978379 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -12,23 +12,23 @@ namespace { -struct Out_CquerySetInactiveRegion - : public lsOutMessage { +struct Out_CclsSetInactiveRegion + : public lsOutMessage { struct Params { lsDocumentUri uri; std::vector inactiveRegions; }; - std::string method = "$cquery/setInactiveRegions"; + std::string method = "$ccls/setInactiveRegions"; Params params; }; -MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion::Params, uri, inactiveRegions); -MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params); +MAKE_REFLECT_STRUCT(Out_CclsSetInactiveRegion::Params, uri, inactiveRegions); +MAKE_REFLECT_STRUCT(Out_CclsSetInactiveRegion, jsonrpc, method, params); struct ScanLineEvent { lsPosition pos; lsPosition end_pos; // Second key when there is a tie for insertion events. int id; - Out_CqueryPublishSemanticHighlighting::Symbol* symbol; + Out_CclsPublishSemanticHighlighting::Symbol* symbol; bool operator<(const ScanLineEvent& other) const { // See the comments below when insertion/deletion events are inserted. if (!(pos == other.pos)) @@ -55,7 +55,7 @@ std::vector* MessageHandler::message_handlers = nullptr; bool FindFileOrFail(QueryDatabase* db, const Project* project, - optional id, + std::optional id, const std::string& absolute_path, QueryFile** out_query_file, QueryFileId* out_file_id) { @@ -107,14 +107,14 @@ bool FindFileOrFail(QueryDatabase* db, void EmitInactiveLines(WorkingFile* working_file, const std::vector& inactive_regions) { - Out_CquerySetInactiveRegion out; + Out_CclsSetInactiveRegion out; out.params.uri = lsDocumentUri::FromPath(working_file->filename); for (Range skipped : inactive_regions) { - optional ls_skipped = GetLsRange(working_file, skipped); + std::optional ls_skipped = GetLsRange(working_file, skipped); if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); } - QueueManager::WriteStdout(kMethodType_CqueryPublishInactiveRegions, out); + QueueManager::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); } void EmitSemanticHighlighting(QueryDatabase* db, @@ -128,7 +128,7 @@ void EmitSemanticHighlighting(QueryDatabase* db, semantic_cache->GetCacheForFile(file->def->path); // Group symbols together. - std::unordered_map + std::unordered_map grouped_symbols; for (SymbolRef sym : file->def->all_symbols) { std::string_view detailed_name; @@ -214,13 +214,13 @@ void EmitSemanticHighlighting(QueryDatabase* db, continue; // applies to for loop } - optional loc = GetLsRange(working_file, sym.range); + std::optional loc = GetLsRange(working_file, sym.range); if (loc) { auto it = grouped_symbols.find(sym); if (it != grouped_symbols.end()) { it->second.ranges.push_back(*loc); } else { - Out_CqueryPublishSemanticHighlighting::Symbol symbol; + Out_CclsPublishSemanticHighlighting::Symbol symbol; symbol.stableId = semantic_cache_for_file->GetStableId( sym.kind, std::string(detailed_name)); symbol.parentKind = parent_kind; @@ -236,7 +236,7 @@ void EmitSemanticHighlighting(QueryDatabase* db, std::vector events; int id = 0; for (auto& entry : grouped_symbols) { - Out_CqueryPublishSemanticHighlighting::Symbol& symbol = entry.second; + Out_CclsPublishSemanticHighlighting::Symbol& symbol = entry.second; for (auto& loc : symbol.ranges) { // For ranges sharing the same start point, the one with leftmost end // point comes first. @@ -272,12 +272,12 @@ void EmitSemanticHighlighting(QueryDatabase* db, } // Publish. - Out_CqueryPublishSemanticHighlighting out; + Out_CclsPublishSemanticHighlighting out; out.params.uri = lsDocumentUri::FromPath(working_file->filename); for (auto& entry : grouped_symbols) if (entry.second.ranges.size()) out.params.symbols.push_back(entry.second); - QueueManager::WriteStdout(kMethodType_CqueryPublishSemanticHighlighting, out); + QueueManager::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } bool ShouldIgnoreFileForIndexing(const std::string& path) { diff --git a/src/message_handler.h b/src/message_handler.h index e838bfb1d..49165a590 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -4,7 +4,7 @@ #include "method.h" #include "query.h" -#include +#include #include #include @@ -25,8 +25,8 @@ struct TimestampManager; struct WorkingFile; struct WorkingFiles; -struct Out_CqueryPublishSemanticHighlighting - : public lsOutMessage { +struct Out_CclsPublishSemanticHighlighting + : public lsOutMessage { struct Symbol { int stableId = 0; lsSymbolKind parentKind; @@ -38,19 +38,19 @@ struct Out_CqueryPublishSemanticHighlighting lsDocumentUri uri; std::vector symbols; }; - std::string method = "$cquery/publishSemanticHighlighting"; + std::string method = "$ccls/publishSemanticHighlighting"; Params params; }; -MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol, +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId, parentKind, kind, storage, ranges); -MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params, +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols); -MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting, +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, params); @@ -107,7 +107,7 @@ struct BaseMessageHandler : MessageHandler { bool FindFileOrFail(QueryDatabase* db, const Project* project, - optional id, + std::optional id, const std::string& absolute_path, QueryFile** out_query_file, QueryFileId* out_file_id = nullptr); diff --git a/src/messages/cquery_base.cc b/src/messages/ccls_base.cc similarity index 80% rename from src/messages/cquery_base.cc rename to src/messages/ccls_base.cc index c38314333..f1c31f29d 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/ccls_base.cc @@ -4,20 +4,20 @@ namespace { -MethodType kMethodType = "$cquery/base"; +MethodType kMethodType = "$ccls/base"; -struct In_CqueryBase : public RequestInMessage { +struct In_CclsBase : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(In_CqueryBase, id, params); -REGISTER_IN_MESSAGE(In_CqueryBase); +MAKE_REFLECT_STRUCT(In_CclsBase, id, params); +REGISTER_IN_MESSAGE(In_CclsBase); -struct Handler_CqueryBase : BaseMessageHandler { +struct Handler_CclsBase : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryBase* request) override { + void Run(In_CclsBase* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -48,5 +48,5 @@ struct Handler_CqueryBase : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryBase); +REGISTER_MESSAGE_HANDLER(Handler_CclsBase); } // namespace diff --git a/src/messages/cquery_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc similarity index 85% rename from src/messages/cquery_call_hierarchy.cc rename to src/messages/ccls_call_hierarchy.cc index 9f6e576f8..04e117f87 100644 --- a/src/messages/cquery_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -6,7 +6,7 @@ namespace { -MethodType kMethodType = "$cquery/callHierarchy"; +MethodType kMethodType = "$ccls/callHierarchy"; enum class CallType : uint8_t { Direct = 0, @@ -20,7 +20,7 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct In_CqueryCallHierarchy : public RequestInMessage { +struct In_CclsCallHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -43,7 +43,7 @@ struct In_CqueryCallHierarchy : public RequestInMessage { Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryCallHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id, @@ -51,10 +51,10 @@ MAKE_REFLECT_STRUCT(In_CqueryCallHierarchy::Params, callType, detailedName, levels); -MAKE_REFLECT_STRUCT(In_CqueryCallHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CqueryCallHierarchy); +MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CclsCallHierarchy); -struct Out_CqueryCallHierarchy : public lsOutMessage { +struct Out_CclsCallHierarchy : public lsOutMessage { struct Entry { QueryFuncId id; std::string_view name; @@ -66,19 +66,19 @@ struct Out_CqueryCallHierarchy : public lsOutMessage { }; lsRequestId id; - optional result; + std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CqueryCallHierarchy::Entry, +MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CqueryCallHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy, jsonrpc, id, result); bool Expand(MessageHandler* m, - Out_CqueryCallHierarchy::Entry* entry, + Out_CclsCallHierarchy::Entry* entry, bool callee, CallType call_type, bool detailed_name, @@ -91,7 +91,7 @@ bool Expand(MessageHandler* m, auto handle = [&](Use use, CallType call_type) { entry->numChildren++; if (levels > 0) { - Out_CqueryCallHierarchy::Entry entry1; + Out_CclsCallHierarchy::Entry entry1; entry1.id = QueryFuncId(use.id); if (auto loc = GetLsLocation(m->db, m->working_files, use)) entry1.location = *loc; @@ -159,11 +159,11 @@ bool Expand(MessageHandler* m, return true; } -struct Handler_CqueryCallHierarchy - : BaseMessageHandler { +struct Handler_CclsCallHierarchy + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - optional BuildInitial(QueryFuncId root_id, + std::optional BuildInitial(QueryFuncId root_id, bool callee, CallType call_type, bool detailed_name, @@ -172,11 +172,11 @@ struct Handler_CqueryCallHierarchy if (!def) return {}; - Out_CqueryCallHierarchy::Entry entry; + Out_CclsCallHierarchy::Entry entry; entry.id = root_id; entry.callType = CallType::Direct; if (def->spell) { - if (optional loc = + if (std::optional loc = GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } @@ -184,13 +184,13 @@ struct Handler_CqueryCallHierarchy return entry; } - void Run(In_CqueryCallHierarchy* request) override { + void Run(In_CclsCallHierarchy* request) override { const auto& params = request->params; - Out_CqueryCallHierarchy out; + Out_CclsCallHierarchy out; out.id = request->id; if (params.id) { - Out_CqueryCallHierarchy::Entry entry; + Out_CclsCallHierarchy::Entry entry; entry.id = *params.id; entry.callType = CallType::Direct; if (entry.id.id < db->funcs.size()) @@ -218,6 +218,6 @@ struct Handler_CqueryCallHierarchy QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryCallHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); } // namespace diff --git a/src/messages/cquery_callers.cc b/src/messages/ccls_callers.cc similarity index 78% rename from src/messages/cquery_callers.cc rename to src/messages/ccls_callers.cc index 701aefbe0..0e7904fc0 100644 --- a/src/messages/cquery_callers.cc +++ b/src/messages/ccls_callers.cc @@ -3,18 +3,18 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/callers"; +MethodType kMethodType = "$ccls/callers"; -struct In_CqueryCallers : public RequestInMessage { +struct In_CclsCallers : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(In_CqueryCallers, id, params); -REGISTER_IN_MESSAGE(In_CqueryCallers); +MAKE_REFLECT_STRUCT(In_CclsCallers, id, params); +REGISTER_IN_MESSAGE(In_CclsCallers); -struct Handler_CqueryCallers : BaseMessageHandler { +struct Handler_CclsCallers : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryCallers* request) override { + void Run(In_CclsCallers* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -44,5 +44,5 @@ struct Handler_CqueryCallers : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryCallers); +REGISTER_MESSAGE_HANDLER(Handler_CclsCallers); } // namespace diff --git a/src/messages/cquery_derived.cc b/src/messages/ccls_derived.cc similarity index 78% rename from src/messages/cquery_derived.cc rename to src/messages/ccls_derived.cc index 9700e88f6..ad415acee 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/ccls_derived.cc @@ -3,18 +3,18 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/derived"; +MethodType kMethodType = "$ccls/derived"; -struct In_CqueryDerived : public RequestInMessage { +struct In_CclsDerived : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(In_CqueryDerived, id, params); -REGISTER_IN_MESSAGE(In_CqueryDerived); +MAKE_REFLECT_STRUCT(In_CclsDerived, id, params); +REGISTER_IN_MESSAGE(In_CclsDerived); -struct Handler_CqueryDerived : BaseMessageHandler { +struct Handler_CclsDerived : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryDerived* request) override { + void Run(In_CclsDerived* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -45,5 +45,5 @@ struct Handler_CqueryDerived : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryDerived); +REGISTER_MESSAGE_HANDLER(Handler_CclsDerived); } // namespace diff --git a/src/messages/cquery_did_view.cc b/src/messages/ccls_did_view.cc similarity index 57% rename from src/messages/cquery_did_view.cc rename to src/messages/ccls_did_view.cc index 73da37da8..ece233b36 100644 --- a/src/messages/cquery_did_view.cc +++ b/src/messages/ccls_did_view.cc @@ -3,30 +3,30 @@ #include "working_files.h" namespace { -MethodType kMethodType = "$cquery/textDocumentDidView"; +MethodType kMethodType = "$ccls/textDocumentDidView"; -struct In_CqueryTextDocumentDidView : public NotificationInMessage { +struct In_CclsTextDocumentDidView : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsDocumentUri textDocumentUri; }; Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView::Params, textDocumentUri); -MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView, params); -REGISTER_IN_MESSAGE(In_CqueryTextDocumentDidView); +MAKE_REFLECT_STRUCT(In_CclsTextDocumentDidView::Params, textDocumentUri); +MAKE_REFLECT_STRUCT(In_CclsTextDocumentDidView, params); +REGISTER_IN_MESSAGE(In_CclsTextDocumentDidView); -struct Handler_CqueryDidView - : BaseMessageHandler { +struct Handler_CclsDidView + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryTextDocumentDidView* request) override { + void Run(In_CclsTextDocumentDidView* request) override { std::string path = request->params.textDocumentUri.GetPath(); WorkingFile* working_file = working_files->GetFileByFilename(path); if (!working_file) return; QueryFile* file = nullptr; - if (!FindFileOrFail(db, project, nullopt, path, &file)) + if (!FindFileOrFail(db, project, std::nullopt, path, &file)) return; clang_complete->NotifyView(path); @@ -36,5 +36,5 @@ struct Handler_CqueryDidView } } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryDidView); +REGISTER_MESSAGE_HANDLER(Handler_CclsDidView); } // namespace diff --git a/src/messages/cquery_file_info.cc b/src/messages/ccls_file_info.cc similarity index 65% rename from src/messages/cquery_file_info.cc rename to src/messages/ccls_file_info.cc index a72612d6e..94475b692 100644 --- a/src/messages/cquery_file_info.cc +++ b/src/messages/ccls_file_info.cc @@ -3,36 +3,36 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/fileInfo"; +MethodType kMethodType = "$ccls/fileInfo"; struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; }; MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); -struct In_CqueryFileInfo : public RequestInMessage { +struct In_CclsFileInfo : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsDocumentSymbolParams params; }; -MAKE_REFLECT_STRUCT(In_CqueryFileInfo, id, params); -REGISTER_IN_MESSAGE(In_CqueryFileInfo); +MAKE_REFLECT_STRUCT(In_CclsFileInfo, id, params); +REGISTER_IN_MESSAGE(In_CclsFileInfo); -struct Out_CqueryFileInfo : public lsOutMessage { +struct Out_CclsFileInfo : public lsOutMessage { lsRequestId id; QueryFile::Def result; }; -MAKE_REFLECT_STRUCT(Out_CqueryFileInfo, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(Out_CclsFileInfo, jsonrpc, id, result); -struct Handler_CqueryFileInfo : BaseMessageHandler { +struct Handler_CclsFileInfo : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryFileInfo* request) override { + void Run(In_CclsFileInfo* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; } - Out_CqueryFileInfo out; + Out_CclsFileInfo out; out.id = request->id; // Expose some fields of |QueryFile::Def|. out.result.path = file->def->path; @@ -43,5 +43,5 @@ struct Handler_CqueryFileInfo : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryFileInfo); +REGISTER_MESSAGE_HANDLER(Handler_CclsFileInfo); } // namespace diff --git a/src/messages/cquery_freshen_index.cc b/src/messages/ccls_freshen_index.cc similarity index 81% rename from src/messages/cquery_freshen_index.cc rename to src/messages/ccls_freshen_index.cc index e52b52368..8e25a7b2b 100644 --- a/src/messages/cquery_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -13,9 +13,9 @@ #include namespace { -MethodType kMethodType = "$cquery/freshenIndex"; +MethodType kMethodType = "$ccls/freshenIndex"; -struct In_CqueryFreshenIndex : public NotificationInMessage { +struct In_CclsFreshenIndex : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { bool dependencies = true; @@ -24,16 +24,16 @@ struct In_CqueryFreshenIndex : public NotificationInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryFreshenIndex::Params, +MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, dependencies, whitelist, blacklist); -MAKE_REFLECT_STRUCT(In_CqueryFreshenIndex, params); -REGISTER_IN_MESSAGE(In_CqueryFreshenIndex); +MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params); +REGISTER_IN_MESSAGE(In_CclsFreshenIndex); -struct Handler_CqueryFreshenIndex : BaseMessageHandler { +struct Handler_CclsFreshenIndex : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryFreshenIndex* request) override { + void Run(In_CclsFreshenIndex* request) override { LOG_S(INFO) << "Freshening " << project->entries.size() << " files"; // TODO: think about this flow and test it more. @@ -65,11 +65,11 @@ struct Handler_CqueryFreshenIndex : BaseMessageHandler { q.pop(); need_index.insert(file->def->path); - optional modification_timestamp = + std::optional modification_timestamp = GetLastModificationTime(file->def->path); if (!modification_timestamp) continue; - optional cached_modification = + std::optional cached_modification = timestamp_manager->GetLastCachedModificationTime(cache_manager.get(), file->def->path); if (modification_timestamp != cached_modification) @@ -89,8 +89,8 @@ struct Handler_CqueryFreshenIndex : BaseMessageHandler { // Send index requests for every file. project->Index(config, QueueManager::instance(), working_files, std::monostate()); - time.ResetAndPrint("[perf] Dispatched $cquery/freshenIndex index requests"); + time.ResetAndPrint("[perf] Dispatched $ccls/freshenIndex index requests"); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryFreshenIndex); +REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); } // namespace diff --git a/src/messages/cquery_index_file.cc b/src/messages/ccls_index_file.cc similarity index 68% rename from src/messages/cquery_index_file.cc rename to src/messages/ccls_index_file.cc index 9e1065582..4dfac6967 100644 --- a/src/messages/cquery_index_file.cc +++ b/src/messages/ccls_index_file.cc @@ -6,9 +6,9 @@ #include namespace { -MethodType kMethodType = "$cquery/indexFile"; +MethodType kMethodType = "$ccls/indexFile"; -struct In_CqueryIndexFile : public NotificationInMessage { +struct In_CclsIndexFile : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string path; @@ -18,17 +18,17 @@ struct In_CqueryIndexFile : public NotificationInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryIndexFile::Params, +MAKE_REFLECT_STRUCT(In_CclsIndexFile::Params, path, args, is_interactive, contents); -MAKE_REFLECT_STRUCT(In_CqueryIndexFile, params); -REGISTER_IN_MESSAGE(In_CqueryIndexFile); +MAKE_REFLECT_STRUCT(In_CclsIndexFile, params); +REGISTER_IN_MESSAGE(In_CclsIndexFile); -struct Handler_CqueryIndexFile : BaseMessageHandler { +struct Handler_CclsIndexFile : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryIndexFile* request) override { + void Run(In_CclsIndexFile* request) override { LOG_S(INFO) << "Indexing file " << request->params.path; QueueManager::instance()->index_request.PushBack( Index_Request(NormalizePath(request->params.path), request->params.args, @@ -36,5 +36,5 @@ struct Handler_CqueryIndexFile : BaseMessageHandler { ICacheManager::Make(config))); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryIndexFile); +REGISTER_MESSAGE_HANDLER(Handler_CclsIndexFile); } // namespace diff --git a/src/messages/cquery_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc similarity index 78% rename from src/messages/cquery_inheritance_hierarchy.cc rename to src/messages/ccls_inheritance_hierarchy.cc index 17a0b1baa..29b9ad5ef 100644 --- a/src/messages/cquery_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -3,9 +3,9 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/inheritanceHierarchy"; +MethodType kMethodType = "$ccls/inheritanceHierarchy"; -struct In_CqueryInheritanceHierarchy : public RequestInMessage { +struct In_CclsInheritanceHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // If id+kind are specified, expand a node; otherwise textDocument+position @@ -24,7 +24,7 @@ struct In_CqueryInheritanceHierarchy : public RequestInMessage { Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryInheritanceHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, textDocument, position, id, @@ -32,11 +32,11 @@ MAKE_REFLECT_STRUCT(In_CqueryInheritanceHierarchy::Params, derived, detailedName, levels); -MAKE_REFLECT_STRUCT(In_CqueryInheritanceHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CqueryInheritanceHierarchy); +MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); -struct Out_CqueryInheritanceHierarchy - : public lsOutMessage { +struct Out_CclsInheritanceHierarchy + : public lsOutMessage { struct Entry { Id id; SymbolKind kind; @@ -49,26 +49,26 @@ struct Out_CqueryInheritanceHierarchy std::vector children; }; lsRequestId id; - optional result; + std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CqueryInheritanceHierarchy::Entry, +MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CqueryInheritanceHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy, jsonrpc, id, result); bool Expand(MessageHandler* m, - Out_CqueryInheritanceHierarchy::Entry* entry, + Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool detailed_name, int levels); template bool ExpandHelper(MessageHandler* m, - Out_CqueryInheritanceHierarchy::Entry* entry, + Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool detailed_name, int levels, @@ -83,14 +83,14 @@ bool ExpandHelper(MessageHandler* m, else entry->name = def->ShortName(); if (def->spell) { - if (optional loc = + if (std::optional loc = GetLsLocation(m->db, m->working_files, *def->spell)) entry->location = *loc; } if (derived) { if (levels > 0) { for (auto id : entity.derived) { - Out_CqueryInheritanceHierarchy::Entry entry1; + Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = id; entry1.kind = entry->kind; if (Expand(m, &entry1, derived, detailed_name, levels - 1)) @@ -102,7 +102,7 @@ bool ExpandHelper(MessageHandler* m, } else { if (levels > 0) { for (auto id : def->bases) { - Out_CqueryInheritanceHierarchy::Entry entry1; + Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = id; entry1.kind = entry->kind; if (Expand(m, &entry1, derived, detailed_name, levels - 1)) @@ -116,7 +116,7 @@ bool ExpandHelper(MessageHandler* m, } bool Expand(MessageHandler* m, - Out_CqueryInheritanceHierarchy::Entry* entry, + Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool detailed_name, int levels) { @@ -128,26 +128,26 @@ bool Expand(MessageHandler* m, m->db->types[entry->id.id]); } -struct Handler_CqueryInheritanceHierarchy - : BaseMessageHandler { +struct Handler_CclsInheritanceHierarchy + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - optional + std::optional BuildInitial(SymbolRef sym, bool derived, bool detailed_name, int levels) { - Out_CqueryInheritanceHierarchy::Entry entry; + Out_CclsInheritanceHierarchy::Entry entry; entry.id = sym.id; entry.kind = sym.kind; Expand(this, &entry, derived, detailed_name, levels); return entry; } - void Run(In_CqueryInheritanceHierarchy* request) override { + void Run(In_CclsInheritanceHierarchy* request) override { const auto& params = request->params; - Out_CqueryInheritanceHierarchy out; + Out_CclsInheritanceHierarchy out; out.id = request->id; if (params.id) { - Out_CqueryInheritanceHierarchy::Entry entry; + Out_CclsInheritanceHierarchy::Entry entry; entry.id = *params.id; entry.kind = params.kind; if (((entry.kind == SymbolKind::Func && entry.id.id < db->funcs.size()) || @@ -177,6 +177,6 @@ struct Handler_CqueryInheritanceHierarchy QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryInheritanceHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); } // namespace diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc similarity index 82% rename from src/messages/cquery_member_hierarchy.cc rename to src/messages/ccls_member_hierarchy.cc index e98e53d53..619b51535 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -3,9 +3,9 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/memberHierarchy"; +MethodType kMethodType = "$ccls/memberHierarchy"; -struct In_CqueryMemberHierarchy : public RequestInMessage { +struct In_CclsMemberHierarchy : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -22,17 +22,17 @@ struct In_CqueryMemberHierarchy : public RequestInMessage { Params params; }; -MAKE_REFLECT_STRUCT(In_CqueryMemberHierarchy::Params, +MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, detailedName, levels); -MAKE_REFLECT_STRUCT(In_CqueryMemberHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CqueryMemberHierarchy); +MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); +REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); -struct Out_CqueryMemberHierarchy - : public lsOutMessage { +struct Out_CclsMemberHierarchy + : public lsOutMessage { struct Entry { QueryTypeId id; std::string_view name; @@ -45,38 +45,38 @@ struct Out_CqueryMemberHierarchy std::vector children; }; lsRequestId id; - optional result; + std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CqueryMemberHierarchy::Entry, +MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CqueryMemberHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy, jsonrpc, id, result); bool Expand(MessageHandler* m, - Out_CqueryMemberHierarchy::Entry* entry, + Out_CclsMemberHierarchy::Entry* entry, bool detailed_name, int levels); // Add a field to |entry| which is a Func/Type. void DoField(MessageHandler* m, - Out_CqueryMemberHierarchy::Entry* entry, + Out_CclsMemberHierarchy::Entry* entry, const QueryVar& var, bool detailed_name, int levels) { const QueryVar::Def* def1 = var.AnyDef(); if (!def1) return; - Out_CqueryMemberHierarchy::Entry entry1; + Out_CclsMemberHierarchy::Entry entry1; if (detailed_name) entry1.fieldName = def1->DetailedName(false); else entry1.fieldName = std::string(def1->ShortName()); if (def1->spell) { - if (optional loc = + if (std::optional loc = GetLsLocation(m->db, m->working_files, *def1->spell)) entry1.location = *loc; } @@ -92,7 +92,7 @@ void DoField(MessageHandler* m, // Expand a type node by adding members recursively to it. bool Expand(MessageHandler* m, - Out_CqueryMemberHierarchy::Entry* entry, + Out_CclsMemberHierarchy::Entry* entry, bool detailed_name, int levels) { const QueryType& type = m->db->types[entry->id.id]; @@ -125,17 +125,17 @@ bool Expand(MessageHandler* m, }); if (def->alias_of) { const QueryType::Def* def1 = m->db->types[def->alias_of->id].AnyDef(); - Out_CqueryMemberHierarchy::Entry entry1; + Out_CclsMemberHierarchy::Entry entry1; entry1.id = *def->alias_of; if (def1 && def1->spell) { // The declaration of target type. - if (optional loc = + if (std::optional loc = GetLsLocation(m->db, m->working_files, *def1->spell)) entry1.location = *loc; } else if (def->spell) { // Builtin types have no declaration but the typedef declaration // itself is useful. - if (optional loc = + if (std::optional loc = GetLsLocation(m->db, m->working_files, *def->spell)) entry1.location = *loc; } @@ -160,25 +160,25 @@ bool Expand(MessageHandler* m, return true; } -struct Handler_CqueryMemberHierarchy - : BaseMessageHandler { +struct Handler_CclsMemberHierarchy + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - optional BuildInitial(QueryFuncId root_id, + std::optional BuildInitial(QueryFuncId root_id, bool detailed_name, int levels) { const auto* def = db->funcs[root_id.id].AnyDef(); if (!def) return {}; - Out_CqueryMemberHierarchy::Entry entry; + Out_CclsMemberHierarchy::Entry entry; // Not type, |id| is invalid. if (detailed_name) entry.name = def->DetailedName(false); else entry.name = std::string(def->ShortName()); if (def->spell) { - if (optional loc = + if (std::optional loc = GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } @@ -188,17 +188,17 @@ struct Handler_CqueryMemberHierarchy return entry; } - optional BuildInitial(QueryTypeId root_id, + std::optional BuildInitial(QueryTypeId root_id, bool detailed_name, int levels) { const auto* def = db->types[root_id.id].AnyDef(); if (!def) return {}; - Out_CqueryMemberHierarchy::Entry entry; + Out_CclsMemberHierarchy::Entry entry; entry.id = root_id; if (def->spell) { - if (optional loc = + if (std::optional loc = GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } @@ -206,13 +206,13 @@ struct Handler_CqueryMemberHierarchy return entry; } - void Run(In_CqueryMemberHierarchy* request) override { + void Run(In_CclsMemberHierarchy* request) override { const auto& params = request->params; - Out_CqueryMemberHierarchy out; + Out_CclsMemberHierarchy out; out.id = request->id; if (params.id) { - Out_CqueryMemberHierarchy::Entry entry; + Out_CclsMemberHierarchy::Entry entry; entry.id = *request->params.id; // entry.name is empty as it is known by the client. if (entry.id.id < db->types.size() && @@ -253,6 +253,6 @@ struct Handler_CqueryMemberHierarchy QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryMemberHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); } // namespace diff --git a/src/messages/cquery_random.cc b/src/messages/ccls_random.cc similarity index 91% rename from src/messages/cquery_random.cc rename to src/messages/ccls_random.cc index 7bbf0761d..f24471e76 100644 --- a/src/messages/cquery_random.cc +++ b/src/messages/ccls_random.cc @@ -7,13 +7,13 @@ #include namespace { -MethodType kMethodType = "$cquery/random"; +MethodType kMethodType = "$ccls/random"; -struct In_CqueryRandom : public RequestInMessage { +struct In_CclsRandom : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } }; -MAKE_REFLECT_STRUCT(In_CqueryRandom, id); -REGISTER_IN_MESSAGE(In_CqueryRandom); +MAKE_REFLECT_STRUCT(In_CclsRandom, id); +REGISTER_IN_MESSAGE(In_CclsRandom); const double kDeclWeight = 3; const double kDamping = 0.1; @@ -46,10 +46,10 @@ void Add(const std::unordered_map& sym2id, } } -struct Handler_CqueryRandom : BaseMessageHandler { +struct Handler_CclsRandom : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryRandom* request) override { + void Run(In_CclsRandom* request) override { std::unordered_map sym2id; std::vector syms; int n = 0; @@ -144,5 +144,5 @@ struct Handler_CqueryRandom : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryRandom); +REGISTER_MESSAGE_HANDLER(Handler_CclsRandom); } // namespace diff --git a/src/messages/cquery_vars.cc b/src/messages/ccls_vars.cc similarity index 80% rename from src/messages/cquery_vars.cc rename to src/messages/ccls_vars.cc index 8ac9816f6..b9426487e 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/ccls_vars.cc @@ -3,20 +3,20 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$cquery/vars"; +MethodType kMethodType = "$ccls/vars"; -struct In_CqueryVars : public RequestInMessage { +struct In_CclsVars : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(In_CqueryVars, id, params); -REGISTER_IN_MESSAGE(In_CqueryVars); +MAKE_REFLECT_STRUCT(In_CclsVars, id, params); +REGISTER_IN_MESSAGE(In_CclsVars); -struct Handler_CqueryVars : BaseMessageHandler { +struct Handler_CclsVars : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CqueryVars* request) override { + void Run(In_CclsVars* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -53,5 +53,5 @@ struct Handler_CqueryVars : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryVars); +REGISTER_MESSAGE_HANDLER(Handler_CclsVars); } // namespace diff --git a/src/messages/cquery_wait.cc b/src/messages/ccls_wait.cc similarity index 82% rename from src/messages/cquery_wait.cc rename to src/messages/ccls_wait.cc index 3a05df756..1e9c9b3be 100644 --- a/src/messages/cquery_wait.cc +++ b/src/messages/ccls_wait.cc @@ -6,15 +6,15 @@ #include namespace { -MethodType kMethodType = "$cquery/wait"; +MethodType kMethodType = "$ccls/wait"; -struct In_CqueryWait : public NotificationInMessage { +struct In_CclsWait : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } }; -MAKE_REFLECT_EMPTY_STRUCT(In_CqueryWait); -REGISTER_IN_MESSAGE(In_CqueryWait); +MAKE_REFLECT_EMPTY_STRUCT(In_CclsWait); +REGISTER_IN_MESSAGE(In_CclsWait); -struct Handler_CqueryWait : MessageHandler { +struct Handler_CclsWait : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(std::unique_ptr request) override { @@ -43,5 +43,5 @@ struct Handler_CqueryWait : MessageHandler { LOG_S(INFO) << "Done waiting for idle"; } }; -REGISTER_MESSAGE_HANDLER(Handler_CqueryWait); +REGISTER_MESSAGE_HANDLER(Handler_CclsWait); } // namespace diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 2edd6ff07..9d97b7c25 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -114,11 +114,11 @@ struct lsTextDocumentSyncOptions { // TextDocumentSyncKind.Full and TextDocumentSyncKindIncremental. lsTextDocumentSyncKind change = lsTextDocumentSyncKind::Incremental; // Will save notifications are sent to the server. - optional willSave; + std::optional willSave; // Will save wait until requests are sent to the server. - optional willSaveWaitUntil; + std::optional willSaveWaitUntil; // Save notifications are sent to the server. - optional save; + std::optional save; }; MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, @@ -132,7 +132,7 @@ struct lsServerCapabilities { // defining each notification or for backwards compatibility the // TextDocumentSyncKind number. // TODO: It seems like the new API is broken and doesn't work. - // optional textDocumentSync; + // std::optional textDocumentSync; lsTextDocumentSyncKind textDocumentSync = lsTextDocumentSyncKind::Incremental; // The server provides hover support. @@ -162,7 +162,7 @@ struct lsServerCapabilities { // The server provides document range formatting. bool documentRangeFormattingProvider = false; // The server provides document formatting on typing. - optional documentOnTypeFormattingProvider; + std::optional documentOnTypeFormattingProvider; // The server provides rename support. bool renameProvider = true; // The server provides document link support. @@ -192,34 +192,34 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, // Workspace specific client capabilities. struct lsWorkspaceClientCapabilites { // The client supports applying batch edits to the workspace. - optional applyEdit; + std::optional applyEdit; struct lsWorkspaceEdit { // The client supports versioned document changes in `WorkspaceEdit`s - optional documentChanges; + std::optional documentChanges; }; // Capabilities specific to `WorkspaceEdit`s - optional workspaceEdit; + std::optional workspaceEdit; struct lsGenericDynamicReg { // Did foo notification supports dynamic registration. - optional dynamicRegistration; + std::optional dynamicRegistration; }; // Capabilities specific to the `workspace/didChangeConfiguration` // notification. - optional didChangeConfiguration; + std::optional didChangeConfiguration; // Capabilities specific to the `workspace/didChangeWatchedFiles` // notification. - optional didChangeWatchedFiles; + std::optional didChangeWatchedFiles; // Capabilities specific to the `workspace/symbol` request. - optional symbol; + std::optional symbol; // Capabilities specific to the `workspace/executeCommand` request. - optional executeCommand; + std::optional executeCommand; }; MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit, @@ -238,25 +238,25 @@ MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, struct lsTextDocumentClientCapabilities { struct lsSynchronization { // Whether text document synchronization supports dynamic registration. - optional dynamicRegistration; + std::optional dynamicRegistration; // The client supports sending will save notifications. - optional willSave; + std::optional willSave; // The client supports sending a will save request and // waits for a response providing text edits which will // be applied to the document before it is saved. - optional willSaveWaitUntil; + std::optional willSaveWaitUntil; // The client supports did save notifications. - optional didSave; + std::optional didSave; }; lsSynchronization synchronization; struct lsCompletion { // Whether completion supports dynamic registration. - optional dynamicRegistration; + std::optional dynamicRegistration; struct lsCompletionItem { // Client supports snippets as insert text. @@ -265,50 +265,50 @@ struct lsTextDocumentClientCapabilities { // and `${3:foo}`. `$0` defines the final tab stop, it defaults to // the end of the snippet. Placeholders with equal identifiers are linked, // that is typing in one will update others too. - optional snippetSupport; + std::optional snippetSupport; }; // The client supports the following `CompletionItem` specific // capabilities. - optional completionItem; + std::optional completionItem; }; // Capabilities specific to the `textDocument/completion` - optional completion; + std::optional completion; struct lsGenericDynamicReg { // Whether foo supports dynamic registration. - optional dynamicRegistration; + std::optional dynamicRegistration; }; // Capabilities specific to the `textDocument/hover` - optional hover; + std::optional hover; // Capabilities specific to the `textDocument/signatureHelp` - optional signatureHelp; + std::optional signatureHelp; // Capabilities specific to the `textDocument/references` - optional references; + std::optional references; // Capabilities specific to the `textDocument/documentHighlight` - optional documentHighlight; + std::optional documentHighlight; // Capabilities specific to the `textDocument/documentSymbol` - optional documentSymbol; + std::optional documentSymbol; // Capabilities specific to the `textDocument/formatting` - optional formatting; + std::optional formatting; // Capabilities specific to the `textDocument/rangeFormatting` - optional rangeFormatting; + std::optional rangeFormatting; // Capabilities specific to the `textDocument/onTypeFormatting` - optional onTypeFormatting; + std::optional onTypeFormatting; // Capabilities specific to the `textDocument/definition` - optional definition; + std::optional definition; // Capabilities specific to the `textDocument/codeAction` - optional codeAction; + std::optional codeAction; struct CodeLensRegistrationOptions : public lsGenericDynamicReg { // Code lens has a resolve provider as well. @@ -316,13 +316,13 @@ struct lsTextDocumentClientCapabilities { }; // Capabilities specific to the `textDocument/codeLens` - optional codeLens; + std::optional codeLens; // Capabilities specific to the `textDocument/documentLink` - optional documentLink; + std::optional documentLink; // Capabilities specific to the `textDocument/rename` - optional rename; + std::optional rename; }; MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, @@ -361,10 +361,10 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, struct lsClientCapabilities { // Workspace specific client capabilities. - optional workspace; + std::optional workspace; // Text document specific client capabilities. - optional textDocument; + std::optional textDocument; /** * Experimental client capabilities. @@ -386,21 +386,21 @@ struct lsInitializeParams { // the server. Is null if the process has not been started by another process. // If the parent process is not alive then the server should exit (see exit // notification) its process. - optional processId; + std::optional processId; // The rootPath of the workspace. Is null // if no folder is open. // // @deprecated in favour of rootUri. - optional rootPath; + std::optional rootPath; // The rootUri of the workspace. Is null if no // folder is open. If both `rootPath` and `rootUri` are set // `rootUri` wins. - optional rootUri; + std::optional rootUri; // User provided initialization options. - optional initializationOptions; + std::optional initializationOptions; // The capabilities provided by the client (editor or tool) lsClientCapabilities capabilities; @@ -538,15 +538,15 @@ struct Handler_Initialize : BaseMessageHandler { out.display_type = Out_ShowLogMessage::DisplayType::Show; out.params.type = lsMessageType::Error; out.params.message = - "cquery client (v" + std::to_string(*config->clientVersion) + + "ccls client (v" + std::to_string(*config->clientVersion) + ") and server (v" + std::to_string(kExpectedClientVersion) + ") version mismatch. Please update "; if (config->clientVersion > kExpectedClientVersion) - out.params.message += "the cquery binary."; + out.params.message += "the ccls binary."; else out.params.message += "your extension client (VSIX file). Make sure to uninstall " - "the cquery extension and restart vscode before " + "the ccls extension and restart vscode before " "reinstalling."; out.Write(std::cout); } diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc deleted file mode 100644 index e3913a2fb..000000000 --- a/src/messages/text_document_code_action.cc +++ /dev/null @@ -1,600 +0,0 @@ -#include "include_complete.h" -#include "lex_utils.h" -#include "lsp_code_action.h" -#include "message_handler.h" -#include "query_utils.h" -#include "queue_manager.h" - -#include - -#include -#include - -namespace { -MethodType kMethodType = "textDocument/codeAction"; - -optional FindIncludeLine(const std::vector& lines, - const std::string& full_include_line) { - // - // This returns an include line. For example, - // - // #include // 0 - // #include // 1 - // - // Given #include , this will return '1', which means that the - // #include text should be inserted at the start of line 1. Inserting - // at the start of a line allows insertion at both the top and bottom of the - // document. - // - // If the include line is already in the document this returns nullopt. - // - - optional last_include_line; - optional best_include_line; - - // 1 => include line is gt content (ie, it should go after) - // -1 => include line is lt content (ie, it should go before) - int last_line_compare = 1; - - for (int line = 0; line < (int)lines.size(); ++line) { - std::string text = Trim(lines[line]); - if (!StartsWith(text, "#include")) { - last_line_compare = 1; - continue; - } - - last_include_line = line; - - int current_line_compare = full_include_line.compare(text); - if (current_line_compare == 0) - return nullopt; - - if (last_line_compare == 1 && current_line_compare == -1) - best_include_line = line; - last_line_compare = current_line_compare; - } - - if (best_include_line) - return *best_include_line; - // If |best_include_line| didn't match that means we likely didn't find an - // include which was lt the new one, so put it at the end of the last include - // list. - if (last_include_line) - return *last_include_line + 1; - // No includes, use top of document. - return 0; -} - -optional GetImplementationFile(QueryDatabase* db, - QueryFileId file_id, - QueryFile* file) { - for (SymbolRef sym : file->def->outline) { - switch (sym.kind) { - case SymbolKind::Func: { - if (const auto* def = db->GetFunc(sym).AnyDef()) { - // Note: we ignore the definition if it is in the same file (ie, - // possibly a header). - if (def->extent) { - QueryFileId t = def->extent->file; - if (t != file_id) - return t; - } - } - break; - } - case SymbolKind::Var: { - const QueryVar::Def* def = db->GetVar(sym).AnyDef(); - // Note: we ignore the definition if it is in the same file (ie, - // possibly a header). - if (def && def->extent) { - QueryFileId t = def->extent->file; - if (t != file_id) - return t; - } - break; - } - default: - break; - } - } - - // No associated definition, scan the project for a file in the same - // directory with the same base-name. - NormalizedPath original_path(file->def->path); - std::string target_path = original_path.path; - size_t last = target_path.find_last_of('.'); - if (last != std::string::npos) { - target_path = target_path.substr(0, last); - } - - LOG_S(INFO) << "!! Looking for impl file that starts with " << target_path; - - for (auto& entry : db->usr_to_file) { - const NormalizedPath& path = entry.first; - - // Do not consider header files for implementation files. - // TODO: make file extensions configurable. - if (EndsWith(path.path, ".h") || EndsWith(path.path, ".hpp")) - continue; - - if (StartsWith(path.path, target_path) && path != original_path) { - return entry.second; - } - } - - return nullopt; -} - -void EnsureImplFile(QueryDatabase* db, - QueryFileId file_id, - optional& impl_uri, - optional& impl_file_id) { - if (!impl_uri.has_value()) { - QueryFile& file = db->files[file_id.id]; - assert(file.def); - - impl_file_id = GetImplementationFile(db, file_id, &file); - if (!impl_file_id.has_value()) - impl_file_id = file_id; - - QueryFile& impl_file = db->files[impl_file_id->id]; - if (impl_file.def) - impl_uri = lsDocumentUri::FromPath(impl_file.def->path); - else - impl_uri = lsDocumentUri::FromPath(file.def->path); - } -} - -optional BuildAutoImplementForFunction(QueryDatabase* db, - WorkingFiles* working_files, - WorkingFile* working_file, - int default_line, - QueryFileId decl_file_id, - QueryFileId impl_file_id, - QueryFunc& func) { - const QueryFunc::Def* def = func.AnyDef(); - assert(def); - for (Use decl : func.declarations) { - if (decl.file != decl_file_id) - continue; - - optional ls_decl = GetLsRange(working_file, decl.range); - if (!ls_decl) - continue; - - optional type_name; - optional same_file_insert_end; - if (def->declaring_type) { - QueryType& declaring_type = db->types[def->declaring_type->id]; - if (const auto* def1 = declaring_type.AnyDef()) { - type_name = std::string(def1->ShortName()); - optional ls_type_extent = - GetLsRange(working_file, def1->extent->range); - if (ls_type_extent) { - same_file_insert_end = ls_type_extent->end; - same_file_insert_end->character += 1; // move past semicolon. - } - } - } - - std::string insert_text; - int newlines_after_name = 0; - LexFunctionDeclaration(working_file->buffer_content, ls_decl->start, - type_name, &insert_text, &newlines_after_name); - - if (!same_file_insert_end) { - same_file_insert_end = ls_decl->end; - same_file_insert_end->line += newlines_after_name; - same_file_insert_end->character = 1000; - } - - lsTextEdit edit; - - if (decl_file_id == impl_file_id) { - edit.range.start = *same_file_insert_end; - edit.range.end = *same_file_insert_end; - edit.newText = "\n\n" + insert_text; - } else { - lsPosition best_pos; - best_pos.line = default_line; - int best_dist = INT_MAX; - - QueryFile& file = db->files[impl_file_id.id]; - assert(file.def); - for (SymbolRef sym : file.def->outline) { - switch (sym.kind) { - case SymbolKind::Func: { - QueryFunc& sym_func = db->GetFunc(sym); - const QueryFunc::Def* def1 = sym_func.AnyDef(); - if (!def1 || !def1->extent) - break; - - for (Use func_decl : sym_func.declarations) { - 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 def_loc = - GetLsLocation(db, working_files, *def1->extent); - if (!def_loc) - continue; - - best_dist = dist; - - if (dist > 0) - best_pos = def_loc->range.start; - else - best_pos = def_loc->range.end; - } - } - } - - break; - } - case SymbolKind::Var: { - // TODO: handle vars. - break; - } - case SymbolKind::Invalid: - case SymbolKind::File: - case SymbolKind::Type: - LOG_S(WARNING) << "Unexpected SymbolKind " - << static_cast(sym.kind); - break; - } - } - - edit.range.start = best_pos; - edit.range.end = best_pos; - if (best_dist < 0) - edit.newText = "\n\n" + insert_text; - else - edit.newText = insert_text + "\n\n"; - } - - return edit; - } - - return nullopt; -} - -struct In_TextDocumentCodeAction : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - - // Contains additional diagnostic information about the context in which - // a code action is run. - struct lsCodeActionContext { - // An array of diagnostics. - std::vector diagnostics; - }; - // Params for the CodeActionRequest - struct lsCodeActionParams { - // The document in which the command was invoked. - lsTextDocumentIdentifier textDocument; - // The range for which the command was invoked. - lsRange range; - // Context carrying additional information. - lsCodeActionContext context; - }; - lsCodeActionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, - diagnostics); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, - textDocument, - range, - context); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); - -struct Out_TextDocumentCodeAction - : public lsOutMessage { - using Command = lsCommand; - - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result); - -struct Handler_TextDocumentCodeAction - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentCodeAction* request) override { - // NOTE: This code snippet will generate some FixIts for testing: - // - // struct origin { int x, int y }; - // void foo() { - // point origin = { - // x: 0.0, - // y: 0.0 - // }; - // } - // - - QueryFileId file_id; - QueryFile* file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) { - return; - } - - WorkingFile* working_file = working_files->GetFileByFilename( - request->params.textDocument.uri.GetPath()); - if (!working_file) { - // TODO: send error response. - LOG_S(WARNING) - << "[error] textDocument/codeAction could not find working file"; - return; - } - - Out_TextDocumentCodeAction out; - out.id = request->id; - - // TODO: auto-insert namespace? - - int default_line = (int)working_file->buffer_lines.size(); - - // Make sure to call EnsureImplFile before using these. We lazy load - // them because computing the values could involve an entire project - // scan. - optional impl_uri; - optional impl_file_id; - - std::vector syms = - FindSymbolsAtLocation(working_file, file, request->params.range.start); - for (SymbolRef sym : syms) { - switch (sym.kind) { - case SymbolKind::Type: { - QueryType& type = db->GetType(sym); - const QueryType::Def* def = type.AnyDef(); - if (!def) - break; - - int num_edits = 0; - - // Get implementation file. - Out_TextDocumentCodeAction::Command command; - - EachDefinedEntity(db->funcs, def->funcs, [&](QueryFunc& func_def) { - const QueryFunc::Def* def1 = func_def.AnyDef(); - if (def1->extent) - return; - EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/); - optional edit = BuildAutoImplementForFunction( - db, working_files, working_file, default_line, file_id, - *impl_file_id, func_def); - if (!edit) - return; - - ++num_edits; - - // Merge edits together if they are on the same line. - // TODO: be smarter about newline merging? ie, don't end up - // with foo()\n\n\n\nfoo(), we want foo()\n\nfoo()\n\n - // - if (!command.arguments.edits.empty() && - command.arguments.edits[command.arguments.edits.size() - 1] - .range.end.line == edit->range.start.line) { - command.arguments.edits[command.arguments.edits.size() - 1] - .newText += edit->newText; - } else { - command.arguments.edits.push_back(*edit); - } - }); - if (command.arguments.edits.empty()) - break; - - // If we're inserting at the end of the document, put a newline - // before the insertion. - if (command.arguments.edits[0].range.start.line >= default_line) - command.arguments.edits[0].newText.insert(0, "\n"); - - command.arguments.textDocumentUri = *impl_uri; - command.title = "Auto-Implement " + std::to_string(num_edits) + - " methods on " + std::string(def->ShortName()); - command.command = "cquery._autoImplement"; - out.result.push_back(command); - break; - } - - case SymbolKind::Func: { - QueryFunc& func = db->GetFunc(sym); - const QueryFunc::Def* def = func.AnyDef(); - if (!def || def->extent) - break; - - EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/); - - // Get implementation file. - Out_TextDocumentCodeAction::Command command; - command.title = "Auto-Implement " + std::string(def->ShortName()); - command.command = "cquery._autoImplement"; - command.arguments.textDocumentUri = *impl_uri; - optional edit = BuildAutoImplementForFunction( - db, working_files, working_file, default_line, file_id, - *impl_file_id, func); - if (!edit) - break; - - // If we're inserting at the end of the document, put a newline - // before the insertion. - if (edit->range.start.line >= default_line) - edit->newText.insert(0, "\n"); - command.arguments.edits.push_back(*edit); - out.result.push_back(command); - break; - } - default: - break; - } - - // Only show one auto-impl section. - if (!out.result.empty()) - break; - } - - std::vector diagnostics; - working_files->DoAction( - [&]() { diagnostics = working_file->diagnostics_; }); - for (lsDiagnostic& diag : diagnostics) { - if (diag.range.start.line != request->params.range.start.line) - continue; - - // For error diagnostics, provide an action to resolve an include. - // TODO: find a way to index diagnostic contents so line numbers - // don't get mismatched when actively editing a file. - std::string_view include_query = LexIdentifierAroundPos( - diag.range.start, working_file->buffer_content); - if (diag.severity == lsDiagnosticSeverity::Error && - !include_query.empty()) { - const size_t kMaxResults = 20; - - std::unordered_set include_absolute_paths; - - // Find include candidate strings. - for (size_t i = 0; i < db->symbols.size(); ++i) { - if (include_absolute_paths.size() > kMaxResults) - break; - if (db->GetSymbolDetailedName(i).find(include_query) == - std::string::npos) - continue; - - Maybe decl_file_id = - GetDeclarationFileForSymbol(db, db->symbols[i]); - if (!decl_file_id) - continue; - - QueryFile& decl_file = db->files[decl_file_id->id]; - if (!decl_file.def) - continue; - - include_absolute_paths.insert(decl_file.def->path); - } - - // Build include strings. - std::unordered_set include_insert_strings; - include_insert_strings.reserve(include_absolute_paths.size()); - - for (const std::string& path : include_absolute_paths) { - optional item = - include_complete->FindCompletionItemForAbsolutePath(path); - if (!item) - continue; - if (item->textEdit) - include_insert_strings.insert(item->textEdit->newText); - else if (!item->insertText.empty()) - include_insert_strings.insert(item->insertText); - else { - // FIXME https://github.com/cquery-project/cquery/issues/463 - LOG_S(WARNING) << "unable to determine insert string for include " - "completion item"; - } - } - - // Build code action. - if (!include_insert_strings.empty()) { - Out_TextDocumentCodeAction::Command command; - - // Build edits. - for (const std::string& include_insert_string : - include_insert_strings) { - lsTextEdit edit; - optional include_line = FindIncludeLine( - working_file->buffer_lines, include_insert_string); - if (!include_line) - continue; - - edit.range.start.line = *include_line; - edit.range.end.line = *include_line; - edit.newText = include_insert_string + "\n"; - command.arguments.edits.push_back(edit); - } - - // Setup metadata and send to client. - if (include_insert_strings.size() == 1) - command.title = "Insert " + *include_insert_strings.begin(); - else - command.title = "Pick one of " + - std::to_string(command.arguments.edits.size()) + - " includes to insert"; - command.command = "cquery._insertInclude"; - command.arguments.textDocumentUri = request->params.textDocument.uri; - out.result.push_back(command); - } - } - - // clang does not provide accurate enough column reporting for - // diagnostics to do good column filtering, so report all - // diagnostics on the line. - if (!diag.fixits_.empty()) { - Out_TextDocumentCodeAction::Command command; - command.title = "FixIt: " + diag.message; - command.command = "cquery._applyFixIt"; - command.arguments.textDocumentUri = request->params.textDocument.uri; - command.arguments.edits = diag.fixits_; - out.result.push_back(command); - } - } - - QueueManager::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); - -TEST_SUITE("FindIncludeLine") { - TEST_CASE("in document") { - std::vector lines = { - "#include ", // 0 - "#include " // 1 - }; - - REQUIRE(FindIncludeLine(lines, "#include ") == nullopt); - } - - TEST_CASE("insert before") { - std::vector lines = { - "#include ", // 0 - "#include " // 1 - }; - - REQUIRE(FindIncludeLine(lines, "#include ") == 0); - } - - TEST_CASE("insert middle") { - std::vector lines = { - "#include ", // 0 - "#include " // 1 - }; - - REQUIRE(FindIncludeLine(lines, "#include ") == 1); - } - - TEST_CASE("insert after") { - std::vector lines = { - "#include ", // 0 - "#include ", // 1 - "", // 2 - }; - - REQUIRE(FindIncludeLine(lines, "#include ") == 2); - } - - TEST_CASE("ignore header") { - std::vector lines = { - "// FOOBAR", // 0 - "// FOOBAR", // 1 - "// FOOBAR", // 2 - "// FOOBAR", // 3 - "", // 4 - "#include ", // 5 - "#include ", // 6 - "", // 7 - }; - - REQUIRE(FindIncludeLine(lines, "#include ") == 5); - REQUIRE(FindIncludeLine(lines, "#include ") == 6); - REQUIRE(FindIncludeLine(lines, "#include ") == 7); - } -} -} // namespace diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 903abf110..521268c05 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -47,21 +47,21 @@ void AddCodeLens(const char* singular, const std::vector& uses, bool force_display) { TCodeLens code_lens; - optional range = GetLsRange(common->working_file, use.range); + std::optional range = GetLsRange(common->working_file, use.range); if (!range) return; if (use.file == QueryFileId()) return; code_lens.range = *range; code_lens.command = lsCommand(); - code_lens.command->command = "cquery.showReferences"; + code_lens.command->command = "ccls.showReferences"; code_lens.command->arguments.uri = GetLsDocumentUri(common->db, use.file); code_lens.command->arguments.position = code_lens.range.start; // Add unique uses. std::unordered_set unique_uses; for (Use use1 : uses) { - optional location = + std::optional location = GetLsLocation(common->db, common->working_files, use1); if (!location) continue; @@ -177,10 +177,10 @@ struct Handler_TextDocumentCodeLens Maybe base_loc = GetDefinitionSpell( db, SymbolIdx{def->bases[0], SymbolKind::Func}); if (base_loc) { - optional ls_base = + std::optional ls_base = GetLsLocation(db, working_files, *base_loc); if (ls_base) { - optional range = + std::optional range = GetLsRange(common.working_file, sym.range); if (range) { TCodeLens code_lens; @@ -188,7 +188,7 @@ struct Handler_TextDocumentCodeLens code_lens.range.start.character += offset++; code_lens.command = lsCommand(); code_lens.command->title = "Base"; - code_lens.command->command = "cquery.goto"; + code_lens.command->command = "ccls.goto"; code_lens.command->arguments.uri = ls_base->uri; code_lens.command->arguments.position = ls_base->range.start; out.result.push_back(code_lens); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 7229d65b7..fd85c311c 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -36,7 +36,7 @@ struct lsCompletionContext { // The trigger character (a single character) that has trigger code complete. // Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` - optional triggerCharacter; + std::optional triggerCharacter; }; MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter); @@ -44,7 +44,7 @@ struct lsCompletionParams : lsTextDocumentPositionParams { // The completion context. This is only available it the client specifies to // send this using // `ClientCapabilities.textDocument.completion.contextSupport === true` - optional context; + std::optional context; }; MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); @@ -92,7 +92,7 @@ void DecorateIncludePaths(const std::smatch& match, item.textEdit->newText = prefix + quote0 + item.textEdit->newText + quote1 + suffix; item.label = prefix + quote0 + item.label + quote1 + suffix; - item.filterText = nullopt; + item.filterText = std::nullopt; } } diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index cf887adbc..95be3ab57 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -26,7 +26,7 @@ struct Handler_TextDocumentDidChange std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); if (config->enableIndexOnDidChange) { - optional content = ReadContent(path); + std::optional content = ReadContent(path); if (!content) { LOG_S(ERROR) << "Unable to read file content after saving " << path; } else { diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 770c9bcb8..9b3ee9fb6 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -19,9 +19,9 @@ struct In_TextDocumentDidOpen : public NotificationInMessage { struct Params { lsTextDocumentItem textDocument; - // cquery extension + // ccls extension // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project - // entry (e.g. loaded from compile_commands.json or .cquery). + // entry (e.g. loaded from compile_commands.json or .ccls). std::vector args; }; Params params; @@ -45,13 +45,13 @@ struct Handler_TextDocumentDidOpen std::shared_ptr cache_manager = ICacheManager::Make(config); WorkingFile* working_file = working_files->OnOpen(params.textDocument); - optional cached_file_contents = + std::optional cached_file_contents = cache_manager->LoadCachedFileContents(path); if (cached_file_contents) working_file->SetIndexContent(*cached_file_contents); QueryFile* file = nullptr; - FindFileOrFail(db, project, nullopt, path, &file); + FindFileOrFail(db, project, std::nullopt, path, &file); if (file && file->def) { EmitInactiveLines(working_file, file->def->inactive_regions); EmitSemanticHighlighting(db, semantic_cache, working_file, file); diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index f187f018d..751d4238d 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -50,7 +50,7 @@ struct Handler_TextDocumentDidSave // if so, ignore that index response. // TODO: send as priority request if (!config->enableIndexOnDidChange) { - optional content = ReadContent(path); + std::optional content = ReadContent(path); if (!content) { LOG_S(ERROR) << "Unable to read file content after saving " << path; } else { diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index 42e74cdb0..e3b1e4c65 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -44,7 +44,7 @@ struct Handler_TextDocumentDocumentHighlight EachOccurrence(db, sym, true, [&](Use use) { if (use.file != file_id) return; - if (optional ls_loc = + if (std::optional ls_loc = GetLsLocation(db, working_files, use)) { lsDocumentHighlight highlight; highlight.range = ls_loc->range; diff --git a/src/messages/text_document_document_link.cc b/src/messages/text_document_document_link.cc index 9a05365aa..b44639dfb 100644 --- a/src/messages/text_document_document_link.cc +++ b/src/messages/text_document_document_link.cc @@ -26,7 +26,7 @@ struct lsDocumentLink { // The range this link applies to. lsRange range; // The uri this link points to. If missing a resolve request is sent later. - optional target; + std::optional target; }; MAKE_REFLECT_STRUCT(lsDocumentLink, range, target); @@ -59,14 +59,14 @@ struct Handler_TextDocumentDocumentLink return; } for (const IndexInclude& include : file->def->includes) { - optional buffer_line = working_file->GetBufferPosFromIndexPos( + std::optional buffer_line = working_file->GetBufferPosFromIndexPos( include.line, nullptr, false); if (!buffer_line) continue; // Subtract 1 from line because querydb stores 1-based lines but // vscode expects 0-based lines. - optional between_quotes = ExtractQuotedRange( + std::optional between_quotes = ExtractQuotedRange( *buffer_line, working_file->buffer_lines[*buffer_line]); if (!between_quotes) continue; diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 2ec075330..09f6723bd 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -40,7 +40,7 @@ struct Handler_TextDocumentDocumentSymbol } for (SymbolRef sym : file->def->outline) { - optional info = + std::optional info = GetSymbolInfo(db, working_files, sym, true /*use_short_name*/); if (!info) continue; @@ -56,7 +56,7 @@ struct Handler_TextDocumentDocumentSymbol continue; } - if (optional location = GetLsLocation( + if (std::optional location = GetLsLocation( db, working_files, Use(sym.range, sym.id, sym.kind, sym.role, file_id))) { info->location = *location; diff --git a/src/messages/text_document_formatting.cc b/src/messages/text_document_formatting.cc index 793c86d63..49290b545 100644 --- a/src/messages/text_document_formatting.cc +++ b/src/messages/text_document_formatting.cc @@ -49,7 +49,7 @@ struct Handler_TextDocumentFormatting working_file->buffer_content.size(), request->params.options)); #else - LOG_S(WARNING) << "You must compile cquery with --use-clang-cxx to use " + LOG_S(WARNING) << "You must compile ccls with --use-clang-cxx to use " "textDocument/formatting."; // TODO: Fallback to execute the clang-format binary? response.result = {}; diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 6a852d8f4..a5b518128 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -52,11 +52,11 @@ REGISTER_IN_MESSAGE(In_TextDocumentHover); struct Out_TextDocumentHover : public lsOutMessage { struct Result { std::vector contents; - optional range; + std::optional range; }; lsRequestId id; - optional result; + std::optional result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); void Reflect(Writer& visitor, Out_TextDocumentHover& value) { @@ -66,7 +66,7 @@ void Reflect(Writer& visitor, Out_TextDocumentHover& value) { if (value.result) REFLECT_MEMBER(result); else { - // Empty optional<> is elided by the default serializer, we need to write + // Empty std::optional<> is elided by the default serializer, we need to write // |null| to be compliant with the LSP. visitor.Key("result"); visitor.Null(); @@ -92,7 +92,7 @@ struct Handler_TextDocumentHover : BaseMessageHandler { for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return hover. - optional ls_range = GetLsRange( + std::optional ls_range = GetLsRange( working_files->GetFileByFilename(file->def->path), sym.range); if (!ls_range) continue; diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc index 175dbb2ae..bc860f67b 100644 --- a/src/messages/text_document_range_formatting.cc +++ b/src/messages/text_document_range_formatting.cc @@ -58,7 +58,7 @@ struct Handler_TextDocumentRangeFormatting working_file->buffer_content, ClangFormatDocument(working_file, start, end, request->params.options)); #else - LOG_S(WARNING) << "You must compile cquery with --use-clang-cxx to use " + LOG_S(WARNING) << "You must compile ccls with --use-clang-cxx to use " "textDocument/rangeFormatting."; // TODO: Fallback to execute the clang-format binary? response.result = {}; diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index 19684cdb0..40f99531b 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -65,7 +65,7 @@ struct Handler_TextDocumentReferences db, sym, request->params.context.includeDeclaration, [&](Use use, lsSymbolKind parent_kind) { if (use.role & request->params.context.role) - if (optional ls_loc = + if (std::optional ls_loc = GetLsLocationEx(db, working_files, use, container)) { if (container) ls_loc->parentKind = parent_kind; diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index b8dcc9d9f..6dc26450b 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -12,7 +12,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { - optional ls_location = GetLsLocation(db, working_files, use); + std::optional ls_location = GetLsLocation(db, working_files, use); if (!ls_location) return; diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index 8f23e5be3..9ceb7410a 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -25,7 +25,7 @@ struct lsParameterInformation { // The human-readable doc-comment of this parameter. Will be shown // in the UI but can be omitted. - optional documentation; + std::optional documentation; }; MAKE_REFLECT_STRUCT(lsParameterInformation, label, documentation); @@ -39,7 +39,7 @@ struct lsSignatureInformation { // The human-readable doc-comment of this signature. Will be shown // in the UI but can be omitted. - optional documentation; + std::optional documentation; // The parameters of this signature. std::vector parameters; @@ -60,7 +60,7 @@ struct lsSignatureHelp { // rely on a default value. // In future version of the protocol this property might become // mandantory to better express this. - optional activeSignature; + std::optional activeSignature; // The active parameter of the active signature. If omitted or the value // lies outside the range of `signatures[activeSignature].parameters` @@ -69,7 +69,7 @@ struct lsSignatureHelp { // In future version of the protocol this property might become // mandantory to better express the active parameter if the // active signature does have any. - optional activeParameter; + std::optional activeParameter; }; MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index d44081e7d..ac2a1bd19 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -50,7 +50,7 @@ struct Handler_WorkspaceDidChangeWatchedFiles switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - optional content = ReadContent(path); + std::optional content = ReadContent(path); if (!content) LOG_S(ERROR) << "Unable to read file content after saving " << path; else { diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index e8f66f25d..a96360f3d 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -35,10 +35,10 @@ struct Handler_WorkspaceExecuteCommand const auto& params = request->params; Out_WorkspaceExecuteCommand out; out.id = request->id; - if (params.command == "cquery._applyFixIt") { - } else if (params.command == "cquery._autoImplement") { - } else if (params.command == "cquery._insertInclude") { - } else if (params.command == "cquery.showReferences") { + if (params.command == "ccls._applyFixIt") { + } else if (params.command == "ccls._autoImplement") { + } else if (params.command == "ccls._insertInclude") { + } else if (params.command == "ccls.showReferences") { out.result = params.arguments.locations; } diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index b069ec847..4294bd058 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -19,7 +19,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx symbol, std::vector* result) { - optional info = + std::optional info = GetSymbolInfo(db, working_files, symbol, false /*use_short_name*/); if (!info) return false; @@ -35,7 +35,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db, loc = decls[0]; } - optional ls_location = GetLsLocation(db, working_files, loc); + std::optional ls_location = GetLsLocation(db, working_files, loc); if (!ls_location) return false; info->location = *ls_location; diff --git a/src/method.cc b/src/method.cc index cd24524da..f1e38590c 100644 --- a/src/method.cc +++ b/src/method.cc @@ -3,8 +3,8 @@ MethodType kMethodType_Unknown = "$unknown"; MethodType kMethodType_Exit = "exit"; MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; -MethodType kMethodType_CqueryPublishInactiveRegions = "$cquery/publishInactiveRegions"; -MethodType kMethodType_CqueryPublishSemanticHighlighting = "$cquery/publishSemanticHighlighting"; +MethodType kMethodType_CclsPublishInactiveRegions = "$ccls/publishInactiveRegions"; +MethodType kMethodType_CclsPublishSemanticHighlighting = "$ccls/publishSemanticHighlighting"; InMessage::~InMessage() = default; diff --git a/src/method.h b/src/method.h index 77d926165..7931673e2 100644 --- a/src/method.h +++ b/src/method.h @@ -9,8 +9,8 @@ using MethodType = const char*; extern MethodType kMethodType_Unknown; extern MethodType kMethodType_Exit; extern MethodType kMethodType_TextDocumentPublishDiagnostics; -extern MethodType kMethodType_CqueryPublishInactiveRegions; -extern MethodType kMethodType_CqueryPublishSemanticHighlighting; +extern MethodType kMethodType_CclsPublishInactiveRegions; +extern MethodType kMethodType_CclsPublishSemanticHighlighting; using lsRequestId = std::variant; diff --git a/src/nt_string.h b/src/nt_string.h index 4083535ef..0bc1e2c68 100644 --- a/src/nt_string.h +++ b/src/nt_string.h @@ -1,10 +1,9 @@ #pragma once -#include - #include #include #include +#include #include // Nullable null-terminated string, which is null if default constructed, diff --git a/src/platform.h b/src/platform.h index cbefb30e3..106b89020 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include #include @@ -34,7 +34,7 @@ bool TryMakeDirectory(const std::string& absolute_path); void SetCurrentThreadName(const std::string& thread_name); -optional GetLastModificationTime(const std::string& absolute_path); +std::optional GetLastModificationTime(const std::string& absolute_path); void MoveFileTo(const std::string& destination, const std::string& source); void CopyFileTo(const std::string& destination, const std::string& source); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 12cb4a371..e3e34b29a 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -49,14 +49,14 @@ namespace { // Returns the canonicalized absolute pathname, without expanding symbolic // links. This is a variant of realpath(2), C++ rewrite of // https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c -optional RealPathNotExpandSymlink(std::string path) { +std::optional RealPathNotExpandSymlink(std::string path) { if (path.empty()) { errno = EINVAL; - return nullopt; + return std::nullopt; } if (path[0] == '\0') { errno = ENOENT; - return nullopt; + return std::nullopt; } // Do not use PATH_MAX because it is tricky on Linux. @@ -70,7 +70,7 @@ optional RealPathNotExpandSymlink(std::string path) { i = 1; } else { if (!getcwd(tmp, sizeof tmp)) - return nullopt; + return std::nullopt; resolved = tmp; } @@ -96,10 +96,10 @@ optional RealPathNotExpandSymlink(std::string path) { // lstat(2) because we do not want to resolve symlinks. resolved += next_token; if (stat(resolved.c_str(), &sb) != 0) - return nullopt; + return std::nullopt; if (!S_ISDIR(sb.st_mode) && j < path.size()) { errno = ENOTDIR; - return nullopt; + return std::nullopt; } } @@ -160,7 +160,7 @@ std::string GetWorkingDirectory() { } std::string NormalizePath(const std::string& path) { - optional resolved = RealPathNotExpandSymlink(path); + std::optional resolved = RealPathNotExpandSymlink(path); return resolved ? *resolved : path; } @@ -184,22 +184,22 @@ void SetCurrentThreadName(const std::string& thread_name) { #endif } -optional GetLastModificationTime(const std::string& absolute_path) { +std::optional GetLastModificationTime(const std::string& absolute_path) { struct stat buf; if (stat(absolute_path.c_str(), &buf) != 0) { switch (errno) { case ENOENT: // std::cerr << "GetLastModificationTime: unable to find file " << // absolute_path << std::endl; - return nullopt; + return std::nullopt; case EINVAL: // std::cerr << "GetLastModificationTime: invalid param to _stat for // file file " << absolute_path << std::endl; - return nullopt; + return std::nullopt; default: // std::cerr << "GetLastModificationTime: unhandled for " << // absolute_path << std::endl; exit(1); - return nullopt; + return std::nullopt; } } @@ -279,7 +279,7 @@ bool RunObjectiveCIndexTests() { void TraceMe() { // If the environment variable is defined, wait for a debugger. - // In gdb, you need to invoke `signal SIGCONT` if you want cquery to continue + // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. if (getenv("CQUERY_TRACEME")) raise(SIGTSTP); diff --git a/src/platform_win.cc b/src/platform_win.cc index 027b61506..2b7f81264 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -95,22 +95,22 @@ void SetCurrentThreadName(const std::string& thread_name) { } } -optional GetLastModificationTime(const std::string& absolute_path) { +std::optional GetLastModificationTime(const std::string& absolute_path) { struct _stat buf; if (_stat(absolute_path.c_str(), &buf) != 0) { switch (errno) { case ENOENT: // std::cerr << "GetLastModificationTime: unable to find file " << // absolute_path << std::endl; - return nullopt; + return std::nullopt; case EINVAL: // std::cerr << "GetLastModificationTime: invalid param to _stat for // file file " << absolute_path << std::endl; - return nullopt; + return std::nullopt; default: // std::cerr << "GetLastModificationTime: unhandled for " << // absolute_path << std::endl; exit(1); - return nullopt; + return std::nullopt; } } @@ -140,7 +140,7 @@ std::vector GetPlatformClangArguments() { // // These options are only needed if clang is targeting the msvc triple, // which depends on how clang was build for windows. clang downloaded from - // releases.llvm.org defaults to msvc, so cquery does as well. + // releases.llvm.org defaults to msvc, so ccls does as well. // // https://github.com/cquery-project/cquery/issues/509 has more context. // diff --git a/src/port.cc b/src/port.cc index 7f5d5be26..adb4cde65 100644 --- a/src/port.cc +++ b/src/port.cc @@ -3,7 +3,7 @@ #include #include -void cquery_unreachable_internal(const char* msg, const char* file, int line) { +void ccls_unreachable_internal(const char* msg, const char* file, int line) { fprintf(stderr, "unreachable %s:%d %s\n", file, line, msg); CQUERY_BUILTIN_UNREACHABLE; abort(); diff --git a/src/port.h b/src/port.h index 6b5a4e3d9..5680bfa91 100644 --- a/src/port.h +++ b/src/port.h @@ -19,10 +19,10 @@ #define CQUERY_BUILTIN_UNREACHABLE #endif -void cquery_unreachable_internal(const char* msg, const char* file, int line); +void ccls_unreachable_internal(const char* msg, const char* file, int line); #ifndef NDEBUG #define CQUERY_UNREACHABLE(msg) \ - cquery_unreachable_internal(msg, __FILE__, __LINE__) + ccls_unreachable_internal(msg, __FILE__, __LINE__) #else #define CQUERY_UNREACHABLE(msg) #endif diff --git a/src/project.cc b/src/project.cc index bf3f4968e..387fe3a03 100644 --- a/src/project.cc +++ b/src/project.cc @@ -62,7 +62,7 @@ bool IsWindowsAbsolutePath(const std::string& path) { (path[2] == '/' || path[2] == '\\') && is_drive_letter(path[0]); } -enum class ProjectMode { CompileCommandsJson, DotCquery, ExternalCommand }; +enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; struct ProjectConfig { std::unordered_set quote_dirs; @@ -130,7 +130,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( const CompileCommandsEntry& entry) { auto cleanup_maybe_relative_path = [&](const std::string& path) { // TODO/FIXME: Normalization will fail for paths that do not exist. Should - // it return an optional? + // it return an std::optional? assert(!path.empty()); if (entry.directory.empty() || IsUnixAbsolutePath(path) || IsWindowsAbsolutePath(path)) { @@ -181,33 +181,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( break; } } - size_t i = 1; - - // If |compilationDatabaseCommand| is specified, the external command provides - // us the JSON compilation database which should be strict. We should do very - // little processing on |args|. - if (config->mode != ProjectMode::ExternalCommand && !clang_cl) { - // Strip all arguments consisting the compiler command, - // as there may be non-compiler related commands beforehand, - // 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 < args.size() && args[i][0] != '-' && - // Do not skip over main source filename - NormalizePathWithTestOptOut(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 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 = args[i].rfind('.')) == std::string::npos || - dot + 4 < args[i].size() || isdigit(args[i][dot + 1]) || - !args[i].compare(dot + 1, 3, "exe"))) - ++i; - } // Compiler driver. - result.args.push_back(args[i - 1]); + result.args.push_back(args[0]); // Add -working-directory if not provided. if (!AnyStartsWith(args, "-working-directory")) @@ -226,6 +201,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Note that when processing paths, some arguments support multiple forms, ie, // {"-Ifoo"} or {"-I", "foo"}. Support both styles. + size_t i = 1; result.args.reserve(args.size() + config->extra_flags.size()); for (; i < args.size(); ++i) { std::string arg = args[i]; @@ -306,7 +282,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( result.args.push_back("-resource-dir=" + config->resource_dir); // There could be a clang version mismatch between what the project uses and - // what cquery uses. Make sure we do not emit warnings for mismatched options. + // what ccls uses. Make sure we do not emit warnings for mismatched options. if (!AnyStartsWith(result.args, "-Wno-unknown-warning-option")) result.args.push_back("-Wno-unknown-warning-option"); @@ -335,11 +311,11 @@ std::vector ReadCompilerArgumentsFromFile( std::vector LoadFromDirectoryListing(Config* init_opts, ProjectConfig* config) { std::vector result; - config->mode = ProjectMode::DotCquery; - LOG_IF_S(WARNING, !FileExists(config->project_dir + "/.cquery") && + config->mode = ProjectMode::DotCcls; + LOG_IF_S(WARNING, !FileExists(config->project_dir + "/.ccls") && config->extra_flags.empty()) - << "cquery has no clang arguments. Considering adding either a " - "compile_commands.json or .cquery file. See the cquery README for " + << "ccls has no clang arguments. Considering adding either a " + "compile_commands.json or .ccls file. See the ccls README for " "more information."; std::unordered_map> folder_args; @@ -350,8 +326,8 @@ std::vector LoadFromDirectoryListing(Config* init_opts, [&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; + } else if (GetBaseName(path) == ".ccls") { + LOG_S(INFO) << "Using .ccls arguments from " << path; folder_args.emplace(GetDirName(path), ReadCompilerArgumentsFromFile(path)); } @@ -359,7 +335,7 @@ std::vector LoadFromDirectoryListing(Config* init_opts, const auto& project_dir_args = folder_args[config->project_dir]; LOG_IF_S(INFO, !project_dir_args.empty()) - << "Using .cquery arguments " << StringJoin(project_dir_args); + << "Using .ccls arguments " << StringJoin(project_dir_args); auto GetCompilerArgumentForFile = [&config, &folder_args](const std::string& path) { @@ -396,8 +372,8 @@ std::vector LoadCompilationEntriesFromDirectory( Config* config, ProjectConfig* project, const std::string& opt_compilation_db_dir) { - // If there is a .cquery file always load using directory listing. - if (FileExists(project->project_dir + ".cquery")) + // If there is a .ccls file always load using directory listing. + if (FileExists(project->project_dir + ".ccls")) return LoadFromDirectoryListing(config, project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. @@ -412,7 +388,7 @@ std::vector LoadCompilationEntriesFromDirectory( #ifdef _WIN32 // TODO #else - char tmpdir[] = "/tmp/cquery-compdb-XXXXXX"; + char tmpdir[] = "/tmp/ccls-compdb-XXXXXX"; if (!mkdtemp(tmpdir)) return {}; comp_db_dir = tmpdir; @@ -654,7 +630,7 @@ void Project::Index(Config* config, WorkingFiles* wfiles, lsRequestId id) { ForAllFilteredFiles(config, [&](int i, const Project::Entry& entry) { - optional content = ReadContent(entry.filename); + std::optional content = ReadContent(entry.filename); if (!content) { LOG_S(ERROR) << "When loading project, canont read file " << entry.filename; @@ -1518,7 +1494,7 @@ TEST_SUITE("Project") { // Guess at same directory level, when there are parent directories. { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("/a/b/c/d/new.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg1"}); @@ -1526,7 +1502,7 @@ TEST_SUITE("Project") { // Guess at same directory level, when there are child directories. { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("/a/b/c/new.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg2"}); @@ -1534,7 +1510,7 @@ TEST_SUITE("Project") { // Guess at new directory (use the closest parent directory). { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("/a/b/c/new/new.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg2"}); @@ -1551,7 +1527,7 @@ TEST_SUITE("Project") { } { - optional entry = p.FindCompilationEntryForFile("ee.cc"); + std::optional entry = p.FindCompilationEntryForFile("ee.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"a", "b", "ee.cc", "d"}); } @@ -1569,7 +1545,7 @@ TEST_SUITE("Project") { REQUIRE(!IsWindowsAbsolutePath("C:/")); REQUIRE(!IsWindowsAbsolutePath("../abc/test")); REQUIRE(!IsWindowsAbsolutePath("5:/test")); - REQUIRE(!IsWindowsAbsolutePath("cquery/project/file.cc")); + REQUIRE(!IsWindowsAbsolutePath("ccls/project/file.cc")); REQUIRE(!IsWindowsAbsolutePath("")); REQUIRE(!IsWindowsAbsolutePath("/etc/linux/path")); } @@ -1597,25 +1573,25 @@ TEST_SUITE("Project") { // Prefer files with the same ending. { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("my_browsertest.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg1"}); } { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("my_unittest.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg2"}); } { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("common/my_browsertest.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg1"}); } { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("common/my_unittest.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg2"}); @@ -1623,7 +1599,7 @@ TEST_SUITE("Project") { // Prefer the same directory over matching file-ending. { - optional entry = + std::optional entry = p.FindCompilationEntryForFile("common/a/foo.cc"); REQUIRE(entry.has_value()); REQUIRE(entry->args == std::vector{"arg3"}); diff --git a/src/project.h b/src/project.h index 2e2a9253c..18e7bbd84 100644 --- a/src/project.h +++ b/src/project.h @@ -3,9 +3,9 @@ #include "config.h" #include "method.h" -#include +#include #include -#include +#include #include #include @@ -33,11 +33,11 @@ struct Project { // Loads a project for the given |directory|. // - // If |config->compilationDatabaseDirectory| is not empty, look for .cquery or + // If |config->compilationDatabaseDirectory| is not empty, look for .ccls or // compile_commands.json in it, otherwise they are retrieved in // |root_directory|. - // For .cquery, recursive directory listing is used and files with known - // suffixes are indexed. .cquery files can exist in subdirectories and they + // For .ccls, recursive directory listing is used and files with known + // suffixes are indexed. .ccls files can exist in subdirectories and they // will affect flags in their subtrees (relative paths are relative to the // project root, not subdirectories). For compile_commands.json, its entries // are indexed. diff --git a/src/query.cc b/src/query.cc index bb0d897bb..b1336b9eb 100644 --- a/src/query.cc +++ b/src/query.cc @@ -5,7 +5,7 @@ #include "serializers/json.h" #include -#include +#include #include #include @@ -39,10 +39,10 @@ void RemoveRange(std::vector* dest, const std::vector& to_remove) { dest->end()); } -optional ToQuery(const IdMap& id_map, +std::optional ToQuery(const IdMap& id_map, const IndexType::Def& type) { if (type.detailed_name.empty()) - return nullopt; + return std::nullopt; QueryType::Def result; result.detailed_name = type.detailed_name; @@ -64,10 +64,10 @@ optional ToQuery(const IdMap& id_map, return result; } -optional ToQuery(const IdMap& id_map, +std::optional ToQuery(const IdMap& id_map, const IndexFunc::Def& func) { if (func.detailed_name.empty()) - return nullopt; + return std::nullopt; QueryFunc::Def result; result.detailed_name = func.detailed_name; @@ -89,9 +89,9 @@ optional ToQuery(const IdMap& id_map, return result; } -optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { +std::optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { if (var.detailed_name.empty()) - return nullopt; + return std::nullopt; QueryVar::Def result; result.detailed_name = var.detailed_name; @@ -549,7 +549,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, }, /*onAdded:*/ [this, ¤t_id_map](IndexType* type) { - optional def_update = + std::optional def_update = ToQuery(current_id_map, type->def); if (def_update) types_def_update.push_back( @@ -574,9 +574,9 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexType* previous, IndexType* current) { - optional previous_remapped_def = + std::optional previous_remapped_def = ToQuery(previous_id_map, previous->def); - optional current_remapped_def = + std::optional current_remapped_def = ToQuery(current_id_map, current->def); if (current_remapped_def && previous_remapped_def != current_remapped_def && @@ -614,7 +614,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, }, /*onAdded:*/ [this, ¤t_id_map](IndexFunc* func) { - optional def_update = + std::optional def_update = ToQuery(current_id_map, func->def); if (def_update) funcs_def_update.push_back( @@ -635,9 +635,9 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexFunc* previous, IndexFunc* current) { - optional previous_remapped_def = + std::optional previous_remapped_def = ToQuery(previous_id_map, previous->def); - optional current_remapped_def = + std::optional current_remapped_def = ToQuery(current_id_map, current->def); if (current_remapped_def && previous_remapped_def != current_remapped_def && @@ -669,7 +669,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, }, /*onAdded:*/ [this, ¤t_id_map](IndexVar* var) { - optional def_update = ToQuery(current_id_map, var->def); + std::optional def_update = ToQuery(current_id_map, var->def); if (def_update) vars_def_update.push_back( QueryVar::DefUpdate(var->usr, std::move(*def_update))); @@ -685,9 +685,9 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexVar* previous, IndexVar* current) { - optional previous_remapped_def = + std::optional previous_remapped_def = ToQuery(previous_id_map, previous->def); - optional current_remapped_def = + std::optional current_remapped_def = ToQuery(current_id_map, current->def); if (current_remapped_def && previous_remapped_def != current_remapped_def && @@ -768,7 +768,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, // but it should be pretty minimal and is solved by simply restarting the // indexer and loading from cache, which is a fast operation. // - // TODO: Add "cquery: Reload Index" command which unloads all querydb state + // TODO: Add "ccls: Reload Index" command which unloads all querydb state // and fully reloads from cache. This will address the memory leak above. switch (usr_kind) { @@ -818,7 +818,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { // This function runs on the querydb thread. // Example types: -// storage_name => std::vector> +// storage_name => std::vector> // merge_update => QueryType::DerivedUpdate => // MergeableUpdate def => QueryType // def->def_var_name => std::vector @@ -831,7 +831,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { } for (const std::string& filename : update->files_removed) - files[usr_to_file[NormalizedPath(filename)].id].def = nullopt; + files[usr_to_file[NormalizedPath(filename)].id].def = std::nullopt; ImportOrUpdate(update->files_def_update); RemoveUsrs(SymbolKind::Type, update->types_removed); @@ -1111,7 +1111,7 @@ TEST_SUITE("query") { TEST_CASE("Remove variable with usage") { auto load_index_from_json = [](const char* json) { return Deserialize(SerializeFormat::Json, "foo.cc", json, "", - nullopt); + std::nullopt); }; auto previous = load_index_from_json(R"RAW( diff --git a/src/query.h b/src/query.h index 008d52a51..ac746aa68 100644 --- a/src/query.h +++ b/src/query.h @@ -110,13 +110,13 @@ struct QueryFile { std::vector all_symbols; // Parts of the file which are disabled. std::vector inactive_regions; - // Used by |$cquery/freshenIndex|. + // Used by |$ccls/freshenIndex|. std::vector dependencies; }; using DefUpdate = WithFileContent; - optional def; + std::optional def; Maybe> symbol_idx; explicit QueryFile(const std::string& path) { @@ -323,8 +323,8 @@ template <> struct IndexToQuery { using type = QueryVarId; }; template <> struct IndexToQuery { using type = Use; }; template <> struct IndexToQuery { using type = SymbolRef; }; template <> struct IndexToQuery { using type = Use; }; -template struct IndexToQuery> { - using type = optional::type>; +template struct IndexToQuery> { + using type = std::optional::type>; }; template struct IndexToQuery> { using type = std::vector::type>; @@ -349,7 +349,7 @@ struct IdMap { template Maybe::type> ToQuery(Maybe id) const { if (!id) - return nullopt; + return std::nullopt; return ToQuery(*id); } template diff --git a/src/query_utils.cc b/src/query_utils.cc index 81bab28f7..72e756c19 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -82,7 +82,7 @@ Maybe GetDeclarationFileForSymbol(QueryDatabase* db, break; } } - return nullopt; + return std::nullopt; } std::vector GetDeclarations(QueryDatabase* db, @@ -155,31 +155,31 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { return ret; } -optional GetLsPosition(WorkingFile* working_file, +std::optional GetLsPosition(WorkingFile* working_file, const Position& position) { if (!working_file) return lsPosition(position.line, position.column); int column = position.column; - if (optional start = + if (std::optional start = working_file->GetBufferPosFromIndexPos(position.line, &column, false)) return lsPosition(*start, column); - return nullopt; + return std::nullopt; } -optional GetLsRange(WorkingFile* working_file, const Range& location) { +std::optional GetLsRange(WorkingFile* working_file, const Range& location) { if (!working_file) { return lsRange(lsPosition(location.start.line, location.start.column), lsPosition(location.end.line, location.end.column)); } int start_column = location.start.column, end_column = location.end.column; - optional start = working_file->GetBufferPosFromIndexPos( + std::optional start = working_file->GetBufferPosFromIndexPos( location.start.line, &start_column, false); - optional end = working_file->GetBufferPosFromIndexPos(location.end.line, + std::optional end = working_file->GetBufferPosFromIndexPos(location.end.line, &end_column, true); if (!start || !end) - return nullopt; + return std::nullopt; // If remapping end fails (end can never be < start), just guess that the // final location didn't move. This only screws up the highlighted code @@ -218,25 +218,25 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) { } } -optional GetLsLocation(QueryDatabase* db, +std::optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, Use use) { std::string path; lsDocumentUri uri = GetLsDocumentUri(db, use.file, &path); - optional range = + std::optional range = GetLsRange(working_files->GetFileByFilename(path), use.range); if (!range) - return nullopt; + return std::nullopt; return lsLocation(uri, *range); } -optional GetLsLocationEx(QueryDatabase* db, +std::optional GetLsLocationEx(QueryDatabase* db, WorkingFiles* working_files, Use use, bool container) { - optional ls_loc = GetLsLocation(db, working_files, use); + std::optional ls_loc = GetLsLocation(db, working_files, use); if (!ls_loc) - return nullopt; + return std::nullopt; lsLocationEx ret; ret.lsLocation::operator=(*ls_loc); if (container) { @@ -282,7 +282,7 @@ lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym) { } // Returns a symbol. The symbol will have *NOT* have a location assigned. -optional GetSymbolInfo(QueryDatabase* db, +std::optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx sym, bool use_short_name) { @@ -314,7 +314,7 @@ optional GetSymbolInfo(QueryDatabase* db, } } - return nullopt; + return std::nullopt; } std::vector FindSymbolsAtLocation(WorkingFile* working_file, @@ -326,7 +326,7 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, int target_line = position.line; int target_column = position.character; if (working_file) { - optional index_line = working_file->GetIndexPosFromBufferPos( + std::optional index_line = working_file->GetIndexPosFromBufferPos( target_line, &target_column, false); if (index_line) target_line = *index_line; diff --git a/src/query_utils.h b/src/query_utils.h index f7f43a57f..a3bd30dfa 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -3,7 +3,7 @@ #include "query.h" #include "working_files.h" -#include +#include Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym); Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); @@ -24,18 +24,18 @@ std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym); std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root); std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root); -optional GetLsPosition(WorkingFile* working_file, +std::optional GetLsPosition(WorkingFile* working_file, const Position& position); -optional GetLsRange(WorkingFile* working_file, const Range& location); +std::optional GetLsRange(WorkingFile* working_file, const Range& location); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id, std::string* path); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id); -optional GetLsLocation(QueryDatabase* db, +std::optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, Use use); -optional GetLsLocationEx(QueryDatabase* db, +std::optional GetLsLocationEx(QueryDatabase* db, WorkingFiles* working_files, Use use, bool container); @@ -45,7 +45,7 @@ std::vector GetLsLocationExs(QueryDatabase* db, bool container, int limit); // Returns a symbol. The symbol will have *NOT* have a location assigned. -optional GetSymbolInfo(QueryDatabase* db, +std::optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx sym, bool use_short_name); diff --git a/src/recorder.cc b/src/recorder.cc index 94a46ed00..f369d85f9 100644 --- a/src/recorder.cc +++ b/src/recorder.cc @@ -12,7 +12,7 @@ std::ofstream* g_file_out = nullptr; void EnableRecording(std::string path) { if (path.empty()) - path = "cquery"; + path = "ccls"; // We can only call |EnableRecording| once. assert(!g_file_in && !g_file_out); diff --git a/src/recorder.h b/src/recorder.h index 772841d3a..f3474ae65 100644 --- a/src/recorder.h +++ b/src/recorder.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/src/semantic_highlight_symbol_cache.cc b/src/semantic_highlight_symbol_cache.cc index 10f8ebc41..3fc045bc7 100644 --- a/src/semantic_highlight_symbol_cache.cc +++ b/src/semantic_highlight_symbol_cache.cc @@ -5,7 +5,7 @@ SemanticHighlightSymbolCache::Entry::Entry( const std::string& path) : all_caches_(all_caches), path(path) {} -optional SemanticHighlightSymbolCache::Entry::TryGetStableId( +std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( SymbolKind kind, const std::string& detailed_name) { TNameToId* map = GetMapForSymbol_(kind); @@ -13,19 +13,19 @@ optional SemanticHighlightSymbolCache::Entry::TryGetStableId( if (it != map->end()) return it->second; - return nullopt; + return std::nullopt; } int SemanticHighlightSymbolCache::Entry::GetStableId( SymbolKind kind, const std::string& detailed_name) { - optional id = TryGetStableId(kind, detailed_name); + std::optional id = TryGetStableId(kind, detailed_name); if (id) return *id; // Create a new id. First try to find a key in another map. all_caches_->cache_.IterateValues([&](const std::shared_ptr& entry) { - optional other_id = entry->TryGetStableId(kind, detailed_name); + std::optional other_id = entry->TryGetStableId(kind, detailed_name); if (other_id) { id = other_id; return false; diff --git a/src/semantic_highlight_symbol_cache.h b/src/semantic_highlight_symbol_cache.h index f540ecb90..907be1e61 100644 --- a/src/semantic_highlight_symbol_cache.h +++ b/src/semantic_highlight_symbol_cache.h @@ -4,7 +4,7 @@ #include "match.h" #include "query.h" -#include +#include #include #include @@ -25,7 +25,7 @@ struct SemanticHighlightSymbolCache { Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path); - optional TryGetStableId(SymbolKind kind, + std::optional TryGetStableId(SymbolKind kind, const std::string& detailed_name); int GetStableId(SymbolKind kind, const std::string& detailed_name); diff --git a/src/serializer.cc b/src/serializer.cc index 02f8fd3c9..7cd1df72b 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -360,7 +360,7 @@ std::unique_ptr Deserialize( const std::string& path, const std::string& serialized_index_content, const std::string& file_content, - optional expected_version) { + std::optional expected_version) { if (serialized_index_content.empty()) return nullptr; diff --git a/src/serializer.h b/src/serializer.h index dbee42438..b2b9b65cf 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -5,14 +5,15 @@ #include "port.h" #include -#include -#include -#include #include +#include #include +#include #include +#include #include +#include #include enum class SerializeFormat { Json, MessagePack }; @@ -176,13 +177,13 @@ void Reflect(Writer& visitor, SerializeFormat& value); //// Type constructors -// ReflectMember optional is used to represent TypeScript optional properties +// ReflectMember std::optional is used to represent TypeScript std::optional properties // (in `key: value` context). -// Reflect optional is used for a different purpose, whether an object is +// Reflect std::optional is used for a different purpose, whether an object is // nullable (possibly in `value` context). For the nullable semantics, // std::variant is recommended. template -void Reflect(Reader& visitor, optional& value) { +void Reflect(Reader& visitor, std::optional& value) { if (visitor.IsNull()) { visitor.GetNull(); return; @@ -192,7 +193,7 @@ void Reflect(Reader& visitor, optional& value) { value = std::move(real_value); } template -void Reflect(Writer& visitor, optional& value) { +void Reflect(Writer& visitor, std::optional& value) { if (value) Reflect(visitor, *value); else @@ -219,8 +220,8 @@ void Reflect(Writer& visitor, Maybe& value) { } template -void ReflectMember(Writer& visitor, const char* name, optional& value) { - // For TypeScript optional property key?: value in the spec, +void ReflectMember(Writer& visitor, const char* name, std::optional& value) { + // For TypeScript std::optional property key?: value in the spec, // We omit both key and value if value is std::nullopt (null) for JsonWriter // to reduce output. But keep it for other serialization formats. if (value || visitor.Format() != SerializeFormat::Json) { @@ -238,22 +239,13 @@ void ReflectMember(Writer& visitor, const char* name, Maybe& value) { } } -// Backport C++17 std::disjunction -namespace { -template -struct disjunction - : std::conditional>::type {}; -template -struct disjunction : B0 {}; -} // namespace - // Helper struct to reflect std::variant template struct ReflectVariant { // If T appears in Ts..., we should set the value of std::variant to // what we get from Reader. template - typename std::enable_if...>::value, + typename std::enable_if...>::value, void>::type ReflectTag(Reader& visitor, std::variant& value) { T a; @@ -263,7 +255,7 @@ struct ReflectVariant { // This SFINAE overload is used to prevent compile error. value = a; is not // allowed if T does not appear in Ts... template - typename std::enable_if...>::value, + typename std::enable_if...>::value, void>::type ReflectTag(Reader&, std::variant&) {} @@ -273,7 +265,7 @@ struct ReflectVariant { ReflectTag(visitor, value); // It is possible that IsInt64() && IsInt(). We don't call ReflectTag // if int is not in Ts... - else if (disjunction...>::value && visitor.IsInt()) + else if (std::disjunction...>::value && visitor.IsInt()) ReflectTag(visitor, value); else if (visitor.IsInt64()) ReflectTag(visitor, value); @@ -363,6 +355,6 @@ std::unique_ptr Deserialize( const std::string& path, const std::string& serialized_index_content, const std::string& file_content, - optional expected_version); + std::optional expected_version); void SetTestOutputMode(); diff --git a/src/standard_includes.cc b/src/standard_includes.cc index 42cc35b3f..43a67c301 100644 --- a/src/standard_includes.cc +++ b/src/standard_includes.cc @@ -95,7 +95,7 @@ const char* kStandardLibraryIncludes[177] = { "new", "nl_types.h", "numeric", - "optional", + "std::optional", "ostream", "poll.h", "pthread.h", diff --git a/src/symbol.h b/src/symbol.h index bcbc6c64d..54a09272e 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -75,7 +75,7 @@ struct lsDocumentHighlight { // The highlight kind, default is DocumentHighlightKind.Text. lsDocumentHighlightKind kind = lsDocumentHighlightKind::Text; - // cquery extension + // ccls extension Role role = Role::None; }; MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); diff --git a/src/task.cc b/src/task.cc index b26f7b600..7a545d71e 100644 --- a/src/task.cc +++ b/src/task.cc @@ -23,14 +23,14 @@ void TaskManager::SetIdle(TaskThread thread, const TIdleTask& task) { queue->idle_task = task; } -bool TaskManager::RunTasks(TaskThread thread, optional> max_time) { +bool TaskManager::RunTasks(TaskThread thread, std::optional> max_time) { auto start = std::chrono::high_resolution_clock::now(); TaskQueue* queue = pending_tasks_[thread].get(); bool ran_task = false; while (true) { - optional task; + std::optional task; // Get a task. { @@ -79,7 +79,7 @@ TEST_CASE("tasks are run as soon as they are posted") { }); // Execute all tasks. - tm.RunTasks(TaskThread::QueryDb, nullopt); + tm.RunTasks(TaskThread::QueryDb, std::nullopt); // Tasks are executed in reverse order. REQUIRE(a == 3); @@ -106,7 +106,7 @@ TEST_CASE("post from inside task manager") { }); // Execute all tasks. - tm.RunTasks(TaskThread::QueryDb, nullopt); + tm.RunTasks(TaskThread::QueryDb, std::nullopt); // Tasks are executed in normal order because the next task is not posted // until the previous one is executed. @@ -125,7 +125,7 @@ TEST_CASE("idle task is run after nested tasks") { }); // No tasks posted - idle runs once. - REQUIRE(tm.RunTasks(TaskThread::QueryDb, nullopt)); + REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt)); REQUIRE(count == 1); count = 0; @@ -134,7 +134,7 @@ TEST_CASE("idle task is run after nested tasks") { tm.Post(TaskThread::QueryDb, [&]() { did_run = true; }); - REQUIRE(tm.RunTasks(TaskThread::QueryDb, nullopt)); + REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt)); REQUIRE(did_run); REQUIRE(count == 1); } @@ -142,10 +142,10 @@ TEST_CASE("idle task is run after nested tasks") { TEST_CASE("RunTasks returns false when idle task returns false and no other tasks were run") { TaskManager tm; - REQUIRE(tm.RunTasks(TaskThread::QueryDb, nullopt) == false); + REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt) == false); tm.SetIdle(TaskThread::QueryDb, []() { return false; }); - REQUIRE(tm.RunTasks(TaskThread::QueryDb, nullopt) == false); + REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt) == false); } TEST_SUITE_END(); diff --git a/src/task.h b/src/task.h index 04feeedb3..5cdd4e0a0 100644 --- a/src/task.h +++ b/src/task.h @@ -1,7 +1,7 @@ #if false #pragma once -#include +#include #include #include @@ -28,10 +28,10 @@ struct TaskManager { // Run pending tasks for |thread|. Stop running tasks after |max_time| has // elapsed. Returns true if tasks were run. - bool RunTasks(TaskThread thread, optional> max_time); + bool RunTasks(TaskThread thread, std::optional> max_time); struct TaskQueue { - optional idle_task; + std::optional idle_task; std::vector tasks; std::mutex tasks_mutex; }; diff --git a/src/test.cc b/src/test.cc index 925a82f46..22524ab72 100644 --- a/src/test.cc +++ b/src/test.cc @@ -200,8 +200,8 @@ void DiffDocuments(std::string path, << std::endl; #if _POSIX_C_SOURCE >= 200809L - char expected_file[] = "/tmp/cquery.expected.XXXXXX"; - char actual_file[] = "/tmp/cquery.actual.XXXXXX"; + char expected_file[] = "/tmp/ccls.expected.XXXXXX"; + char actual_file[] = "/tmp/ccls.actual.XXXXXX"; int expected_fd = mkstemp(expected_file); int actual_fd = mkstemp(actual_file); dprintf(expected_fd, "%s", joined_expected_output.c_str()); @@ -269,7 +269,7 @@ void VerifySerializeToFrom(IndexFile* file) { std::string serialized = Serialize(SerializeFormat::Json, *file); std::unique_ptr result = Deserialize(SerializeFormat::Json, "--.cc", serialized, "", - nullopt /*expected_version*/); + std::nullopt /*expected_version*/); std::string actual = result->ToString(); if (expected != actual) { std::cerr << "Serialization failure" << std::endl; @@ -310,7 +310,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { if (GetClangVersion() != kRequiredClangVersion && GetClangVersion().find("trunk") == std::string::npos) { std::cerr << "Index tests must be run using clang version \"" - << kRequiredClangVersion << "\" (cquery is running with \"" + << kRequiredClangVersion << "\" (ccls is running with \"" << GetClangVersion() << "\")" << std::endl; return false; } @@ -378,7 +378,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { std::string expected_output = text_replacer.Apply(entry.second); // FIXME: promote to utils, find and remove duplicates (ie, - // cquery_call_tree.cc, maybe something in project.cc). + // ccls_call_tree.cc, maybe something in project.cc). auto basename = [](const std::string& path) -> std::string { size_t last_index = path.find_last_of('/'); if (last_index == std::string::npos) diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 5f9404e0d..5b3608a82 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -2,7 +2,7 @@ #include "utils.h" -#include +#include #include #include @@ -172,7 +172,7 @@ struct ThreadedQueue : public BaseThreadQueue { // Get the first element from the queue without blocking. Returns a null // value if the queue is empty. - optional TryPopFrontHelper(int which) { + std::optional TryPopFrontHelper(int which) { std::lock_guard lock(mutex_); auto execute = [&](std::deque* q) { auto val = std::move(q->front()); @@ -184,12 +184,12 @@ struct ThreadedQueue : public BaseThreadQueue { return execute(&priority_); if (which & 1 && queue_.size()) return execute(&queue_); - return nullopt; + return std::nullopt; } - optional TryPopFront() { return TryPopFrontHelper(3); } + std::optional TryPopFront() { return TryPopFrontHelper(3); } - optional TryPopBack() { + std::optional TryPopBack() { std::lock_guard lock(mutex_); auto execute = [&](std::deque* q) { auto val = std::move(q->back()); @@ -202,12 +202,12 @@ struct ThreadedQueue : public BaseThreadQueue { return execute(&queue_); if (priority_.size()) return execute(&priority_); - return nullopt; + return std::nullopt; } - optional TryPopFrontLow() { return TryPopFrontHelper(1); } + std::optional TryPopFrontLow() { return TryPopFrontHelper(1); } - optional TryPopFrontHigh() { return TryPopFrontHelper(2); } + std::optional TryPopFrontHigh() { return TryPopFrontHelper(2); } mutable std::mutex mutex_; diff --git a/src/timer.cc b/src/timer.cc index c2b37c0b1..94bc9cf58 100644 --- a/src/timer.cc +++ b/src/timer.cc @@ -46,7 +46,7 @@ void Timer::Pause() { .count(); elapsed_ += elapsed; - start_ = nullopt; + start_ = std::nullopt; } void Timer::Resume() { diff --git a/src/timer.h b/src/timer.h index bbe2a955b..182da6713 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -25,7 +25,7 @@ struct Timer { void Resume(); // Raw start time. - optional> start_; + std::optional> start_; // Elapsed time. long long elapsed_ = 0; }; diff --git a/src/timestamp_manager.cc b/src/timestamp_manager.cc index c99241477..77f69accd 100644 --- a/src/timestamp_manager.cc +++ b/src/timestamp_manager.cc @@ -3,7 +3,7 @@ #include "cache_manager.h" #include "indexer.h" -optional TimestampManager::GetLastCachedModificationTime( +std::optional TimestampManager::GetLastCachedModificationTime( ICacheManager* cache_manager, const std::string& path) { { @@ -14,7 +14,7 @@ optional TimestampManager::GetLastCachedModificationTime( } IndexFile* file = cache_manager->TryLoad(path); if (!file) - return nullopt; + return std::nullopt; UpdateCachedModificationTime(path, file->last_modification_time); return file->last_modification_time; diff --git a/src/timestamp_manager.h b/src/timestamp_manager.h index 5fbc0865e..ac02b10fc 100644 --- a/src/timestamp_manager.h +++ b/src/timestamp_manager.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -11,7 +11,7 @@ struct ICacheManager; // important for import perf, as during dependency checking the same files are // checked over and over again if they are common headers. struct TimestampManager { - optional GetLastCachedModificationTime(ICacheManager* cache_manager, + std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, const std::string& path); void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); diff --git a/src/utils.cc b/src/utils.cc index 38080abf4..f20e3c02a 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -215,14 +215,14 @@ static void GetFilesInFolderHelper( goto bail; } - // Skip all dot files except .cquery. + // Skip all dot files except .ccls. // // The nested ifs are intentional, branching order is subtle here. // // Note that in the future if we do support dot directories/files, we must // always ignore the '.' and '..' directories otherwise this will loop // infinitely. - if (file.name[0] != '.' || strcmp(file.name, ".cquery") == 0) { + if (file.name[0] != '.' || strcmp(file.name, ".ccls") == 0) { if (file.is_dir) { if (recursive) { std::string child_dir = q.front().second + file.name + "/"; @@ -315,7 +315,7 @@ bool FileExists(const std::string& filename) { return cache.is_open(); } -optional ReadContent(const std::string& filename) { +std::optional ReadContent(const std::string& filename) { LOG_S(INFO) << "Reading " << filename; std::ifstream cache; cache.open(filename); @@ -324,7 +324,7 @@ optional ReadContent(const std::string& filename) { return std::string(std::istreambuf_iterator(cache), std::istreambuf_iterator()); } catch (std::ios_base::failure&) { - return nullopt; + return std::nullopt; } } diff --git a/src/utils.h b/src/utils.h index da54e338c..860a8fa21 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include #include @@ -94,7 +94,7 @@ std::string EscapeFileName(std::string path); // FIXME: Move ReadContent into ICacheManager? bool FileExists(const std::string& filename); -optional ReadContent(const std::string& filename); +std::optional ReadContent(const std::string& filename); std::vector ReadLinesWithEnding(std::string filename); std::vector ToLines(const std::string& content, bool trim_whitespace); diff --git a/src/working_files.cc b/src/working_files.cc index 64c091c31..1e173eec1 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -146,7 +146,7 @@ int AlignColumn(const std::string& a, int column, std::string b, bool is_end) { // Find matching buffer line of index_lines[line]. // By symmetry, this can also be used to find matching index line of a buffer // line. -optional FindMatchingLine(const std::vector& index_lines, +std::optional FindMatchingLine(const std::vector& index_lines, const std::vector& index_to_buffer, int line, int* column, @@ -171,7 +171,7 @@ optional FindMatchingLine(const std::vector& index_lines, down = down >= int(index_to_buffer.size()) ? int(buffer_lines.size()) - 1 : index_to_buffer[down]; if (up > down) - return nullopt; + return std::nullopt; // Search for lines [up,down] and use Myers's diff algorithm to find the best // match (least edit distance). @@ -313,7 +313,7 @@ void WorkingFile::ComputeLineMapping() { buffer_to_index[index_to_buffer[i]] = i; } -optional WorkingFile::GetBufferPosFromIndexPos(int line, +std::optional WorkingFile::GetBufferPosFromIndexPos(int line, int* column, bool is_end) { // The implementation is simple but works pretty well for most cases. We @@ -333,7 +333,7 @@ optional WorkingFile::GetBufferPosFromIndexPos(int line, LOG_S(WARNING) << "Bad index_line (got " << line << ", expected [0, " << index_lines.size() << ")) in " << filename << stack.c_str(); - return nullopt; + return std::nullopt; } if (index_to_buffer.empty()) @@ -342,12 +342,12 @@ optional WorkingFile::GetBufferPosFromIndexPos(int line, buffer_lines, is_end); } -optional WorkingFile::GetIndexPosFromBufferPos(int line, +std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int* column, bool is_end) { // See GetBufferLineFromIndexLine for additional comments. if (line < 0 || line >= (int)buffer_lines.size()) - return nullopt; + return std::nullopt; if (buffer_to_index.empty()) ComputeLineMapping(); diff --git a/src/working_files.h b/src/working_files.h index 60ce33750..c48c57d83 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -4,7 +4,7 @@ #include "utils.h" #include -#include +#include #include #include @@ -42,10 +42,10 @@ struct WorkingFile { // Also resolves |column| if not NULL. // When resolving a range, use is_end = false for begin() and is_end = // true for end() to get a better alignment of |column|. - optional GetBufferPosFromIndexPos(int line, int* column, bool is_end); + std::optional GetBufferPosFromIndexPos(int line, int* column, bool is_end); // Finds the index line number which maps to buffer line number |line|. // Also resolves |column| if not NULL. - optional GetIndexPosFromBufferPos(int line, int* column, bool is_end); + std::optional GetIndexPosFromBufferPos(int line, int* column, bool is_end); // TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into // lex_utils.h/cc diff --git a/third_party/string_view.h b/third_party/string_view.h deleted file mode 100644 index 3c858d730..000000000 --- a/third_party/string_view.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#define STX_NAMESPACE_NAME std -#include "string_view.hpp" From 89dd4b066b4cb7e3345e2c6248805e74537738ff Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Mar 2018 22:05:21 -0700 Subject: [PATCH 052/378] . --- .gitignore | 1 + CMakeLists.txt | 7 - README.md | 3 +- compile_commands.json | 1 - src/clang_complete.h | 2 +- src/clang_cursor.cc | 23 +- src/clang_cursor.h | 11 + src/clang_format.cc | 117 ------- src/clang_format.h | 18 - src/clang_index.cc | 22 -- src/clang_index.h | 14 - src/clang_indexer.cc | 54 --- src/clang_translation_unit.h | 3 +- src/clang_utils.cc | 80 +---- src/clang_utils.h | 12 +- src/command_line.cc | 79 +---- src/include_complete.cc | 2 - src/indexer.h | 10 +- src/lsp.cc | 3 - src/message_handler.cc | 72 +++- src/message_handler.h | 38 +- src/messages/initialize.cc | 22 +- src/messages/text_document_completion.cc | 5 +- src/recorder.cc | 56 --- src/recorder.h | 9 - src/semantic_highlight_symbol_cache.cc | 72 ---- src/semantic_highlight_symbol_cache.h | 43 --- src/task.cc | 152 -------- src/task.h | 41 --- wscript | 424 ----------------------- 30 files changed, 159 insertions(+), 1237 deletions(-) delete mode 120000 compile_commands.json delete mode 100644 src/clang_format.cc delete mode 100644 src/clang_format.h delete mode 100644 src/clang_index.cc delete mode 100644 src/clang_index.h delete mode 100644 src/recorder.cc delete mode 100644 src/recorder.h delete mode 100644 src/semantic_highlight_symbol_cache.cc delete mode 100644 src/semantic_highlight_symbol_cache.h delete mode 100644 src/task.cc delete mode 100644 src/task.h delete mode 100644 wscript diff --git a/.gitignore b/.gitignore index a0783c5f0..87cc1bce2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ build debug release +/compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 90c13cc97..63db0c0f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,8 +170,6 @@ target_sources(ccls PRIVATE src/cache_manager.cc src/clang_complete.cc src/clang_cursor.cc - src/clang_format.cc - src/clang_index.cc src/clang_indexer.cc src/clang_translation_unit.cc src/clang_utils.cc @@ -201,11 +199,8 @@ target_sources(ccls PRIVATE src/query_utils.cc src/query.cc src/queue_manager.cc - src/recorder.cc - src/semantic_highlight_symbol_cache.cc src/serializer.cc src/standard_includes.cc - src/task.cc src/test.cc src/third_party_impl.cc src/timer.cc @@ -242,9 +237,7 @@ target_sources(ccls PRIVATE src/messages/text_document_document_highlight.cc src/messages/text_document_document_link.cc src/messages/text_document_document_symbol.cc - src/messages/text_document_formatting.cc src/messages/text_document_hover.cc - src/messages/text_document_range_formatting.cc src/messages/text_document_references.cc src/messages/text_document_rename.cc src/messages/text_document_signature_help.cc diff --git a/README.md b/README.md index 9f29f1b23..5d9737d29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # ccls -ccls is a fork of cquery, a C/C++/Objective-C language server. +ccls is a fork of cquery (originally written by Jacob Dufault), +a C/C++/Objective-C language server. * code completion (with both signature help and snippets) * finding [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc) diff --git a/compile_commands.json b/compile_commands.json deleted file mode 120000 index 4595a4b07..000000000 --- a/compile_commands.json +++ /dev/null @@ -1 +0,0 @@ -build/release/compile_commands.json \ No newline at end of file diff --git a/src/clang_complete.h b/src/clang_complete.h index 0ed458962..142ab86a9 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -1,6 +1,6 @@ #pragma once -#include "clang_index.h" +#include "clang_cursor.h" #include "clang_translation_unit.h" #include "lru_cache.h" #include "lsp_completion.h" diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index 8ce4c2626..35197f729 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -2,10 +2,10 @@ #include "clang_utils.h" +#include #include - #include -#include +#include Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { CXSourceLocation start = clang_getRangeStart(range); @@ -284,3 +284,22 @@ NtString ClangCursor::get_comments() const { std::string ClangCursor::ToString() const { return ::ToString(get_kind()) + " " + get_spell_name(); } + +ClangIndex::ClangIndex() : ClangIndex(1, 0) {} + +ClangIndex::ClangIndex(int exclude_declarations_from_pch, + int display_diagnostics) { + // llvm::InitializeAllTargets (and possibly others) called by + // clang_createIndex transtively modifies/reads lib/Support/TargetRegistry.cpp + // FirstTarget. There will be a race condition if two threads call + // clang_createIndex concurrently. + static std::mutex mutex_; + std::lock_guard lock(mutex_); + + cx_index = + clang_createIndex(exclude_declarations_from_pch, display_diagnostics); +} + +ClangIndex::~ClangIndex() { + clang_disposeIndex(cx_index); +} diff --git a/src/clang_cursor.h b/src/clang_cursor.h index 53f94cfaa..6084408dc 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -114,3 +114,14 @@ struct hash { } }; } // namespace std + +// Simple RAII wrapper about CXIndex. +// Note: building a ClangIndex instance acquires a global lock, since libclang +// API does not appear to be thread-safe here. +class ClangIndex { + public: + ClangIndex(); + ClangIndex(int exclude_declarations_from_pch, int display_diagnostics); + ~ClangIndex(); + CXIndex cx_index; +}; diff --git a/src/clang_format.cc b/src/clang_format.cc deleted file mode 100644 index 5bb238a83..000000000 --- a/src/clang_format.cc +++ /dev/null @@ -1,117 +0,0 @@ -#if USE_CLANG_CXX - -#include "clang_format.h" -#include "working_files.h" - -#include -#include - -using namespace clang; -using clang::format::FormatStyle; - -namespace { - -// TODO Objective-C 'header/interface' files may use .h, we should get this from -// project information. -FormatStyle::LanguageKind getLanguageKindFromFilename( - llvm::StringRef filename) { - if (filename.endswith(".m") || filename.endswith(".mm")) { - return FormatStyle::LK_ObjC; - } - return FormatStyle::LK_Cpp; -} - -} // namespace - -std::vector ClangFormatDocument( - WorkingFile* working_file, - int start, - int end, - lsFormattingOptions options) { - const auto language_kind = - getLanguageKindFromFilename(working_file->filename); - FormatStyle predefined_style; - getPredefinedStyle("chromium", language_kind, &predefined_style); - llvm::Expected style = - format::getStyle("file", working_file->filename, "chromium"); - if (!style) { - // If, for some reason, we cannot get a format style, use Chromium's with - // tab configuration provided by the client editor. - LOG_S(ERROR) << llvm::toString(style.takeError()); - predefined_style.UseTab = options.insertSpaces - ? FormatStyle::UseTabStyle::UT_Never - : FormatStyle::UseTabStyle::UT_Always; - predefined_style.IndentWidth = options.tabSize; - } - - auto format_result = reformat( - style ? *style : predefined_style, working_file->buffer_content, - llvm::ArrayRef(tooling::Range(start, end - start)), - working_file->filename); - return std::vector(format_result.begin(), - format_result.end()); -} - -TEST_SUITE("ClangFormat") { - TEST_CASE("entireDocument") { - const std::string sample_document = "int main() { int *i = 0; return 0; }"; - WorkingFile* file = new WorkingFile("foo.cc", sample_document); - lsFormattingOptions formatting_options; - formatting_options.insertSpaces = true; - const auto replacements = ClangFormatDocument( - file, 0, sample_document.size(), formatting_options); - - // echo "int main() { int *i = 0; return 0; }" | clang-format - // -style=Chromium -output-replacements-xml - // - // - // - // - // - // - // - // - // - - REQUIRE(replacements.size() == 5); - REQUIRE(replacements[0].getOffset() == 12); - REQUIRE(replacements[0].getLength() == 1); - REQUIRE(replacements[0].getReplacementText() == "\n "); - - REQUIRE(replacements[1].getOffset() == 16); - REQUIRE(replacements[1].getLength() == 1); - REQUIRE(replacements[1].getReplacementText() == ""); - - REQUIRE(replacements[2].getOffset() == 18); - REQUIRE(replacements[2].getLength() == 0); - REQUIRE(replacements[2].getReplacementText() == " "); - - REQUIRE(replacements[3].getOffset() == 24); - REQUIRE(replacements[3].getLength() == 1); - REQUIRE(replacements[3].getReplacementText() == "\n "); - - REQUIRE(replacements[4].getOffset() == 34); - REQUIRE(replacements[4].getLength() == 1); - REQUIRE(replacements[4].getReplacementText() == "\n"); - } - - TEST_CASE("range") { - const std::string sampleDocument = "int main() { int *i = 0; return 0; }"; - WorkingFile* file = new WorkingFile("foo.cc", sampleDocument); - lsFormattingOptions formattingOptions; - formattingOptions.insertSpaces = true; - const auto replacements = - ClangFormatDocument(file, 30, sampleDocument.size(), formattingOptions); - - REQUIRE(replacements.size() == 2); - REQUIRE(replacements[0].getOffset() == 24); - REQUIRE(replacements[0].getLength() == 1); - REQUIRE(replacements[0].getReplacementText() == "\n "); - - REQUIRE(replacements[1].getOffset() == 34); - REQUIRE(replacements[1].getLength() == 1); - REQUIRE(replacements[1].getReplacementText() == "\n"); - } -} - -#endif diff --git a/src/clang_format.h b/src/clang_format.h deleted file mode 100644 index 862f3e067..000000000 --- a/src/clang_format.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#if USE_CLANG_CXX - -#include "lsp.h" -#include "working_files.h" - -#include - -#include - -std::vector ClangFormatDocument( - WorkingFile* working_file, - int start, - int end, - lsFormattingOptions options); - -#endif diff --git a/src/clang_index.cc b/src/clang_index.cc deleted file mode 100644 index 9c74fdfac..000000000 --- a/src/clang_index.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "clang_index.h" - -#include - -ClangIndex::ClangIndex() : ClangIndex(1, 0) {} - -ClangIndex::ClangIndex(int exclude_declarations_from_pch, - int display_diagnostics) { - // llvm::InitializeAllTargets (and possibly others) called by - // clang_createIndex transtively modifies/reads lib/Support/TargetRegistry.cpp - // FirstTarget. There will be a race condition if two threads call - // clang_createIndex concurrently. - static std::mutex mutex_; - std::lock_guard lock(mutex_); - - cx_index = - clang_createIndex(exclude_declarations_from_pch, display_diagnostics); -} - -ClangIndex::~ClangIndex() { - clang_disposeIndex(cx_index); -} diff --git a/src/clang_index.h b/src/clang_index.h deleted file mode 100644 index 1350d9000..000000000 --- a/src/clang_index.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -// Simple RAII wrapper about CXIndex. -// Note: building a ClangIndex instance acquires a global lock, since libclang -// API does not appear to be thread-safe here. -class ClangIndex { - public: - ClangIndex(); - ClangIndex(int exclude_declarations_from_pch, int display_diagnostics); - ~ClangIndex(); - CXIndex cx_index; -}; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index f4240df3c..4ff2c86d0 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -1555,7 +1555,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetVarDetail(var, std::string(decl->entityInfo->name), decl->cursor, decl->semanticContainer, !decl->isRedeclaration, db, param); - // FIXME https://github.com/jacobdufault/ccls/issues/239 var->def.kind = GetSymbolKind(decl->entityInfo->kind); if (var->def.kind == lsSymbolKind::Variable && decl->cursor.kind == CXCursor_ParmDecl) @@ -1776,8 +1775,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. - // TODO Think how to display multi-line declaration like `typedef struct { - // ... } foo;` https://github.com/jacobdufault/ccls/issues/29 if (extent.end.line - extent.start.line < kMaxLinesDisplayTypeAliasDeclarations) { FileContents& fc = param->file_contents[db->path]; @@ -1924,7 +1921,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { } } -// https://github.com/jacobdufault/ccls/issues/174 // Type-dependent member access expressions do not have accurate spelling // ranges. // @@ -2328,56 +2324,6 @@ void IndexInit() { clang_toggleCrashRecovery(1); } -void ClangSanityCheck() { - std::vector args = {"clang", "index_tests/vars/class_member.cc"}; - unsigned opts = 0; - CXIndex index = clang_createIndex(0, 1); - CXTranslationUnit tu; - clang_parseTranslationUnit2FullArgv(index, nullptr, args.data(), args.size(), - nullptr, 0, opts, &tu); - assert(tu); - - IndexerCallbacks callback = {0}; - callback.abortQuery = [](CXClientData client_data, void* reserved) { - return 0; - }; - callback.diagnostic = [](CXClientData client_data, - CXDiagnosticSet diagnostics, void* reserved) {}; - callback.enteredMainFile = [](CXClientData client_data, CXFile mainFile, - void* reserved) -> CXIdxClientFile { - return nullptr; - }; - callback.ppIncludedFile = - [](CXClientData client_data, - const CXIdxIncludedFileInfo* file) -> CXIdxClientFile { - return nullptr; - }; - callback.importedASTFile = - [](CXClientData client_data, - const CXIdxImportedASTFileInfo*) -> CXIdxClientASTFile { - return nullptr; - }; - callback.startedTranslationUnit = [](CXClientData client_data, - void* reserved) -> CXIdxClientContainer { - return nullptr; - }; - callback.indexDeclaration = [](CXClientData client_data, - const CXIdxDeclInfo* decl) {}; - callback.indexEntityReference = [](CXClientData client_data, - const CXIdxEntityRefInfo* ref) {}; - - const unsigned kIndexOpts = 0; - CXIndexAction index_action = clang_IndexAction_create(index); - int index_param = 0; - clang_toggleCrashRecovery(0); - clang_indexTranslationUnit(index_action, &index_param, &callback, - sizeof(IndexerCallbacks), kIndexOpts, tu); - clang_IndexAction_dispose(index_action); - - clang_disposeTranslationUnit(tu); - clang_disposeIndex(index); -} - std::string GetClangVersion() { return ToString(clang_getClangVersion()); } diff --git a/src/clang_translation_unit.h b/src/clang_translation_unit.h index efeedc6c6..59e2f17fa 100644 --- a/src/clang_translation_unit.h +++ b/src/clang_translation_unit.h @@ -1,7 +1,6 @@ #pragma once #include "clang_cursor.h" -#include "clang_index.h" #include @@ -28,4 +27,4 @@ struct ClangTranslationUnit { ~ClangTranslationUnit(); CXTranslationUnit cx_tu; -}; \ No newline at end of file +}; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index d89f78567..cfd5ce6ac 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -2,8 +2,6 @@ #include "platform.h" -#include - namespace { lsRange GetLsRangeForFixIt(const CXSourceRange& range) { @@ -106,31 +104,6 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, return ls_diagnostic; } -#if USE_CLANG_CXX -static lsPosition OffsetToRange(llvm::StringRef document, size_t offset) { - // TODO: Support Windows line endings, etc. - llvm::StringRef text_before = document.substr(0, offset); - int num_line = text_before.count('\n'); - int num_column = text_before.size() - text_before.rfind('\n') - 1; - return {num_line, num_column}; -} - -std::vector ConvertClangReplacementsIntoTextEdits( - llvm::StringRef document, - const std::vector& clang_replacements) { - std::vector text_edits_result; - for (const auto& replacement : clang_replacements) { - const auto startPosition = OffsetToRange(document, replacement.getOffset()); - const auto endPosition = OffsetToRange( - document, replacement.getOffset() + replacement.getLength()); - text_edits_result.push_back( - {{startPosition, endPosition}, replacement.getReplacementText()}); - } - return text_edits_result; -} - -#endif - std::string FileName(CXFile file) { CXString cx_name = clang_getFileName(file); std::string name = ToString(cx_name); @@ -172,60 +145,9 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { case CXType_Double: return "double"; case CXType_LongDouble: return "long double"; case CXType_Float128: return "__float128"; -#if CINDEX_VERSION_MINOR >= 43 case CXType_Half: return "_Float16"; -#endif case CXType_NullPtr: return "nullptr"; default: return ""; - // clang-format on - } -} - -#if USE_CLANG_CXX -TEST_SUITE("ClangUtils") { - TEST_CASE("replacements") { - const std::string sample_document = - "int \n" - "main() { int *i = 0; return 0; \n" - "}"; - const std::vector clang_replacements = { - {"foo.cc", 3, 2, " "}, {"foo.cc", 13, 1, "\n "}, - {"foo.cc", 17, 1, ""}, {"foo.cc", 19, 0, " "}, - {"foo.cc", 25, 1, "\n "}, {"foo.cc", 35, 2, "\n"}}; - - // Expected format: - // - // int main() { - // int *i = 0; - // return 0; - // } - - const auto text_edits = ConvertClangReplacementsIntoTextEdits( - sample_document, clang_replacements); - REQUIRE(text_edits.size() == 6); - REQUIRE(text_edits[0].range.start.line == 0); - REQUIRE(text_edits[0].range.start.character == 3); - REQUIRE(text_edits[0].newText == " "); - - REQUIRE(text_edits[1].range.start.line == 1); - REQUIRE(text_edits[1].range.start.character == 8); - REQUIRE(text_edits[1].newText == "\n "); - - REQUIRE(text_edits[2].range.start.line == 1); - REQUIRE(text_edits[2].range.start.character == 12); - REQUIRE(text_edits[2].newText == ""); - - REQUIRE(text_edits[3].range.start.line == 1); - REQUIRE(text_edits[3].range.start.character == 14); - REQUIRE(text_edits[3].newText == " "); - - REQUIRE(text_edits[4].range.start.line == 1); - REQUIRE(text_edits[4].range.start.character == 20); - REQUIRE(text_edits[4].newText == "\n "); - - REQUIRE(text_edits[5].range.start.line == 1); - REQUIRE(text_edits[5].range.start.character == 30); - REQUIRE(text_edits[5].newText == "\n"); + // clang-format on } } -#endif diff --git a/src/clang_utils.h b/src/clang_utils.h index 652368761..8db9fedd4 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -3,11 +3,8 @@ #include "lsp_diagnostic.h" #include -#if USE_CLANG_CXX -#include -#endif -#include +#include #include std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, @@ -21,10 +18,3 @@ std::string ToString(CXString cx_string); std::string ToString(CXCursorKind cursor_kind); const char* ClangBuiltinTypeName(CXTypeKind); - -// Converts Clang formatting replacement operations into LSP text edits. -#if USE_CLANG_CXX -std::vector ConvertClangReplacementsIntoTextEdits( - llvm::StringRef document, - const std::vector& clang_replacements); -#endif diff --git a/src/command_line.cc b/src/command_line.cc index 700e5b10d..c5be6682d 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -19,8 +19,6 @@ #include "query.h" #include "query_utils.h" #include "queue_manager.h" -#include "recorder.h" -#include "semantic_highlight_symbol_cache.h" #include "serializer.h" #include "serializers/json.h" #include "test.h" @@ -43,19 +41,10 @@ #include #include -// TODO: provide a feature like 'https://github.com/goldsborough/clang-expand', -// ie, a fully linear view of a function with inline function calls expanded. -// We can probably use vscode decorators to achieve it. - -// TODO: implement ThreadPool type which monitors CPU usage / number of work -// items per second completed and scales up/down number of running threads. - std::string g_init_options; namespace { -std::vector kEmptyArgs; - // This function returns true if e2e timing should be displayed for the given // MethodId. bool ShouldDisplayMethodTiming(MethodType type) { @@ -70,9 +59,6 @@ void PrintHelp() { << R"help(ccls is a low-latency C/C++/Objective-C language server. Mode: - --clang-sanity-check - Run a simple index test. Verifies basic clang functionality. - Needs to be executed from the ccls root checkout directory. --test-unit Run unit tests. --test-index Run index tests. opt_filter_path can be used to specify which @@ -85,37 +71,20 @@ Other command line options: --init Override client provided initialization options https://github.com/cquery-project/cquery/wiki/Initialization-options - --record - Writes stdin to .in and stdout to .out --log-file Logging file for diagnostics --log-file-append Like --log-file, but appending --log-all-to-stderr Write all log messages to STDERR. - --wait-for-input Wait for an '[Enter]' before exiting --help Print this help information. --ci Prevents tests from prompting the user for input. Used for continuous integration so it can fail faster instead of timing out. -See more on https://github.com/cquery-project/cquery/wiki +See more on https://github.com/MaskRay/ccls/wiki )help"; } } // namespace -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // QUERYDB MAIN //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -248,20 +217,6 @@ void RunQueryDbThread(const std::string& bin_name, } } -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // STDIN MAIN ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -333,8 +288,6 @@ void LaunchStdoutThread(std::unordered_map* request_times, time.ResetAndPrint("[e2e] Running " + std::string(message.method)); } - RecordOutput(message.content); - fwrite(message.content.c_str(), message.content.size(), 1, stdout); fflush(stdout); } @@ -360,23 +313,6 @@ void LanguageServerMain(const std::string& bin_name, RunQueryDbThread(bin_name, config, querydb_waiter, indexer_waiter); } -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -// MAIN //////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { TraceMe(); @@ -413,14 +349,6 @@ int main(int argc, char** argv) { loguru::Verbosity_MAX); } - if (HasOption(options, "--record")) - EnableRecording(options["--record"]); - - if (HasOption(options, "--clang-sanity-check")) { - language_server = false; - ClangSanityCheck(); - } - if (HasOption(options, "--test-unit")) { language_server = false; doctest::Context context; @@ -467,10 +395,5 @@ int main(int argc, char** argv) { &stdout_waiter); } - if (HasOption(options, "--wait-for-input")) { - std::cerr << std::endl << "[Enter] to exit" << std::endl; - getchar(); - } - return 0; } diff --git a/src/include_complete.cc b/src/include_complete.cc index 19f48c8ec..dcbaf8bcb 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -168,8 +168,6 @@ void IncludeComplete::AddFile(const std::string& absolute_path) { if (is_scanning) lock.lock(); InsertCompletionItem(absolute_path, std::move(item)); - if (lock) - lock.unlock(); } void IncludeComplete::InsertIncludesFromDirectory(std::string directory, diff --git a/src/indexer.h b/src/indexer.h index 025a27127..24db98c46 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -1,7 +1,6 @@ #pragma once #include "clang_cursor.h" -#include "clang_index.h" #include "clang_translation_unit.h" #include "clang_utils.h" #include "file_consumer.h" @@ -16,14 +15,13 @@ #include "symbol.h" #include "utils.h" -#include -#include - +#include #include +#include #include -#include -#include #include +#include +#include #include struct IndexFile; diff --git a/src/lsp.cc b/src/lsp.cc index bebe3cf8b..eb1825a68 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -1,6 +1,5 @@ #include "lsp.h" -#include "recorder.h" #include "serializers/json.h" #include @@ -67,8 +66,6 @@ std::optional ReadJsonRpcContentFrom( content += *c; } - RecordInput(content); - return content; } diff --git a/src/message_handler.cc b/src/message_handler.cc index bcb978379..dbf6d091e 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -4,7 +4,6 @@ #include "project.h" #include "query_utils.h" #include "queue_manager.h" -#include "semantic_highlight_symbol_cache.h" #include @@ -42,6 +41,77 @@ struct ScanLineEvent { }; } // namespace +SemanticHighlightSymbolCache::Entry::Entry( + SemanticHighlightSymbolCache* all_caches, + const std::string& path) + : all_caches_(all_caches), path(path) {} + +std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( + SymbolKind kind, + const std::string& detailed_name) { + TNameToId* map = GetMapForSymbol_(kind); + auto it = map->find(detailed_name); + if (it != map->end()) + return it->second; + + return std::nullopt; +} + +int SemanticHighlightSymbolCache::Entry::GetStableId( + SymbolKind kind, + const std::string& detailed_name) { + std::optional id = TryGetStableId(kind, detailed_name); + if (id) + return *id; + + // Create a new id. First try to find a key in another map. + all_caches_->cache_.IterateValues([&](const std::shared_ptr& entry) { + std::optional other_id = entry->TryGetStableId(kind, detailed_name); + if (other_id) { + id = other_id; + return false; + } + return true; + }); + + // Create a new id. + TNameToId* map = GetMapForSymbol_(kind); + if (!id) + id = all_caches_->next_stable_id_++; + return (*map)[detailed_name] = *id; +} + +SemanticHighlightSymbolCache::Entry::TNameToId* +SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) { + switch (kind) { + case SymbolKind::Type: + return &detailed_type_name_to_stable_id; + case SymbolKind::Func: + return &detailed_func_name_to_stable_id; + case SymbolKind::Var: + return &detailed_var_name_to_stable_id; + case SymbolKind::File: + case SymbolKind::Invalid: + break; + } + assert(false); + return nullptr; +} + +SemanticHighlightSymbolCache::SemanticHighlightSymbolCache() + : cache_(kCacheSize) {} + +void SemanticHighlightSymbolCache::Init(Config* config) { + match_ = std::make_unique(config->highlight.whitelist, + config->highlight.blacklist); +} + +std::shared_ptr +SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) { + return cache_.Get( + path, [&, this]() { return std::make_shared(this, path); }); +} + MessageHandler::MessageHandler() { // Dynamically allocate |message_handlers|, otherwise there will be static // initialization order races. diff --git a/src/message_handler.h b/src/message_handler.h index 49165a590..8fe0c6c41 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -1,12 +1,14 @@ #pragma once +#include "lru_cache.h" #include "lsp.h" +#include "match.h" #include "method.h" #include "query.h" #include - #include +#include #include struct ClangCompleteManager; @@ -20,11 +22,43 @@ struct IncludeComplete; struct MultiQueueWaiter; struct Project; struct QueryDatabase; -struct SemanticHighlightSymbolCache; struct TimestampManager; struct WorkingFile; struct WorkingFiles; +// Caches symbols for a single file for semantic highlighting to provide +// relatively stable ids. Only supports xxx files at a time. +struct SemanticHighlightSymbolCache { + struct Entry { + SemanticHighlightSymbolCache* all_caches_ = nullptr; + + // The path this cache belongs to. + std::string path; + // Detailed symbol name to stable id. + using TNameToId = std::unordered_map; + TNameToId detailed_type_name_to_stable_id; + TNameToId detailed_func_name_to_stable_id; + TNameToId detailed_var_name_to_stable_id; + + Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path); + + std::optional TryGetStableId(SymbolKind kind, + const std::string& detailed_name); + int GetStableId(SymbolKind kind, const std::string& detailed_name); + + TNameToId* GetMapForSymbol_(SymbolKind kind); + }; + + constexpr static int kCacheSize = 10; + LruCache cache_; + uint32_t next_stable_id_ = 0; + std::unique_ptr match_; + + SemanticHighlightSymbolCache(); + void Init(Config*); + std::shared_ptr GetCacheForFile(const std::string& path); +}; + struct Out_CclsPublishSemanticHighlighting : public lsOutMessage { struct Symbol { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 9d97b7c25..fd42cd342 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -6,7 +6,6 @@ #include "platform.h" #include "project.h" #include "queue_manager.h" -#include "semantic_highlight_symbol_cache.h" #include "serializers/json.h" #include "timer.h" #include "work_thread.h" @@ -361,26 +360,13 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, struct lsClientCapabilities { // Workspace specific client capabilities. - std::optional workspace; + lsWorkspaceClientCapabilites workspace; // Text document specific client capabilities. - std::optional textDocument; - - /** - * Experimental client capabilities. - */ - // experimental?: any; // TODO + lsTextDocumentClientCapabilities textDocument; }; MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -////////////////////////////// INITIALIZATION /////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - struct lsInitializeParams { // The process Id of the parent process that started // the server. Is null if the process has not been started by another process. @@ -524,8 +510,8 @@ struct Handler_Initialize : BaseMessageHandler { } // Client capabilities - if (request->params.capabilities.textDocument) { - const auto& cap = *request->params.capabilities.textDocument; + { + const auto& cap = request->params.capabilities.textDocument; if (cap.completion && cap.completion->completionItem) config->client.snippetSupport = cap.completion->completionItem->snippetSupport.value_or(false); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index fd85c311c..a186e1783 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -338,7 +338,10 @@ struct Handler_TextDocumentCompletion : MessageHandler { include_complete->completion_items_mutex, std::defer_lock); if (include_complete->is_scanning) lock.lock(); - out.result.items = include_complete->completion_items; + std::string quote = result.match[5]; + for (auto& item : include_complete->completion_items) + if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + out.result.items.push_back(item); } FilterAndSortCompletionResponse(&out, result.pattern, config->completion.filterAndSort); diff --git a/src/recorder.cc b/src/recorder.cc deleted file mode 100644 index f369d85f9..000000000 --- a/src/recorder.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include "recorder.h" - -#include - -#include -#include - -namespace { -std::ofstream* g_file_in = nullptr; -std::ofstream* g_file_out = nullptr; -} // namespace - -void EnableRecording(std::string path) { - if (path.empty()) - path = "ccls"; - - // We can only call |EnableRecording| once. - 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); - - // Make sure we can write to the files. - bool bad = false; - if (!g_file_in->good()) { - LOG_S(ERROR) << "record: cannot write to " << path << ".in"; - bad = true; - } - if (!g_file_out->good()) { - LOG_S(ERROR) << "record: cannot write to " << path << ".out"; - bad = true; - } - if (bad) { - delete g_file_in; - delete g_file_out; - g_file_in = nullptr; - g_file_out = nullptr; - } -} - -void RecordInput(std::string_view content) { - if (!g_file_in) - return; - (*g_file_in) << "Content-Length: " << content.size() << "\r\n\r\n" << content; - (*g_file_in).flush(); -} - -void RecordOutput(std::string_view content) { - if (!g_file_out) - return; - (*g_file_out) << content; - (*g_file_out).flush(); -} \ No newline at end of file diff --git a/src/recorder.h b/src/recorder.h deleted file mode 100644 index f3474ae65..000000000 --- a/src/recorder.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -#include - -void EnableRecording(std::string path); -void RecordInput(std::string_view content); -void RecordOutput(std::string_view content); \ No newline at end of file diff --git a/src/semantic_highlight_symbol_cache.cc b/src/semantic_highlight_symbol_cache.cc deleted file mode 100644 index 3fc045bc7..000000000 --- a/src/semantic_highlight_symbol_cache.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "semantic_highlight_symbol_cache.h" - -SemanticHighlightSymbolCache::Entry::Entry( - SemanticHighlightSymbolCache* all_caches, - const std::string& path) - : all_caches_(all_caches), path(path) {} - -std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( - SymbolKind kind, - const std::string& detailed_name) { - TNameToId* map = GetMapForSymbol_(kind); - auto it = map->find(detailed_name); - if (it != map->end()) - return it->second; - - return std::nullopt; -} - -int SemanticHighlightSymbolCache::Entry::GetStableId( - SymbolKind kind, - const std::string& detailed_name) { - std::optional id = TryGetStableId(kind, detailed_name); - if (id) - return *id; - - // Create a new id. First try to find a key in another map. - all_caches_->cache_.IterateValues([&](const std::shared_ptr& entry) { - std::optional other_id = entry->TryGetStableId(kind, detailed_name); - if (other_id) { - id = other_id; - return false; - } - return true; - }); - - // Create a new id. - TNameToId* map = GetMapForSymbol_(kind); - if (!id) - id = all_caches_->next_stable_id_++; - return (*map)[detailed_name] = *id; -} - -SemanticHighlightSymbolCache::Entry::TNameToId* -SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) { - switch (kind) { - case SymbolKind::Type: - return &detailed_type_name_to_stable_id; - case SymbolKind::Func: - return &detailed_func_name_to_stable_id; - case SymbolKind::Var: - return &detailed_var_name_to_stable_id; - case SymbolKind::File: - case SymbolKind::Invalid: - break; - } - assert(false); - return nullptr; -} - -SemanticHighlightSymbolCache::SemanticHighlightSymbolCache() - : cache_(kCacheSize) {} - -void SemanticHighlightSymbolCache::Init(Config* config) { - match_ = std::make_unique(config->highlight.whitelist, - config->highlight.blacklist); -} - -std::shared_ptr -SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) { - return cache_.Get( - path, [&, this]() { return std::make_shared(this, path); }); -} diff --git a/src/semantic_highlight_symbol_cache.h b/src/semantic_highlight_symbol_cache.h deleted file mode 100644 index 907be1e61..000000000 --- a/src/semantic_highlight_symbol_cache.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "lru_cache.h" -#include "match.h" -#include "query.h" - -#include - -#include -#include - -// Caches symbols for a single file for semantic highlighting to provide -// relatively stable ids. Only supports xxx files at a time. -struct SemanticHighlightSymbolCache { - struct Entry { - SemanticHighlightSymbolCache* all_caches_ = nullptr; - - // The path this cache belongs to. - std::string path; - // Detailed symbol name to stable id. - using TNameToId = std::unordered_map; - TNameToId detailed_type_name_to_stable_id; - TNameToId detailed_func_name_to_stable_id; - TNameToId detailed_var_name_to_stable_id; - - Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path); - - std::optional TryGetStableId(SymbolKind kind, - const std::string& detailed_name); - int GetStableId(SymbolKind kind, const std::string& detailed_name); - - TNameToId* GetMapForSymbol_(SymbolKind kind); - }; - - constexpr static int kCacheSize = 10; - LruCache cache_; - uint32_t next_stable_id_ = 0; - std::unique_ptr match_; - - SemanticHighlightSymbolCache(); - void Init(Config*); - std::shared_ptr GetCacheForFile(const std::string& path); -}; diff --git a/src/task.cc b/src/task.cc deleted file mode 100644 index 7a545d71e..000000000 --- a/src/task.cc +++ /dev/null @@ -1,152 +0,0 @@ -#if false -#include "task.h" - -#include "utils.h" - -#include - -TaskManager::TaskManager() { - pending_tasks_[TaskThread::Indexer] = std::make_unique(); - pending_tasks_[TaskThread::QueryDb] = std::make_unique(); -} - -void TaskManager::Post(TaskThread thread, const TTask& task) { - TaskQueue* queue = pending_tasks_[thread].get(); - std::lock_guard lock_guard(queue->tasks_mutex); - queue->tasks.push_back(task); -} - -void TaskManager::SetIdle(TaskThread thread, const TIdleTask& task) { - TaskQueue* queue = pending_tasks_[thread].get(); - std::lock_guard lock_guard(queue->tasks_mutex); - assert(!queue->idle_task && "There is already an idle task"); - queue->idle_task = task; -} - -bool TaskManager::RunTasks(TaskThread thread, std::optional> max_time) { - auto start = std::chrono::high_resolution_clock::now(); - TaskQueue* queue = pending_tasks_[thread].get(); - - bool ran_task = false; - - while (true) { - std::optional task; - - // Get a task. - { - std::lock_guard lock_guard(queue->tasks_mutex); - if (queue->tasks.empty()) - break; - task = std::move(queue->tasks[queue->tasks.size() - 1]); - queue->tasks.pop_back(); - } - - // Execute task. - assert(task); - (*task)(); - ran_task = true; - - // Stop if we've run past our max time. Don't run idle_task. - auto elapsed = std::chrono::high_resolution_clock::now() - start; - if (max_time && elapsed > *max_time) - return ran_task; - } - - if (queue->idle_task) { - // Even if the idle task returns false we still ran something before. - ran_task = (*queue->idle_task)() || ran_task; - } - - return ran_task; -} - -TEST_SUITE("Task"); - -TEST_CASE("tasks are run as soon as they are posted") { - TaskManager tm; - - // Post three tasks. - int next = 1; - int a = 0, b = 0, c = 0; - tm.Post(TaskThread::QueryDb, [&] { - a = next++; - }); - tm.Post(TaskThread::QueryDb, [&] { - b = next++; - }); - tm.Post(TaskThread::QueryDb, [&] { - c = next++; - }); - - // Execute all tasks. - tm.RunTasks(TaskThread::QueryDb, std::nullopt); - - // Tasks are executed in reverse order. - REQUIRE(a == 3); - REQUIRE(b == 2); - REQUIRE(c == 1); -} - -TEST_CASE("post from inside task manager") { - TaskManager tm; - - // Post three tasks. - int next = 1; - int a = 0, b = 0, c = 0; - tm.Post(TaskThread::QueryDb, [&] () { - a = next++; - - tm.Post(TaskThread::QueryDb, [&] { - b = next++; - - tm.Post(TaskThread::QueryDb, [&] { - c = next++; - }); - }); - }); - - // Execute all tasks. - tm.RunTasks(TaskThread::QueryDb, std::nullopt); - - // Tasks are executed in normal order because the next task is not posted - // until the previous one is executed. - REQUIRE(a == 1); - REQUIRE(b == 2); - REQUIRE(c == 3); -} - -TEST_CASE("idle task is run after nested tasks") { - TaskManager tm; - - int count = 0; - tm.SetIdle(TaskThread::QueryDb, [&]() { - ++count; - return true; - }); - - // No tasks posted - idle runs once. - REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt)); - REQUIRE(count == 1); - count = 0; - - // Idle runs after other posted tasks. - bool did_run = false; - tm.Post(TaskThread::QueryDb, [&]() { - did_run = true; - }); - REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt)); - REQUIRE(did_run); - REQUIRE(count == 1); -} - -TEST_CASE("RunTasks returns false when idle task returns false and no other tasks were run") { - TaskManager tm; - - REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt) == false); - - tm.SetIdle(TaskThread::QueryDb, []() { return false; }); - REQUIRE(tm.RunTasks(TaskThread::QueryDb, std::nullopt) == false); -} - -TEST_SUITE_END(); -#endif \ No newline at end of file diff --git a/src/task.h b/src/task.h deleted file mode 100644 index 5cdd4e0a0..000000000 --- a/src/task.h +++ /dev/null @@ -1,41 +0,0 @@ -#if false -#pragma once - -#include - -#include -#include -#include -#include -#include - -enum class TaskThread { - Indexer, - QueryDb, -}; - -struct TaskManager { - using TTask = std::function; - using TIdleTask = std::function; - - TaskManager(); - - // Run |task| at some point in the future. This will run the task as soon as possible. - void Post(TaskThread thread, const TTask& task); - - // Run |task| whenever there is nothing else to run. - void SetIdle(TaskThread thread, const TIdleTask& idle_task); - - // Run pending tasks for |thread|. Stop running tasks after |max_time| has - // elapsed. Returns true if tasks were run. - bool RunTasks(TaskThread thread, std::optional> max_time); - - struct TaskQueue { - std::optional idle_task; - std::vector tasks; - std::mutex tasks_mutex; - }; - - std::unordered_map> pending_tasks_; -}; -#endif \ No newline at end of file diff --git a/wscript b/wscript deleted file mode 100644 index d090ab41e..000000000 --- a/wscript +++ /dev/null @@ -1,424 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -try: - from urllib2 import urlopen # Python 2 -except ImportError: - from urllib.request import urlopen # Python 3 - -import os.path -import string -import subprocess -import sys -import re -import ctypes -import shutil - -VERSION = '0.0.1' -APPNAME = 'cquery' - -top = '.' -out = 'build' - -CLANG_TARBALL_NAME = None -CLANG_TARBALL_EXT = '.tar.xz' -if sys.platform == 'darwin': - CLANG_TARBALL_NAME = 'clang+llvm-$version-x86_64-apple-darwin' -elif sys.platform.startswith('freebsd'): - CLANG_TARBALL_NAME = 'clang+llvm-$version-amd64-unknown-freebsd-10' -# It is either 'linux2' or 'linux3' before Python 3.3 -elif sys.platform.startswith('linux'): - # These executable depend on libtinfo.so.5 - CLANG_TARBALL_NAME = 'clang+llvm-$version-x86_64-linux-gnu-ubuntu-14.04' -elif sys.platform == 'win32': - CLANG_TARBALL_NAME = 'LLVM-$version-win64' - CLANG_TARBALL_EXT = '.exe' - -from waflib.Tools.compiler_cxx import cxx_compiler -cxx_compiler['linux'] = ['clang++', 'g++'] - -# Creating symbolic link on Windows requires a special priviledge SeCreateSymboliclinkPrivilege, -# which an non-elevated process lacks. Starting with Windows 10 build 14972, this got relaxed -# when Developer Mode is enabled. Triggering this new behaviour requires a new flag. -SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 - -# Python 2 has no symlink function and Python 3's symlink function does not allow creation of -# symlinks without admin rights (even when Developer Mode is enabled) so we define our own -# symlink function when on Windows. -if sys.platform == 'win32': - kdll = ctypes.windll.kernel32 - def symlink(source, link_name, target_is_directory=False): - # SYMBOLIC_LINK_FLAG_DIRECTORY: 0x1 - flags = int(target_is_directory) | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE - - # Use unicode version (W suffix) of Windows symbolic link function and convert strings to - # unicode if Python 2 is used (strings are unicode by default in Python 3). - if sys.version_info < (3, 0): - ret = kdll.CreateSymbolicLinkW(unicode(link_name), unicode(source), flags) - else: - ret = kdll.CreateSymbolicLinkW(link_name, source, flags) - - if ret == 0: - err = ctypes.WinError() - raise err - os.symlink = symlink -elif sys.version_info.major < 3: - os_symlink_bak = os.symlink - os.symlink = lambda src, dst, target_is_directory=False: os_symlink_bak(src, dst) - -# There is a null pointer dereference issue in tools/libclang/CXIndexDataConsumer.cpp handleReference. -def patch_byte_in_libclang(filename, offset, old, new): - with open(filename, 'rb+') as f: - f.seek(offset) - t = f.read(1) - if t == old: - f.seek(offset) - f.write(new) - print('Applied byte patch hack at 0x{:x}'.format(offset)) - print('This is a makeshift for indexing default arguments of template template parameters, which otherwise would crash libclang') - print('See https://github.com/jacobdufault/cquery/issues/219 for details') - else: - assert t == new - -def options(opt): - opt.load('compiler_cxx') - grp = opt.add_option_group('Configuration options related to use of clang from the system (not recommended)') - grp.add_option('--enable-assert', action='store_true') - grp.add_option('--use-clang-cxx', dest='use_clang_cxx', default=False, action='store_true', - help='use clang C++ API') - grp.add_option('--bundled-clang', dest='bundled_clang', default='6.0.0', - help='bundled clang version, downloaded from https://releases.llvm.org/ , e.g. 5.0.1 6.0.0') - grp.add_option('--llvm-config', dest='llvm_config', - help='path to llvm-config to use system libclang, e.g. llvm-config llvm-config-6.0') - grp.add_option('--clang-prefix', dest='clang_prefix', - help='enable fallback configuration method by specifying a clang installation prefix (e.g. /opt/llvm)') - grp.add_option('--variant', default='release', - help='variant name for saving configuration and build results. Variants other than "debug" turn on -O3') - -def download_and_extract(destdir, url, ext): - dest = destdir + ext - - # Extract the tarball. - if not os.path.isdir(os.path.join(destdir, 'include')): - # Download and save the compressed tarball as |compressed_file_name|. - if not os.path.isfile(dest): - print('Downloading tarball') - print(' destination: {0}'.format(dest)) - print(' source: {0}'.format(url)) - # TODO: verify checksum - response = urlopen(url, timeout=60) - with open(dest, 'wb') as f: - f.write(response.read()) - else: - print('Found tarball at {0}'.format(dest)) - - print('Extracting {0}'.format(dest)) - # TODO: make portable. - if ext == '.exe': - subprocess.call(['7z', 'x', '-o{0}'.format(destdir), '-xr!$PLUGINSDIR', dest]) - else: - subprocess.call(['tar', '-x', '-C', out, '-f', dest]) - # TODO Remove after migrating to a clang release newer than 5.0.1 - # For 5.0.1 Mac OS X, the directory and the tarball have different name - if destdir == 'build/clang+llvm-5.0.1-x86_64-apple-darwin': - os.rename(destdir.replace('5.0.1', '5.0.1-final'), destdir) - # TODO Byte patch hack for other prebuilt binaries - elif destdir == 'build/clang+llvm-4.0.0-x86_64-linux-gnu-ubuntu-14.04': - patch_byte_in_libclang(os.path.join(destdir, 'lib/libclang.so.4.0'), - 0x4172b5, b'\x48', b'\x4d') - elif destdir == 'build/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04': - patch_byte_in_libclang(os.path.join(destdir, 'lib/libclang.so.5.0'), - 0x47aece, b'\x48', b'\x4d') - else: - print('Found extracted at {0}'.format(destdir)) - -def copy_or_symlink(src, dst): - print('copy_or_symlink src={0}, dst={1}'.format(src, dst)) - try: - os.makedirs(os.path.dirname(dst)) - except OSError: - pass - - try: - os.symlink(src, dst) - except (OSError, NotImplementedError): - shutil.copy(src, dst) - -def configure(ctx): - ctx.resetenv(ctx.options.variant) - - ctx.load('compiler_cxx') - if ctx.env.CXX_NAME == 'msvc': - # /Zi: -g, /WX: -Werror, /W3: roughly -Wall, there is no -std=c++11 equivalent in MSVC. - # /wd4722: ignores warning C4722 (destructor never returns) in loguru - # /wd4267: ignores warning C4267 (conversion from 'size_t' to 'type'), roughly -Wno-sign-compare - # /MD: use multithread c library from DLL - cxxflags = ['/nologo', '/FS', '/EHsc', '/Zi', '/W3', '/wd4996', '/wd4722', '/wd4267', '/wd4800', '/MD'] - ldflags = [] - if 'release' in ctx.options.variant: - cxxflags.append('/O2') # There is no O3 - else: - cxxflags += ['/Zi', '/FS'] - ldflags += ['/DEBUG'] - else: - # So that dladdr() called in loguru.hpp gives symbol names in main executable - ldflags = ['-rdynamic'] - if ctx.env.CXXFLAGS: - cxxflags = ctx.env.CXXFLAGS - else: - cxxflags = ['-g', '-Wall', '-Wno-sign-compare'] - if ctx.env.CXX_NAME == 'gcc': - cxxflags.append('-Wno-return-type') - # Otherwise (void)write(...) => -Werror=unused-result - cxxflags.append('-Wno-unused-result') - - if all(not x.startswith('-std=') for x in ctx.env.CXXFLAGS): - cxxflags.append('-std=c++14') - - if ctx.options.use_clang_cxx: - # include/clang/Format/Format.h error: multi-line comment - cxxflags.append('-Wno-comment') - # Without -fno-rtti, some Clang C++ functions may report `undefined references to typeinfo` - cxxflags.append('-fno-rtti') - - if 'asan' in ctx.options.variant: - cxxflags.append('-fsanitize=address,undefined') - ldflags.append('-fsanitize=address,undefined') - if 'release' in ctx.options.variant: - cxxflags.append('-O' if 'asan' in ctx.options.variant else '-O3') - - if ctx.options.enable_assert is None: - if 'debug' in ctx.options.variant: - ctx.options.enable_assert = True - if not ctx.options.enable_assert: - ctx.define('NDEBUG', 1) - - if ctx.env.CXX_NAME == 'clang' and 'debug' in ctx.options.variant: - cxxflags.append('-fno-limit-debug-info') - - ctx.env.CXXFLAGS = cxxflags - if not ctx.env.LDFLAGS: - ctx.env.LDFLAGS = ldflags - - ctx.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=True) - - ctx.load('clang_compilation_database', tooldir='.') - - ctx.env['use_clang_cxx'] = ctx.options.use_clang_cxx - ctx.env['llvm_config'] = ctx.options.llvm_config - ctx.env['bundled_clang'] = ctx.options.bundled_clang - def libname(lib): - # Newer MinGW and MSVC both wants full file name - if sys.platform == 'win32': - return 'lib' + lib - return lib - - # Do not use bundled clang+llvm - if ctx.options.llvm_config is not None or ctx.options.clang_prefix is not None: - if ctx.options.llvm_config is not None: - # Ask llvm-config for cflags and ldflags - ctx.find_program(ctx.options.llvm_config, msg='checking for llvm-config', var='LLVM_CONFIG', mandatory=False) - - ctx.env.rpath = [str(subprocess.check_output( - [ctx.options.llvm_config, '--libdir'], - stderr=subprocess.STDOUT).decode()).strip()] - - if ctx.options.clang_prefix: - ctx.start_msg('Checking for clang prefix') - prefix = ctx.root.find_node(ctx.options.clang_prefix) - if not prefix: - raise ctx.errors.ConfigurationError('clang prefix not found: "%s"'%ctx.options.clang_prefix) - ctx.end_msg(prefix) - - includes = [ n.abspath() for n in [ prefix.find_node('include') ] if n ] - libpath = [ n.abspath() for n in [ prefix.find_node(l) for l in ('lib', 'lib64')] if n ] - ctx.check_cxx(msg='Checking for library clang', lib=libname('clang'), uselib_store='clang', includes=includes, libpath=libpath) - else: - ctx.check_cfg(msg='Checking for clang flags', - path=ctx.env.LLVM_CONFIG, - package='', - uselib_store='clang', - args='--cppflags --ldflags') - # llvm-config does not provide the actual library we want so we check for it - # using the provided info so far. - ctx.check_cxx(lib=libname('clang'), uselib_store='clang', use='clang') - - - # Use CXX set by --check-cxx-compiler if it is "clang". - # See https://github.com/jacobdufault/cquery/issues/237 - clang = ctx.env.get_flat('CXX') - if 'clang' not in clang: - # Otherwise, infer the clang executable path with llvm-config --bindir - output = str(subprocess.check_output( - [ctx.options.llvm_config, '--bindir'], - stderr=subprocess.STDOUT).decode()).strip() - clang = os.path.join(output, 'clang') - - # Use the detected clang executable to infer resource directory - # Use `clang -### -xc /dev/null` instead of `clang -print-resource-dir` because the option is unavailable in 4.0.0 - devnull = '/dev/null' if sys.platform != 'win32' else 'NUL' - output = str(subprocess.check_output( - [clang, '-###', '-xc', devnull], - stderr=subprocess.STDOUT).decode()) - match = re.search(r'"-resource-dir" "([^"]*)"', output, re.M) - if match: - ctx.env.default_resource_directory = match.group(1) - else: - bld.fatal("Failed to found system clang resource directory.") - - else: - global CLANG_TARBALL_NAME, CLANG_TARBALL_EXT - - if CLANG_TARBALL_NAME is None: - sys.stderr.write('ERROR: releases.llvm.org does not provide prebuilt binary for your platform {0}\n'.format(sys.platform)) - sys.exit(1) - - # TODO Remove after 5.0.1 is stable - if ctx.options.bundled_clang == '5.0.0' and sys.platform.startswith('linux'): - CLANG_TARBALL_NAME = 'clang+llvm-$version-linux-x86_64-ubuntu14.04' - - CLANG_TARBALL_NAME = string.Template(CLANG_TARBALL_NAME).substitute(version=ctx.options.bundled_clang) - # Directory clang has been extracted to. - CLANG_DIRECTORY = '{0}/{1}'.format(out, CLANG_TARBALL_NAME) - # URL of the tarball to download. - CLANG_TARBALL_URL = 'http://releases.llvm.org/{0}/{1}{2}'.format(ctx.options.bundled_clang, CLANG_TARBALL_NAME, CLANG_TARBALL_EXT) - - print('Checking for clang') - download_and_extract(CLANG_DIRECTORY, CLANG_TARBALL_URL, CLANG_TARBALL_EXT) - - bundled_clang_dir = os.path.join(out, ctx.options.variant, 'lib', CLANG_TARBALL_NAME) - try: - os.makedirs(os.path.dirname(bundled_clang_dir)) - except OSError: - pass - clang_dir = os.path.normpath('../../' + CLANG_TARBALL_NAME) - try: - if not os.path.exists(bundled_clang_dir): - os.symlink(clang_dir, bundled_clang_dir, target_is_directory=True) - except (OSError, NotImplementedError): - # Copying the whole directory instead. - print ('shutil.copytree({0}, {1})'.format(os.path.join(out, CLANG_TARBALL_NAME), bundled_clang_dir)) - try: - shutil.copytree(os.path.join(out, CLANG_TARBALL_NAME), bundled_clang_dir) - except Exception as e: - print('Failed to copy tree, ', e) - - clang_node = ctx.path.find_dir(bundled_clang_dir) - ctx.check_cxx(uselib_store='clang', - includes=clang_node.find_dir('include').abspath(), - libpath=clang_node.find_dir('lib').abspath(), - lib=libname('clang')) - - clang_tarball_name = os.path.basename(os.path.dirname(ctx.env['LIBPATH_clang'][0])) - ctx.env.clang_tarball_name = clang_tarball_name - ctx.env.default_resource_directory = '../lib/{}/lib/clang/{}'.format(clang_tarball_name, ctx.env.bundled_clang) - - if sys.platform.startswith('freebsd') or sys.platform.startswith('linux'): - ctx.env.rpath = ['$ORIGIN/../lib/' + clang_tarball_name + '/lib'] - elif sys.platform == 'darwin': - ctx.env.rpath = ['@loader_path/../lib/' + clang_tarball_name + '/lib'] - elif sys.platform == 'win32': - # Poor Windows users' RPATH - copy libclang.lib and libclang.dll to the build directory. - ctx.env.rpath = [] # Unsupported - clang_dir = os.path.dirname(ctx.env['LIBPATH_clang'][0]) - dest_dir = os.path.join(ctx.path.get_bld().abspath(), ctx.options.variant, 'bin') - # copy_or_symlink(os.path.join(clang_dir, 'lib', 'libclang.lib'), os.path.join(dest_dir, 'libclang.lib')) - copy_or_symlink(os.path.join(clang_dir, 'bin', 'libclang.dll'), os.path.join(dest_dir, 'libclang.dll')) - else: - ctx.env.rpath = ctx.env['LIBPATH_clang'] - - ctx.msg('Clang includes', ctx.env.INCLUDES_clang) - ctx.msg('Clang library dir', ctx.env.LIBPATH_clang) - -def build(bld): - cc_files = bld.path.ant_glob(['src/*.cc', 'src/messages/*.cc', 'third_party/*.cc']) - if bld.env['use_clang_cxx']: - cc_files += bld.path.ant_glob(['src/clang_cxx/*.cc']) - - lib = [] - if sys.platform.startswith('linux'): - # For __atomic_* when lock free instructions are unavailable - # (either through hardware or OS support) - lib.append('pthread') - # loguru calls dladdr - lib.append('dl') - elif sys.platform.startswith('freebsd'): - # loguru::stacktrace_as_stdstring calls backtrace_symbols - lib.append('execinfo') - # sparsepp/spp_memory.h uses libkvm - lib.append('kvm') - - lib.append('pthread') - lib.append('thr') - elif sys.platform == 'darwin': - lib.append('pthread') - elif sys.platform == 'msys': - lib.append('psapi') # GetProcessMemoryInfo - - if bld.env['use_clang_cxx']: - # -fno-rtti is required for object files using clang/llvm C++ API - - # The order is derived by topological sorting LINK_LIBS in clang/lib/*/CMakeLists.txt - lib.append('clangFormat') - lib.append('clangToolingCore') - lib.append('clangRewrite') - lib.append('clangAST') - lib.append('clangLex') - lib.append('clangBasic') - - # The order is derived from llvm-config --libs core - lib.append('LLVMCore') - lib.append('LLVMBinaryFormat') - lib.append('LLVMSupport') - lib.append('LLVMDemangle') - - lib.append('ncurses') - - # https://waf.io/apidocs/tools/c_aliases.html#waflib.Tools.c_aliases.program - bld.program( - source=cc_files, - use=['clang'], - includes=[ - 'src/', - 'third_party/', - 'third_party/doctest/', - 'third_party/loguru/', - 'third_party/msgpack-c/include', - 'third_party/rapidjson/include/', - 'third_party/sparsepp/'] + - (['libclang'] if bld.env['use_clang_cxx'] else []), - defines=[ - 'LOGURU_WITH_STREAMS=1', - 'LOGURU_FILENAME_WIDTH=18', - 'LOGURU_THREADNAME_WIDTH=13', - 'DEFAULT_RESOURCE_DIRECTORY="' + bld.env.get_flat('default_resource_directory') + '"'] + - (['USE_CLANG_CXX=1', 'LOGURU_RTTI=0'] - if bld.env['use_clang_cxx'] - else []), - lib=lib, - rpath=bld.env.rpath, - target='bin/cquery') - - if bld.cmd == 'install' and 'clang_tarball_name' in bld.env: - clang_tarball_name = bld.env.clang_tarball_name - if sys.platform != 'win32': - bld.install_files('${PREFIX}/lib/' + clang_tarball_name + '/lib', bld.path.get_bld().ant_glob('lib/' + clang_tarball_name + '/lib/libclang.(dylib|so.[4-9])', quiet=True)) - # TODO This may be cached and cannot be re-triggered. Use proper shell escape. - bld(rule='rsync -rtR {}/./lib/{}/lib/clang/*/include {}/'.format(bld.path.get_bld(), clang_tarball_name, bld.env['PREFIX'])) - -def init(ctx): - from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext - for y in (BuildContext, CleanContext, InstallContext, UninstallContext): - class tmp(y): - variant = ctx.options.variant - - # This is needed because waf initializes the ConfigurationContext with - # an arbitrary setenv('') which would rewrite the previous configuration - # cache for the default variant if the configure step finishes. - # Ideally ConfigurationContext should just let us override this at class - # level like the other Context subclasses do with variant - from waflib.Configure import ConfigurationContext - class cctx(ConfigurationContext): - def resetenv(self, name): - self.all_envs = {} - self.setenv(name) From f8a816d110b86c6954501d48148fd52c0e749a86 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 01:01:32 -0700 Subject: [PATCH 053/378] . --- CMakeLists.txt | 2 - src/clang_complete.cc | 11 ++ src/clang_complete.h | 15 ++ src/code_complete_cache.cc | 12 -- src/code_complete_cache.h | 22 --- src/command_line.cc | 27 +++- src/fuzzy_match.h | 3 +- src/lex_utils.cc | 151 ------------------- src/lex_utils.h | 4 - src/messages/text_document_completion.cc | 1 - src/messages/text_document_signature_help.cc | 1 - src/options.cc | 30 ---- src/options.h | 9 -- src/platform.h | 3 - src/platform_posix.cc | 4 - src/platform_win.cc | 19 --- src/project.cc | 6 - src/query.cc | 15 -- src/working_files.cc | 103 ------------- 19 files changed, 52 insertions(+), 386 deletions(-) delete mode 100644 src/code_complete_cache.cc delete mode 100644 src/code_complete_cache.h delete mode 100644 src/options.cc delete mode 100644 src/options.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 63db0c0f3..e3364e3b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,6 @@ target_sources(ccls PRIVATE src/clang_indexer.cc src/clang_translation_unit.cc src/clang_utils.cc - src/code_complete_cache.cc src/command_line.cc src/diagnostics_engine.cc src/file_consumer.cc @@ -189,7 +188,6 @@ target_sources(ccls PRIVATE src/lsp.cc src/match.cc src/message_handler.cc - src/options.cc src/platform_posix.cc src/platform_win.cc src/platform.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 1ac65e46d..d76dbf817 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -816,3 +816,14 @@ void ClangCompleteManager::FlushAllSessions() { preloaded_sessions_.Clear(); completion_sessions_.Clear(); } + +void CodeCompleteCache::WithLock(std::function action) { + std::lock_guard lock(mutex_); + action(); +} + +bool CodeCompleteCache::IsCacheValid(lsTextDocumentPositionParams position) { + std::lock_guard lock(mutex_); + return cached_path_ == position.textDocument.uri.GetPath() && + cached_completion_position_ == position.position; +} diff --git a/src/clang_complete.h b/src/clang_complete.h index 142ab86a9..8080c0e5b 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -145,3 +145,18 @@ struct ClangCompleteManager { // reparsed. ThreadedQueue parse_requests_; }; + +// Cached completion information, so we can give fast completion results when +// the user erases a character. vscode will resend the completion request if +// that happens. +struct CodeCompleteCache { + // NOTE: Make sure to access these variables under |WithLock|. + std::optional cached_path_; + std::optional cached_completion_position_; + std::vector cached_results_; + + std::mutex mutex_; + + void WithLock(std::function action); + bool IsCacheValid(lsTextDocumentPositionParams position); +}; diff --git a/src/code_complete_cache.cc b/src/code_complete_cache.cc deleted file mode 100644 index df9244619..000000000 --- a/src/code_complete_cache.cc +++ /dev/null @@ -1,12 +0,0 @@ -#include "code_complete_cache.h" - -void CodeCompleteCache::WithLock(std::function action) { - std::lock_guard lock(mutex_); - action(); -} - -bool CodeCompleteCache::IsCacheValid(lsTextDocumentPositionParams position) { - std::lock_guard lock(mutex_); - return cached_path_ == position.textDocument.uri.GetPath() && - cached_completion_position_ == position.position; -} \ No newline at end of file diff --git a/src/code_complete_cache.h b/src/code_complete_cache.h deleted file mode 100644 index 39696f1bc..000000000 --- a/src/code_complete_cache.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "lsp_completion.h" - -#include - -#include - -// Cached completion information, so we can give fast completion results when -// the user erases a character. vscode will resend the completion request if -// that happens. -struct CodeCompleteCache { - // NOTE: Make sure to access these variables under |WithLock|. - std::optional cached_path_; - std::optional cached_completion_position_; - std::vector cached_results_; - - std::mutex mutex_; - - void WithLock(std::function action); - bool IsCacheValid(lsTextDocumentPositionParams position); -}; diff --git a/src/command_line.cc b/src/command_line.cc index c5be6682d..eda149ee0 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -1,7 +1,6 @@ // TODO: cleanup includes #include "cache_manager.h" #include "clang_complete.h" -#include "code_complete_cache.h" #include "diagnostics_engine.h" #include "file_consumer.h" #include "import_manager.h" @@ -13,7 +12,6 @@ #include "lsp_diagnostic.h" #include "match.h" #include "message_handler.h" -#include "options.h" #include "platform.h" #include "project.h" #include "query.h" @@ -45,6 +43,31 @@ std::string g_init_options; namespace { +std::unordered_map ParseOptions(int argc, + char** argv) { + std::unordered_map output; + + for (int i = 1; i < argc; ++i) { + std::string arg = argv[i]; + if (arg[0] == '-') { + auto equal = arg.find('='); + if (equal != std::string::npos) { + output[arg.substr(0, equal)] = arg.substr(equal + 1); + } else if (i + 1 < argc && argv[i + 1][0] != '-') + output[arg] = argv[++i]; + else + output[arg] = ""; + } + } + + return output; +} + +bool HasOption(const std::unordered_map& options, + const std::string& option) { + return options.find(option) != options.end(); +} + // This function returns true if e2e timing should be displayed for the given // MethodId. bool ShouldDisplayMethodTiming(MethodType type) { diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 52a89986f..958f35cda 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -1,9 +1,8 @@ #pragma once -#include - #include #include +#include class FuzzyMatcher { public: diff --git a/src/lex_utils.cc b/src/lex_utils.cc index ff0406885..5d66adf07 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -24,28 +24,6 @@ int GetOffsetForPosition(lsPosition position, std::string_view content) { return int(i); } -lsPosition CharPos(std::string_view search, - char character, - int character_offset) { - lsPosition result; - size_t index = 0; - while (index < search.size()) { - char c = search[index]; - if (c == character) - break; - if (c == '\n') { - result.line += 1; - result.character = 0; - } else { - result.character += 1; - } - ++index; - } - assert(index < search.size()); - result.character += character_offset; - return result; -} - // TODO: eliminate |line_number| param. std::optional ExtractQuotedRange(int line_number, const std::string& line) { // Find starting and ending quote. @@ -237,132 +215,3 @@ TEST_SUITE("Substring") { std::make_pair(true, 7)); } } - -TEST_SUITE("LexFunctionDeclaration") { - TEST_CASE("simple") { - std::string buffer_content = " void Foo(); "; - lsPosition declaration = CharPos(buffer_content, 'F'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, - &newlines_after_name); - REQUIRE(insert_text == "void Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - - LexFunctionDeclaration(buffer_content, declaration, std::string("Type"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "void Type::Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - } - - TEST_CASE("ctor") { - std::string buffer_content = " Foo(); "; - lsPosition declaration = CharPos(buffer_content, 'F'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "Foo::Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - } - - TEST_CASE("dtor") { - std::string buffer_content = " ~Foo(); "; - lsPosition declaration = CharPos(buffer_content, '~'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "Foo::~Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - } - - TEST_CASE("complex return type") { - std::string buffer_content = " std::vector Foo(); "; - lsPosition declaration = CharPos(buffer_content, 'F'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, - &newlines_after_name); - REQUIRE(insert_text == "std::vector Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - - LexFunctionDeclaration(buffer_content, declaration, std::string("Type"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "std::vector Type::Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - } - - TEST_CASE("extra complex return type") { - std::string buffer_content = " std::function < int() > \n Foo(); "; - lsPosition declaration = CharPos(buffer_content, 'F'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, - &newlines_after_name); - REQUIRE(insert_text == "std::function < int() > \n Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - - LexFunctionDeclaration(buffer_content, declaration, std::string("Type"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "std::function < int() > \n Type::Foo() {\n}"); - REQUIRE(newlines_after_name == 0); - } - - TEST_CASE("parameters") { - std::string buffer_content = "void Foo(int a,\n\n int b); "; - lsPosition declaration = CharPos(buffer_content, 'F'); - std::string insert_text; - int newlines_after_name = 0; - - LexFunctionDeclaration(buffer_content, declaration, std::nullopt, &insert_text, - &newlines_after_name); - REQUIRE(insert_text == "void Foo(int a,\n\n int b) {\n}"); - REQUIRE(newlines_after_name == 2); - - LexFunctionDeclaration(buffer_content, declaration, std::string("Type"), - &insert_text, &newlines_after_name); - REQUIRE(insert_text == "void Type::Foo(int a,\n\n int b) {\n}"); - REQUIRE(newlines_after_name == 2); - } -} - -TEST_SUITE("LexWordAroundPos") { - TEST_CASE("edges") { - std::string content = "Foobar"; - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'F'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'o'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'b'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'a'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'r'), content) == "Foobar"); - } - - TEST_CASE("simple") { - std::string content = " Foobar "; - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'F'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'o'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'b'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'a'), content) == "Foobar"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'r'), content) == "Foobar"); - } - - TEST_CASE("underscores, numbers and ::") { - std::string content = " file:ns::_my_t5ype7 "; - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'f'), content) == "file"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 's'), content) == "ns"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, 'y'), content) == - "ns::_my_t5ype7"); - } - - TEST_CASE("dot, dash, colon are skipped") { - std::string content = "1. 2- 3:"; - REQUIRE(LexIdentifierAroundPos(CharPos(content, '1'), content) == "1"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, '2'), content) == "2"); - REQUIRE(LexIdentifierAroundPos(CharPos(content, '3'), content) == "3"); - } -} diff --git a/src/lex_utils.h b/src/lex_utils.h index 6fbc68645..36328ad35 100644 --- a/src/lex_utils.h +++ b/src/lex_utils.h @@ -9,10 +9,6 @@ // Utility method to map |position| to an offset inside of |content|. int GetOffsetForPosition(lsPosition position, std::string_view content); -// Utility method to find a position for the given character. -lsPosition CharPos(std::string_view search, - char character, - int character_offset = 0); // TODO: eliminate |line_number| param. std::optional ExtractQuotedRange(int line_number, const std::string& line); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index a186e1783..14e82af44 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -1,5 +1,4 @@ #include "clang_complete.h" -#include "code_complete_cache.h" #include "fuzzy_match.h" #include "include_complete.h" #include "message_handler.h" diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index 9ceb7410a..c06050eae 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -1,5 +1,4 @@ #include "clang_complete.h" -#include "code_complete_cache.h" #include "message_handler.h" #include "queue_manager.h" #include "timer.h" diff --git a/src/options.cc b/src/options.cc deleted file mode 100644 index b0962f5fe..000000000 --- a/src/options.cc +++ /dev/null @@ -1,30 +0,0 @@ -#include "options.h" - -#include - -#include - -std::unordered_map ParseOptions(int argc, - char** argv) { - std::unordered_map output; - - for (int i = 1; i < argc; ++i) { - std::string arg = argv[i]; - if (arg[0] == '-') { - auto equal = arg.find('='); - if (equal != std::string::npos) { - output[arg.substr(0, equal)] = arg.substr(equal + 1); - } else if (i + 1 < argc && argv[i + 1][0] != '-') - output[arg] = argv[++i]; - else - output[arg] = ""; - } - } - - return output; -} - -bool HasOption(const std::unordered_map& options, - const std::string& option) { - return options.find(option) != options.end(); -} diff --git a/src/options.h b/src/options.h deleted file mode 100644 index eec6f17ef..000000000 --- a/src/options.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -std::unordered_map ParseOptions(int argc, - char** argv); - -bool HasOption(const std::unordered_map& options, - const std::string& option); \ No newline at end of file diff --git a/src/platform.h b/src/platform.h index 106b89020..770012143 100644 --- a/src/platform.h +++ b/src/platform.h @@ -41,9 +41,6 @@ void CopyFileTo(const std::string& destination, const std::string& source); bool IsSymLink(const std::string& path); -// Returns any clang arguments that are specific to the current platform. -std::vector GetPlatformClangArguments(); - // Free any unused memory and return it to the system. void FreeUnusedMemory(); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index e3e34b29a..ad8613204 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -259,10 +259,6 @@ bool IsSymLink(const std::string& path) { return lstat(path.c_str(), &buf) == 0 && S_ISLNK(buf.st_mode); } -std::vector GetPlatformClangArguments() { - return {}; -} - void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); diff --git a/src/platform_win.cc b/src/platform_win.cc index 2b7f81264..2ddb96a8a 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -129,25 +129,6 @@ bool IsSymLink(const std::string& path) { return false; } -std::vector GetPlatformClangArguments() { - // - // Found by executing - // - // $ clang++ -E -x c++ - -v - // - // https://clang.llvm.org/docs/MSVCCompatibility.html - // - // - // These options are only needed if clang is targeting the msvc triple, - // which depends on how clang was build for windows. clang downloaded from - // releases.llvm.org defaults to msvc, so ccls does as well. - // - // https://github.com/cquery-project/cquery/issues/509 has more context. - // - return {"-fms-extensions", "-fms-compatibility", - "-fdelayed-template-parsing"}; -} - void FreeUnusedMemory() {} bool RunObjectiveCIndexTests() { diff --git a/src/project.cc b/src/project.cc index 387fe3a03..ff8c75ff5 100644 --- a/src/project.cc +++ b/src/project.cc @@ -188,12 +188,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (!AnyStartsWith(args, "-working-directory")) result.args.emplace_back("-working-directory=" + entry.directory); - if (!gTestOutputMode) { - std::vector platform = GetPlatformClangArguments(); - for (auto arg : platform) - result.args.push_back(arg); - } - bool next_flag_is_path = false; bool add_next_flag_to_quote_dirs = false; bool add_next_flag_to_angle_dirs = false; diff --git a/src/query.cc b/src/query.cc index b1336b9eb..9fcb4c417 100644 --- a/src/query.cc +++ b/src/query.cc @@ -19,17 +19,6 @@ namespace { -template -void VerifyUnique(const std::vector& values0) { -// FIXME: Run on a big code-base for a while and verify no assertions are -// triggered. -#if false - auto values = values0; - std::sort(values.begin(), values.end()); - assert(std::unique(values.begin(), values.end()) == values.end()); -#endif -} - template void RemoveRange(std::vector* dest, const std::vector& to_remove) { std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); @@ -767,9 +756,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, // There means that there is some memory growth that will never be reclaimed, // but it should be pretty minimal and is solved by simply restarting the // indexer and loading from cache, which is a fast operation. - // - // TODO: Add "ccls: Reload Index" command which unloads all querydb state - // and fully reloads from cache. This will address the memory leak above. switch (usr_kind) { case SymbolKind::Type: { @@ -827,7 +813,6 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { auto& def = storage_name[merge_update.id.id]; \ AddRange(&def.def_var_name, merge_update.to_add); \ RemoveRange(&def.def_var_name, merge_update.to_remove); \ - VerifyUnique(def.def_var_name); \ } for (const std::string& filename : update->files_removed) diff --git a/src/working_files.cc b/src/working_files.cc index 1e173eec1..52fcd5168 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -546,106 +546,3 @@ WorkingFiles::Snapshot WorkingFiles::AsSnapshot( } return result; } - -lsPosition CharPos(const WorkingFile& file, - char character, - int character_offset = 0) { - return CharPos(file.buffer_content, character, character_offset); -} - -TEST_SUITE("WorkingFile") { - TEST_CASE("simple call") { - WorkingFile f("foo.cc", "abcd(1, 2"); - int active_param = 0; - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '1'), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) == - "abcd"); - REQUIRE(active_param == 1); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) == - "abcd"); - REQUIRE(active_param == 1); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '2'), &active_param) == - "abcd"); - REQUIRE(active_param == 1); - } - - TEST_CASE("nested call") { - WorkingFile f("foo.cc", "abcd(efg(), 2"); - int active_param = 0; - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'e'), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'f'), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g'), &active_param) == - "abcd"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 1), &active_param) == - "efg"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 2), &active_param) == - "efg"); - REQUIRE(active_param == 0); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) == - "abcd"); - REQUIRE(active_param == 1); - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) == - "abcd"); - REQUIRE(active_param == 1); - } - - TEST_CASE("auto-insert )") { - WorkingFile f("foo.cc", "abc()"); - int active_param = 0; - REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ')'), &active_param) == - "abc"); - REQUIRE(active_param == 0); - } - - TEST_CASE("existing completion") { - WorkingFile f("foo.cc", "zzz.asdf"); - bool is_global_completion; - std::string existing_completion; - - f.FindStableCompletionSource(CharPos(f, '.'), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "zzz"); - f.FindStableCompletionSource(CharPos(f, 'a', 1), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "a"); - f.FindStableCompletionSource(CharPos(f, 's', 1), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "as"); - f.FindStableCompletionSource(CharPos(f, 'd', 1), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "asd"); - f.FindStableCompletionSource(CharPos(f, 'f', 1), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "asdf"); - } - - TEST_CASE("existing completion underscore") { - WorkingFile f("foo.cc", "ABC_DEF"); - bool is_global_completion; - std::string existing_completion; - - f.FindStableCompletionSource(CharPos(f, 'C'), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "AB"); - f.FindStableCompletionSource(CharPos(f, '_'), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "ABC"); - f.FindStableCompletionSource(CharPos(f, 'D'), &is_global_completion, - &existing_completion); - REQUIRE(existing_completion == "ABC_"); - } -} From 6c8fee41417e772e8e3c978ac48af02aaf6be304 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 09:25:58 -0700 Subject: [PATCH 054/378] . --- index_tests/constructors/constructor.cc | 4 +- index_tests/constructors/destructor.cc | 2 +- .../constructors/implicit_constructor.cc | 4 +- index_tests/constructors/make_functions.cc | 12 +- .../func_associated_function_params.cc | 4 +- .../class_inherit_templated_parent.cc | 4 +- index_tests/lambdas/lambda.cc | 10 +- index_tests/macros/foo.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 4 +- index_tests/namespaces/namespace_reference.cc | 2 +- .../outline/static_function_in_type.cc | 2 +- index_tests/preprocessor/include_guard.cc | 2 +- .../implicit_variable_instantiation.cc | 2 +- index_tests/templates/specialization.cc | 10 +- .../template_var_usage_folded_into_one.cc | 2 +- index_tests/usage/func_usage_addr_func.cc | 2 +- index_tests/usage/func_usage_addr_method.cc | 2 +- index_tests/usage/func_usage_call_method.cc | 2 +- .../usage/func_usage_forward_decl_method.cc | 2 +- .../usage/type_usage_as_template_parameter.cc | 2 +- ...ype_usage_as_template_parameter_complex.cc | 2 +- index_tests/usage/type_usage_declare_local.cc | 4 +- index_tests/usage/type_usage_declare_param.cc | 4 +- .../type_usage_declare_param_prototype.cc | 2 +- .../usage/type_usage_declare_qualifiers.cc | 12 +- index_tests/usage/type_usage_various.cc | 2 +- index_tests/usage/usage_inside_of_call.cc | 2 +- index_tests/usage/var_usage_call_function.cc | 2 +- index_tests/usage/var_usage_class_member.cc | 2 +- index_tests/usage/var_usage_local.cc | 2 +- index_tests/usage/var_usage_shadowed_local.cc | 4 +- .../usage/var_usage_shadowed_parameter.cc | 2 +- index_tests/vars/deduce_auto_type.cc | 4 +- index_tests/vars/function_local.cc | 2 +- index_tests/vars/function_param.cc | 4 +- index_tests/vars/function_shadow_local.cc | 4 +- index_tests/vars/function_shadow_param.cc | 2 +- .../vars/type_instance_on_using_type.cc | 2 +- src/clang_indexer.cc | 25 +- src/indexer.h | 4 +- src/message_handler.cc | 4 - src/message_handler.h | 2 - src/messages/text_document_did_open.cc | 2 - src/messages/text_document_did_save.cc | 2 - src/project.cc | 734 +----------------- src/test.cc | 3 +- src/type_printer.cc | 10 +- src/utils.cc | 34 - 48 files changed, 96 insertions(+), 858 deletions(-) diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index 82c7469ff..e779b786d 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -64,7 +64,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 18410644574635149442, + "usr": 10983126130596230582, "detailed_name": "Foo f", "short_name": "f", "declarations": [], @@ -76,7 +76,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 11468802633764653592, + "usr": 17165811951126099095, "detailed_name": "Foo *f2", "short_name": "f2", "hover": "Foo *f2 = new Foo()", diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index acfa71a37..12482769c 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -85,7 +85,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 9954632887635271906, + "usr": 1893354193220338759, "detailed_name": "Foo f", "short_name": "f", "declarations": [], diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index fd696780a..30589861b 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -63,7 +63,7 @@ void Make() { }], "vars": [{ "id": 0, - "usr": 17348451315735351657, + "usr": 449111627548814328, "detailed_name": "Type foo0", "short_name": "foo0", "declarations": [], @@ -75,7 +75,7 @@ void Make() { "storage": 1 }, { "id": 1, - "usr": 3757978174345638825, + "usr": 17097499197730163115, "detailed_name": "Type foo1", "short_name": "foo1", "declarations": [], diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index f044001af..ab2d2cd50 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -137,7 +137,7 @@ OUTPUT: make_functions.cc "skipped_by_preprocessor": [], "types": [{ "id": 0, - "usr": 7902098450755788854, + "usr": 9281343527065946499, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -153,7 +153,7 @@ OUTPUT: make_functions.cc "uses": ["4:1-4:2|-1|1|4"] }, { "id": 1, - "usr": 12533159752419999454, + "usr": 10771590811355716928, "detailed_name": "Args", "short_name": "Args", "kind": 26, @@ -169,7 +169,7 @@ OUTPUT: make_functions.cc "uses": ["4:15-4:19|-1|1|4"] }, { "id": 2, - "usr": 18441628706991062891, + "usr": 11897454629873246477, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -185,7 +185,7 @@ OUTPUT: make_functions.cc "uses": ["9:1-9:2|-1|1|4"] }, { "id": 3, - "usr": 9441341235704820385, + "usr": 3337128087216004141, "detailed_name": "Args", "short_name": "Args", "kind": 26, @@ -328,7 +328,7 @@ OUTPUT: make_functions.cc }], "vars": [{ "id": 0, - "usr": 15288691366352169805, + "usr": 8463700030555379526, "detailed_name": "Args &&... args", "short_name": "args", "declarations": [], @@ -339,7 +339,7 @@ OUTPUT: make_functions.cc "storage": 1 }, { "id": 1, - "usr": 12338908251430965107, + "usr": 3908732770590594660, "detailed_name": "Args... args", "short_name": "args", "declarations": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index f917921e5..e3aba26f4 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -51,7 +51,7 @@ int foo(int a, int b) { return 0; } }], "vars": [{ "id": 0, - "usr": 10480417713467708012, + "usr": 14555488990109936920, "detailed_name": "int a", "short_name": "a", "declarations": [], @@ -63,7 +63,7 @@ int foo(int a, int b) { return 0; } "storage": 1 }, { "id": 1, - "usr": 18099600680625658464, + "usr": 10963664335057337329, "detailed_name": "int b", "short_name": "b", "declarations": [], diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 1b1bda9d1..bc12cca6f 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -97,7 +97,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "uses": ["13:56-13:64|-1|1|4"] }, { "id": 5, - "usr": 780719166805015998, + "usr": 7916588271848318236, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -131,7 +131,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [{ "id": 0, - "usr": 3880651725784125791, + "usr": 12990052348105569112, "detailed_name": "unsigned int T", "short_name": "T", "declarations": [], diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 2bc4d60f4..e670cc625 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -32,7 +32,7 @@ void foo() { "uses": [] }, { "id": 1, - "usr": 1287417953265234030, + "usr": 14635009347499519042, "detailed_name": "", "short_name": "", "kind": 0, @@ -62,7 +62,7 @@ void foo() { "callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"] }, { "id": 1, - "usr": 1328781044864682611, + "usr": 17926497908620168464, "detailed_name": "", "short_name": "", "kind": 0, @@ -76,7 +76,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 17270098654620601683, + "usr": 12666114896600231317, "detailed_name": "int x", "short_name": "x", "declarations": [], @@ -88,7 +88,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 16806544259835773270, + "usr": 2981279427664991319, "detailed_name": "lambda dosomething", "short_name": "dosomething", "declarations": [], @@ -100,7 +100,7 @@ void foo() { "storage": 1 }, { "id": 2, - "usr": 2034725908368218782, + "usr": 12879188959314906706, "detailed_name": "int y", "short_name": "y", "declarations": [], diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 6dbe14661..888034438 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -87,7 +87,7 @@ int x = A; "storage": 0 }, { "id": 2, - "usr": 14946041066794678724, + "usr": 2056319845419860263, "detailed_name": "DISALLOW", "short_name": "DISALLOW", "hover": "#define DISALLOW(type) type(type&&) = delete;", diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 9a92b8081..8fa504385 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -142,7 +142,7 @@ void func() { "storage": 1 }, { "id": 1, - "usr": 107714981785063096, + "usr": 6030927277961448585, "detailed_name": "int a", "short_name": "a", "hover": "int a = foo::bar::baz::qux", @@ -155,7 +155,7 @@ void func() { "storage": 1 }, { "id": 2, - "usr": 1200087780658383286, + "usr": 7657277353101371136, "detailed_name": "int b", "short_name": "b", "hover": "int b = fbz::qux", diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 235ebaeeb..a8383d89c 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -105,7 +105,7 @@ void Runner() { "storage": 1 }, { "id": 1, - "usr": 7976909968919750794, + "usr": 3649375698083002347, "detailed_name": "int a", "short_name": "a", "declarations": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 2bcf1f767..682ca165d 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -177,7 +177,7 @@ OUTPUT: static_function_in_type.cc }], "vars": [{ "id": 0, - "usr": 9285345059965948351, + "usr": 13569879755236306838, "detailed_name": "ns::Manager *m", "short_name": "m", "declarations": [], diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 4ae27e172..764e434ca 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -12,7 +12,7 @@ "funcs": [], "vars": [{ "id": 0, - "usr": 13076155634261037336, + "usr": 11674328179498211370, "detailed_name": "FOO", "short_name": "FOO", "hover": "#define FOO", diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 3301266f2..b4ef6130c 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -83,7 +83,7 @@ namespace ns { "uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"] }, { "id": 4, - "usr": 14511917000226829276, + "usr": 2205716167465743256, "detailed_name": "", "short_name": "", "kind": 0, diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 5a545a486..2b75f557e 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -81,7 +81,7 @@ void foo(float Value); "uses": ["7:1-7:9|-1|1|4"] }, { "id": 2, - "usr": 10862637711685426953, + "usr": 9673599782548740467, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -97,7 +97,7 @@ void foo(float Value); "uses": ["5:16-5:17|-1|1|4"] }, { "id": 3, - "usr": 756188769017350739, + "usr": 7143192229126273961, "detailed_name": "Args", "short_name": "Args", "kind": 26, @@ -159,7 +159,7 @@ void foo(float Value); "uses": ["31:1-31:7|-1|1|4"] }, { "id": 7, - "usr": 3421332160420436276, + "usr": 8880262253425334092, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -239,7 +239,7 @@ void foo(float Value); "uses": [] }, { "id": 12, - "usr": 2461355892344618654, + "usr": 14111105212951082474, "detailed_name": "T", "short_name": "T", "kind": 26, @@ -409,7 +409,7 @@ void foo(float Value); "storage": 0 }, { "id": 7, - "usr": 10307767688451422448, + "usr": 17826688417349629938, "detailed_name": "T Value", "short_name": "Value", "declarations": [], diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 8c8fed789..5d7464e93 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -69,7 +69,7 @@ UnexposedDecl var "uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"] }, { "id": 2, - "usr": 8864163146308556810, + "usr": 11919899838872947844, "detailed_name": "", "short_name": "", "kind": 0, diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 6e5d8f316..2f69d39c7 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -61,7 +61,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 13681544683892648258, + "usr": 16088407831770615719, "detailed_name": "void (*)() x", "short_name": "x", "declarations": [], diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index faeec595e..b2d9fb460 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -64,7 +64,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 8436636043513449412, + "usr": 4636142131003982569, "detailed_name": "void (Foo::*)() x", "short_name": "x", "declarations": [], diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 088a737ab..01ef98f95 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -64,7 +64,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 3014406561587537195, + "usr": 14045150712868309451, "detailed_name": "Foo *f", "short_name": "f", "hover": "Foo *f = nullptr", diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index b34f9875c..c9c988c12 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -63,7 +63,7 @@ void usage() { }], "vars": [{ "id": 0, - "usr": 12410753116854389823, + "usr": 16229832321010999607, "detailed_name": "Foo *f", "short_name": "f", "hover": "Foo *f = nullptr", diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 5752413ba..57b128e76 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -90,7 +90,7 @@ unique_ptr* return_type() { "storage": 3 }, { "id": 2, - "usr": 2462000803278878465, + "usr": 3364438781074774169, "detailed_name": "unique_ptr *local", "short_name": "local", "declarations": [], diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 50e7690d1..d200b0254 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -219,7 +219,7 @@ unique_ptr* Foo::foo() { return nullptr; } "storage": 2 }, { "id": 1, - "usr": 11547294959889394856, + "usr": 500112618220246, "detailed_name": "unique_ptr, S2> *local", "short_name": "local", "declarations": [], diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 0503fbc6e..733155945 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -60,7 +60,7 @@ void Foo() { }], "vars": [{ "id": 0, - "usr": 11033478034711123650, + "usr": 16374832544037266261, "detailed_name": "ForwardType *a", "short_name": "a", "declarations": [], @@ -72,7 +72,7 @@ void Foo() { "storage": 1 }, { "id": 1, - "usr": 8949902309768550158, + "usr": 2580122838476012357, "detailed_name": "ImplementedType b", "short_name": "b", "declarations": [], diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 24fd0927f..b6155f873 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -57,7 +57,7 @@ void foo(ForwardType* f, ImplementedType a) {} }], "vars": [{ "id": 0, - "usr": 2584795197111552890, + "usr": 13058491096576226774, "detailed_name": "ForwardType *f", "short_name": "f", "declarations": [], @@ -69,7 +69,7 @@ void foo(ForwardType* f, ImplementedType a) {} "storage": 1 }, { "id": 1, - "usr": 5136230284979460117, + "usr": 11055777568039014776, "detailed_name": "ImplementedType a", "short_name": "a", "declarations": [], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 711054df3..2cbc4522c 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -49,7 +49,7 @@ void foo(Foo* f, Foo*) {} }], "vars": [{ "id": 0, - "usr": 2161866804398917919, + "usr": 13823260660189154978, "detailed_name": "Foo *f", "short_name": "f", "declarations": [], diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 5c31c5e17..0219d89f5 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -46,7 +46,7 @@ void foo(Type& a0, const Type& a1) { }], "vars": [{ "id": 0, - "usr": 16414210592877294238, + "usr": 7997456978847868736, "detailed_name": "Type &a0", "short_name": "a0", "declarations": [], @@ -58,7 +58,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 1, - "usr": 11558141642862804306, + "usr": 17228576662112939520, "detailed_name": "const Type &a1", "short_name": "a1", "declarations": [], @@ -70,7 +70,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 2, - "usr": 1536316608590232194, + "usr": 15429032129697337561, "detailed_name": "Type a2", "short_name": "a2", "declarations": [], @@ -82,7 +82,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 3, - "usr": 316760354845869406, + "usr": 6081981442495435784, "detailed_name": "Type *a3", "short_name": "a3", "declarations": [], @@ -94,7 +94,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 4, - "usr": 12321730890779907974, + "usr": 5004072032239834773, "detailed_name": "const Type *a4", "short_name": "a4", "declarations": [], @@ -106,7 +106,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 5, - "usr": 4771437488905761633, + "usr": 14939253431683105646, "detailed_name": "const Type *const a5", "short_name": "a5", "hover": "const Type *const a5 = nullptr", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index ba72ffad3..e38d14d64 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -53,7 +53,7 @@ extern Foo foo; }], "vars": [{ "id": 0, - "usr": 14873619387499024780, + "usr": 16380484338511689669, "detailed_name": "Foo f", "short_name": "f", "declarations": [], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 2bec1cb68..556bacc4c 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -125,7 +125,7 @@ void foo() { "storage": 0 }, { "id": 2, - "usr": 13284113377394221067, + "usr": 8039186520399841081, "detailed_name": "int a", "short_name": "a", "hover": "int a = 5", diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index e5cbf4236..de98e5fca 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -46,7 +46,7 @@ void caller() { }], "vars": [{ "id": 0, - "usr": 3510529098767253033, + "usr": 9121974011454213596, "detailed_name": "void (*)() x", "short_name": "x", "declarations": [], diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 37a097610..21bbdfd93 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -127,7 +127,7 @@ void foo() { "storage": 0 }, { "id": 2, - "usr": 16303259148898744165, + "usr": 14669930844300034456, "detailed_name": "Foo f", "short_name": "f", "declarations": [], diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index f9c0124ea..09fd489c6 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -40,7 +40,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 8534460107894911680, + "usr": 14014650769929566957, "detailed_name": "int x", "short_name": "x", "declarations": [], diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index db8572066..f1767412d 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -45,7 +45,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 17941402366659878910, + "usr": 13311055950748663970, "detailed_name": "int a", "short_name": "a", "declarations": [], @@ -57,7 +57,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 11094102496276744608, + "usr": 14036425367303419504, "detailed_name": "int a", "short_name": "a", "declarations": [], diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index e5c784acf..591f7b1da 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -57,7 +57,7 @@ void foo(int a) { "storage": 1 }, { "id": 1, - "usr": 8011559936501990179, + "usr": 6997229590862003559, "detailed_name": "int a", "short_name": "a", "declarations": [], diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 42f6d581b..8bd1166f4 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -44,7 +44,7 @@ void f() { }], "vars": [{ "id": 0, - "usr": 9275666070987716270, + "usr": 10601729374837386290, "detailed_name": "Foo *x", "short_name": "x", "declarations": [], @@ -56,7 +56,7 @@ void f() { "storage": 1 }, { "id": 1, - "usr": 16202433437488621027, + "usr": 18422884837902130475, "detailed_name": "Foo *y", "short_name": "y", "declarations": [], diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 6f0adec7b..4c3951ca1 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -42,7 +42,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 10782632605670042066, + "usr": 13198746475679542317, "detailed_name": "Foo *a", "short_name": "a", "declarations": [], diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index cc61eff72..0108c73be 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -40,7 +40,7 @@ void foo(Foo* p0, Foo* p1) {} }], "vars": [{ "id": 0, - "usr": 4580260577538694711, + "usr": 8730439006497971620, "detailed_name": "Foo *p0", "short_name": "p0", "declarations": [], @@ -52,7 +52,7 @@ void foo(Foo* p0, Foo* p1) {} "storage": 1 }, { "id": 1, - "usr": 12071725611268840435, + "usr": 2525014371090380500, "detailed_name": "Foo *p1", "short_name": "p1", "declarations": [], diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 0c4fa4a14..1d16f481e 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -45,7 +45,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 3440226937504376525, + "usr": 1894874819807168345, "detailed_name": "int a", "short_name": "a", "declarations": [], @@ -57,7 +57,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 14700715011944976607, + "usr": 4508045017817092115, "detailed_name": "int a", "short_name": "a", "declarations": [], diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index 5f8a99882..ee7b225ef 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -51,7 +51,7 @@ void foo(int p) { "storage": 1 }, { "id": 1, - "usr": 2147918703972955240, + "usr": 11404600766177939811, "detailed_name": "int p", "short_name": "p", "hover": "int p = 0", diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 7d01422b8..1101a9834 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -64,7 +64,7 @@ void Foo() { }], "vars": [{ "id": 0, - "usr": 7730100248624586522, + "usr": 6975456769752895964, "detailed_name": "F a", "short_name": "a", "declarations": [], diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 4ff2c86d0..2032056bf 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -525,11 +525,8 @@ void SetTypeName(IndexType* type, // 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 = + std::tie(type->def.detailed_name, type->def.short_name_offset) = param->ns.QualifiedName(container ? container : &parent, name); - auto idx = type->def.detailed_name.rfind(name); - assert(idx != std::string::npos); - type->def.short_name_offset = idx; type->def.short_name_size = strlen(name); } @@ -599,7 +596,7 @@ void SetVarDetail(IndexVar* var, ? param->PrettyPrintCursor(cursor.cx_cursor) : #endif - param->ns.QualifiedName(semanticContainer, short_name); + param->ns.QualifiedName(semanticContainer, short_name).first; if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) { CXType enum_type = clang_getCanonicalType( @@ -782,12 +779,6 @@ void Uniquify(std::vector& uses) { uses.resize(n); } -// FIXME Reference: set id in call sites and remove this -// void AddUse(std::vector& values, Range value) { -// values.push_back( -// Use(value, Id(), SymbolKind::File, Role::Reference, {})); -//} - void AddUse(IndexFile* db, std::vector& uses, Range range, @@ -1422,10 +1413,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, } // namespace -std::string NamespaceHelper::QualifiedName(const CXIdxContainerInfo* container, - std::string_view unqualified_name) { +std::pair NamespaceHelper::QualifiedName( + const CXIdxContainerInfo* container, + std::string_view unqualified_name) { if (!container) - return std::string(unqualified_name); + return {std::string(unqualified_name), 0}; // Anonymous namespaces are not processed by indexDeclaration. We trace // nested namespaces bottom-up through clang_getCursorSemanticParent until // one that we know its qualified name. Then do another trace top-down and @@ -1455,8 +1447,9 @@ std::string NamespaceHelper::QualifiedName(const CXIdxContainerInfo* container, qualifier += "::"; container_cursor_to_qualified_name[namespaces[i]] = qualifier; } - // C++17 string::append - return qualifier + std::string(unqualified_name); + int pos = qualifier.size(); + qualifier.append(unqualified_name); + return {qualifier, pos}; } void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { diff --git a/src/indexer.h b/src/indexer.h index 24db98c46..e52ddb3d5 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -509,8 +509,8 @@ struct NamespaceHelper { std::unordered_map container_cursor_to_qualified_name; - std::string QualifiedName(const CXIdxContainerInfo* container, - std::string_view unqualified_name); + std::pair QualifiedName(const CXIdxContainerInfo* container, + std::string_view unqualified_name); }; // |import_file| is the cc file which is what gets passed to clang. diff --git a/src/message_handler.cc b/src/message_handler.cc index dbf6d091e..0d3a2082a 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -349,7 +349,3 @@ void EmitSemanticHighlighting(QueryDatabase* db, out.params.symbols.push_back(entry.second); QueueManager::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } - -bool ShouldIgnoreFileForIndexing(const std::string& path) { - return StartsWith(path, "git:"); -} diff --git a/src/message_handler.h b/src/message_handler.h index 8fe0c6c41..ea6c67e34 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -153,5 +153,3 @@ void EmitSemanticHighlighting(QueryDatabase* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFile* working_file, QueryFile* file); - -bool ShouldIgnoreFileForIndexing(const std::string& path); diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 9b3ee9fb6..7c10ebf8e 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -40,8 +40,6 @@ struct Handler_TextDocumentDidOpen const auto& params = request->params; Timer time; std::string path = params.textDocument.uri.GetPath(); - if (ShouldIgnoreFileForIndexing(path)) - return; std::shared_ptr cache_manager = ICacheManager::Make(config); WorkingFile* working_file = working_files->OnOpen(params.textDocument); diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 751d4238d..57a3310be 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -32,8 +32,6 @@ struct Handler_TextDocumentDidSave void Run(In_TextDocumentDidSave* request) override { std::string path = request->params.textDocument.uri.GetPath(); - if (ShouldIgnoreFileForIndexing(path)) - return; // Send out an index request, and copy the current buffer state so we // can update the cached index contents when the index is done. diff --git a/src/project.cc b/src/project.cc index ff8c75ff5..198d60f92 100644 --- a/src/project.cc +++ b/src/project.cc @@ -69,7 +69,6 @@ struct ProjectConfig { std::unordered_set angle_dirs; std::vector extra_flags; std::string project_dir; - std::string resource_dir; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -273,7 +272,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Add -resource-dir so clang can correctly resolve system includes like // if (!AnyStartsWith(result.args, "-resource-dir")) - result.args.push_back("-resource-dir=" + config->resource_dir); + result.args.push_back("-resource-dir=" + init_opts->resourceDirectory); // There could be a clang version mismatch between what the project uses and // what ccls uses. Make sure we do not emit warnings for mismatched options. @@ -476,39 +475,16 @@ std::vector LoadCompilationEntriesFromDirectory( // Computes a score based on how well |a| and |b| match. This is used for // argument guessing. -int ComputeGuessScore(const std::string& a, const std::string& b) { - const int kMatchPrefixWeight = 100; - const int kMismatchDirectoryWeight = 100; - const int kMatchPostfixWeight = 1; - - int score = 0; - size_t i = 0; - - // Increase score based on matching prefix. - for (i = 0; i < a.size() && i < b.size(); ++i) { - if (a[i] != b[i]) - break; - score += kMatchPrefixWeight; - } - - // Reduce score based on mismatched directory distance. - for (size_t j = i; j < a.size(); ++j) { - if (a[j] == '/') - score -= kMismatchDirectoryWeight; - } - for (size_t j = i; j < b.size(); ++j) { - if (b[j] == '/') - score -= kMismatchDirectoryWeight; - } - - // Increase score based on common ending. Don't increase as much as matching - // prefix or directory distance. - for (size_t offset = 1; offset <= a.size() && offset <= b.size(); ++offset) { - if (a[a.size() - offset] != b[b.size() - offset]) - break; - score += kMatchPostfixWeight; - } - +int ComputeGuessScore(std::string_view a, std::string_view b) { + // Increase score based on common prefix and suffix. Prefixes are prioritized. + if (a.size() < b.size()) + std::swap(a, b); + size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); + size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); + int score = 10 * i + j; + if (i + j < b.size()) + score -= 100 * (std::count(a.begin() + i, a.end() - j, '/') + + std::count(b.begin() + i, b.end() - j, '/')); return score; } @@ -519,7 +495,6 @@ void Project::Load(Config* config, const std::string& root_directory) { ProjectConfig project; project.extra_flags = config->extraClangArguments; project.project_dir = root_directory; - project.resource_dir = config->resourceDirectory; entries = LoadCompilationEntriesFromDirectory( config, &project, config->compilationDatabaseDirectory); @@ -647,7 +622,7 @@ TEST_SUITE("Project") { Config config; ProjectConfig project; project.project_dir = "/w/c/s/"; - project.resource_dir = "/w/resource_dir/"; + config.resourceDirectory = "/w/resource_dir/"; CompileCommandsEntry entry; entry.directory = directory; @@ -691,19 +666,6 @@ TEST_SUITE("Project") { {"clang.exe", "-working-directory=/dir/", "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); - - CheckFlags( - /* raw */ {"goma", "clang"}, - /* expected */ - {"clang", "-working-directory=/dir/", "-resource-dir=/w/resource_dir/", - "-Wno-unknown-warning-option", "-fparse-all-comments"}); - - CheckFlags( - /* raw */ {"goma", "clang", "--foo"}, - /* expected */ - {"clang", "-working-directory=/dir/", "--foo", - "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", - "-fparse-all-comments"}); } TEST_CASE("Windows path normalization") { @@ -756,678 +718,6 @@ TEST_SUITE("Project") { "-fparse-all-comments"}); } - // Checks flag parsing for a random chromium file in comparison to what - // YouCompleteMe fetches. - TEST_CASE("ycm") { - CheckFlags( - "/w/c/s/out/Release", "../../ash/login/lock_screen_sanity_unittest.cc", - - /* raw */ - { - "/work/goma/gomacc", - "../../third_party/llvm-build/Release+Asserts/bin/clang++", - "-MMD", - "-MF", - "obj/ash/ash_unittests/lock_screen_sanity_unittest.o.d", - "-DV8_DEPRECATION_WARNINGS", - "-DDCHECK_ALWAYS_ON=1", - "-DUSE_UDEV", - "-DUSE_AURA=1", - "-DUSE_NSS_CERTS=1", - "-DUSE_OZONE=1", - "-DFULL_SAFE_BROWSING", - "-DSAFE_BROWSING_CSD", - "-DSAFE_BROWSING_DB_LOCAL", - "-DCHROMIUM_BUILD", - "-DFIELDTRIAL_TESTING_ENABLED", - "-D_FILE_OFFSET_BITS=64", - "-D_LARGEFILE_SOURCE", - "-D_LARGEFILE64_SOURCE", - "-DCR_CLANG_REVISION=\"313786-1\"", - "-D__STDC_CONSTANT_MACROS", - "-D__STDC_FORMAT_MACROS", - "-DCOMPONENT_BUILD", - "-DOS_CHROMEOS", - "-DNDEBUG", - "-DNVALGRIND", - "-DDYNAMIC_ANNOTATIONS_ENABLED=0", - "-DGL_GLEXT_PROTOTYPES", - "-DUSE_GLX", - "-DUSE_EGL", - "-DANGLE_ENABLE_RELEASE_ASSERTS", - "-DTOOLKIT_VIEWS=1", - "-DGTEST_API_=", - "-DGTEST_HAS_POSIX_RE=0", - "-DGTEST_LANG_CXX11=1", - "-DUNIT_TEST", - "-DUSING_V8_SHARED", - "-DU_USING_ICU_NAMESPACE=0", - "-DU_ENABLE_DYLOAD=0", - "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE", - "-DUCHAR_TYPE=uint16_t", - "-DGOOGLE_PROTOBUF_NO_RTTI", - "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER", - "-DHAVE_PTHREAD", - "-DPROTOBUF_USE_DLLS", - "-DBORINGSSL_SHARED_LIBRARY", - "-DSK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS", - "-DSK_HAS_PNG_LIBRARY", - "-DSK_HAS_WEBP_LIBRARY", - "-DSK_HAS_JPEG_LIBRARY", - "-DSKIA_DLL", - "-DGR_GL_IGNORE_ES3_MSAA=0", - "-DSK_SUPPORT_GPU=1", - "-DMESA_EGL_NO_X11_HEADERS", - "-I../..", - "-Igen", - "-I../../third_party/libwebp/src", - "-I../../third_party/khronos", - "-I../../gpu", - "-I../../third_party/googletest/src/googletest/include", - "-I../../third_party/WebKit", - "-Igen/third_party/WebKit", - "-I../../v8/include", - "-Igen/v8/include", - "-I../../third_party/icu/source/common", - "-I../../third_party/icu/source/i18n", - "-I../../third_party/protobuf/src", - "-Igen/protoc_out", - "-I../../third_party/protobuf/src", - "-I../../third_party/boringssl/src/include", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/include/nss", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/include/nspr", - "-I../../skia/config", - "-I../../skia/ext", - "-I../../third_party/skia/include/c", - "-I../../third_party/skia/include/config", - "-I../../third_party/skia/include/core", - "-I../../third_party/skia/include/effects", - "-I../../third_party/skia/include/encode", - "-I../../third_party/skia/include/gpu", - "-I../../third_party/skia/include/images", - "-I../../third_party/skia/include/lazy", - "-I../../third_party/skia/include/pathops", - "-I../../third_party/skia/include/pdf", - "-I../../third_party/skia/include/pipe", - "-I../../third_party/skia/include/ports", - "-I../../third_party/skia/include/utils", - "-I../../third_party/skia/third_party/vulkan", - "-I../../third_party/skia/include/codec", - "-I../../third_party/skia/src/gpu", - "-I../../third_party/skia/src/sksl", - "-I../../third_party/ced/src", - "-I../../third_party/mesa/src/include", - "-I../../third_party/libwebm/source", - "-Igen", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/include/" - "dbus-1.0", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/lib/" - "x86_64-linux-gnu/dbus-1.0/include", - "-I../../third_party/googletest/custom", - "-I../../third_party/googletest/src/googlemock/include", - "-fno-strict-aliasing", - "-Wno-builtin-macro-redefined", - "-D__DATE__=", - "-D__TIME__=", - "-D__TIMESTAMP__=", - "-funwind-tables", - "-fPIC", - "-pipe", - "-B../../third_party/binutils/Linux_x64/Release/bin", - "-pthread", - "-fcolor-diagnostics", - "-no-canonical-prefixes", - "-m64", - "-march=x86-64", - "-Wall", - "-Werror", - "-Wextra", - "-Wno-missing-field-initializers", - "-Wno-unused-parameter", - "-Wno-c++11-narrowing", - "-Wno-covered-switch-default", - "-Wno-unneeded-internal-declaration", - "-Wno-inconsistent-missing-override", - "-Wno-undefined-var-template", - "-Wno-nonportable-include-path", - "-Wno-address-of-packed-member", - "-Wno-unused-lambda-capture", - "-Wno-user-defined-warnings", - "-Wno-enum-compare-switch", - "-Wno-tautological-unsigned-zero-compare", - "-Wno-null-pointer-arithmetic", - "-Wno-tautological-unsigned-enum-zero-compare", - "-O2", - "-fno-ident", - "-fdata-sections", - "-ffunction-sections", - "-fno-omit-frame-pointer", - "-g0", - "-fvisibility=hidden", - "-Xclang", - "-load", - "-Xclang", - "../../third_party/llvm-build/Release+Asserts/lib/" - "libFindBadConstructs.so", - "-Xclang", - "-add-plugin", - "-Xclang", - "find-bad-constructs", - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "check-auto-raw-pointer", - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "check-ipc", - "-Wheader-hygiene", - "-Wstring-conversion", - "-Wtautological-overlap-compare", - "-Wno-header-guard", - "-std=gnu++14", - "-fno-rtti", - "-nostdinc++", - "-isystem../../buildtools/third_party/libc++/trunk/include", - "-isystem../../buildtools/third_party/libc++abi/trunk/include", - "--sysroot=../../build/linux/debian_jessie_amd64-sysroot", - "-fno-exceptions", - "-fvisibility-inlines-hidden", - "-c", - "../../ash/login/ui/lock_screen_sanity_unittest.cc", - "-o", - "obj/ash/ash_unittests/lock_screen_sanity_unittest.o", - }, - - /* expected */ - {"../../third_party/llvm-build/Release+Asserts/bin/clang++", - "-working-directory=/w/c/s/out/Release", - "-DV8_DEPRECATION_WARNINGS", - "-DDCHECK_ALWAYS_ON=1", - "-DUSE_UDEV", - "-DUSE_AURA=1", - "-DUSE_NSS_CERTS=1", - "-DUSE_OZONE=1", - "-DFULL_SAFE_BROWSING", - "-DSAFE_BROWSING_CSD", - "-DSAFE_BROWSING_DB_LOCAL", - "-DCHROMIUM_BUILD", - "-DFIELDTRIAL_TESTING_ENABLED", - "-D_FILE_OFFSET_BITS=64", - "-D_LARGEFILE_SOURCE", - "-D_LARGEFILE64_SOURCE", - "-DCR_CLANG_REVISION=\"313786-1\"", - "-D__STDC_CONSTANT_MACROS", - "-D__STDC_FORMAT_MACROS", - "-DCOMPONENT_BUILD", - "-DOS_CHROMEOS", - "-DNDEBUG", - "-DNVALGRIND", - "-DDYNAMIC_ANNOTATIONS_ENABLED=0", - "-DGL_GLEXT_PROTOTYPES", - "-DUSE_GLX", - "-DUSE_EGL", - "-DANGLE_ENABLE_RELEASE_ASSERTS", - "-DTOOLKIT_VIEWS=1", - "-DGTEST_API_=", - "-DGTEST_HAS_POSIX_RE=0", - "-DGTEST_LANG_CXX11=1", - "-DUNIT_TEST", - "-DUSING_V8_SHARED", - "-DU_USING_ICU_NAMESPACE=0", - "-DU_ENABLE_DYLOAD=0", - "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE", - "-DUCHAR_TYPE=uint16_t", - "-DGOOGLE_PROTOBUF_NO_RTTI", - "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER", - "-DHAVE_PTHREAD", - "-DPROTOBUF_USE_DLLS", - "-DBORINGSSL_SHARED_LIBRARY", - "-DSK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS", - "-DSK_HAS_PNG_LIBRARY", - "-DSK_HAS_WEBP_LIBRARY", - "-DSK_HAS_JPEG_LIBRARY", - "-DSKIA_DLL", - "-DGR_GL_IGNORE_ES3_MSAA=0", - "-DSK_SUPPORT_GPU=1", - "-DMESA_EGL_NO_X11_HEADERS", - "-I../..", - "-Igen", - "-I../../third_party/libwebp/src", - "-I../../third_party/khronos", - "-I../../gpu", - "-I../../third_party/googletest/src/googletest/" - "include", - "-I../../third_party/WebKit", - "-Igen/third_party/WebKit", - "-I../../v8/include", - "-Igen/v8/include", - "-I../../third_party/icu/source/common", - "-I../../third_party/icu/source/i18n", - "-I../../third_party/protobuf/src", - "-Igen/protoc_out", - "-I../../third_party/protobuf/src", - "-I../../third_party/boringssl/src/include", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/include/nss", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/include/nspr", - "-I../../skia/config", - "-I../../skia/ext", - "-I../../third_party/skia/include/c", - "-I../../third_party/skia/include/config", - "-I../../third_party/skia/include/core", - "-I../../third_party/skia/include/effects", - "-I../../third_party/skia/include/encode", - "-I../../third_party/skia/include/gpu", - "-I../../third_party/skia/include/images", - "-I../../third_party/skia/include/lazy", - "-I../../third_party/skia/include/pathops", - "-I../../third_party/skia/include/pdf", - "-I../../third_party/skia/include/pipe", - "-I../../third_party/skia/include/ports", - "-I../../third_party/skia/include/utils", - "-I../../third_party/skia/third_party/vulkan", - "-I../../third_party/skia/include/codec", - "-I../../third_party/skia/src/gpu", - "-I../../third_party/skia/src/sksl", - "-I../../third_party/ced/src", - "-I../../third_party/mesa/src/include", - "-I../../third_party/libwebm/source", - "-Igen", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/include/dbus-1.0", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/lib/x86_64-linux-gnu/dbus-1.0/include", - "-I../../third_party/googletest/custom", - "-I../../third_party/googletest/src/googlemock/" - "include", - "-fno-strict-aliasing", - "-Wno-builtin-macro-redefined", - "-D__DATE__=", - "-D__TIME__=", - "-D__TIMESTAMP__=", - "-funwind-tables", - "-fPIC", - "-pipe", - "-B../../third_party/binutils/Linux_x64/Release/bin", - "-pthread", - "-fcolor-diagnostics", - "-no-canonical-prefixes", - "-m64", - "-march=x86-64", - "-Wall", - "-Werror", - "-Wextra", - "-Wno-missing-field-initializers", - "-Wno-unused-parameter", - "-Wno-c++11-narrowing", - "-Wno-covered-switch-default", - "-Wno-unneeded-internal-declaration", - "-Wno-inconsistent-missing-override", - "-Wno-undefined-var-template", - "-Wno-nonportable-include-path", - "-Wno-address-of-packed-member", - "-Wno-unused-lambda-capture", - "-Wno-user-defined-warnings", - "-Wno-enum-compare-switch", - "-Wno-tautological-unsigned-zero-compare", - "-Wno-null-pointer-arithmetic", - "-Wno-tautological-unsigned-enum-zero-compare", - "-O2", - "-fno-ident", - "-fdata-sections", - "-ffunction-sections", - "-fno-omit-frame-pointer", - "-g0", - "-fvisibility=hidden", - "-Wheader-hygiene", - "-Wstring-conversion", - "-Wtautological-overlap-compare", - "-Wno-header-guard", - "-std=gnu++14", - "-fno-rtti", - "-nostdinc++", - "-isystem../../buildtools/third_party/libc++/" - "trunk/" - "include", - "-isystem../../buildtools/third_party/libc++abi/" - "trunk/" - "include", - "--sysroot=&/w/c/s/out/Release/../../build/linux/" - "debian_jessie_amd64-sysroot", - "-fno-exceptions", - "-fvisibility-inlines-hidden", - "&/w/c/s/out/Release/../../ash/login/ui/" - "lock_screen_sanity_unittest.cc", - "-resource-dir=/w/resource_dir/", - "-Wno-unknown-warning-option", - "-fparse-all-comments"}); - } - - // Checks flag parsing for an example chromium file. - TEST_CASE("chromium") { - CheckFlags( - "/w/c/s/out/Release", "../../apps/app_lifetime_monitor.cc", - /* raw */ - {"/work/goma/gomacc", - "../../third_party/llvm-build/Release+Asserts/bin/clang++", - "-MMD", - "-MF", - "obj/apps/apps/app_lifetime_monitor.o.d", - "-DV8_DEPRECATION_WARNINGS", - "-DDCHECK_ALWAYS_ON=1", - "-DUSE_UDEV", - "-DUSE_ASH=1", - "-DUSE_AURA=1", - "-DUSE_NSS_CERTS=1", - "-DUSE_OZONE=1", - "-DDISABLE_NACL", - "-DFULL_SAFE_BROWSING", - "-DSAFE_BROWSING_CSD", - "-DSAFE_BROWSING_DB_LOCAL", - "-DCHROMIUM_BUILD", - "-DFIELDTRIAL_TESTING_ENABLED", - "-DCR_CLANG_REVISION=\"310694-1\"", - "-D_FILE_OFFSET_BITS=64", - "-D_LARGEFILE_SOURCE", - "-D_LARGEFILE64_SOURCE", - "-D__STDC_CONSTANT_MACROS", - "-D__STDC_FORMAT_MACROS", - "-DCOMPONENT_BUILD", - "-DOS_CHROMEOS", - "-DNDEBUG", - "-DNVALGRIND", - "-DDYNAMIC_ANNOTATIONS_ENABLED=0", - "-DGL_GLEXT_PROTOTYPES", - "-DUSE_GLX", - "-DUSE_EGL", - "-DANGLE_ENABLE_RELEASE_ASSERTS", - "-DTOOLKIT_VIEWS=1", - "-DV8_USE_EXTERNAL_STARTUP_DATA", - "-DU_USING_ICU_NAMESPACE=0", - "-DU_ENABLE_DYLOAD=0", - "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE", - "-DUCHAR_TYPE=uint16_t", - "-DGOOGLE_PROTOBUF_NO_RTTI", - "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER", - "-DHAVE_PTHREAD", - "-DPROTOBUF_USE_DLLS", - "-DSK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS", - "-DSK_HAS_PNG_LIBRARY", - "-DSK_HAS_WEBP_LIBRARY", - "-DSK_HAS_JPEG_LIBRARY", - "-DSKIA_DLL", - "-DGR_GL_IGNORE_ES3_MSAA=0", - "-DSK_SUPPORT_GPU=1", - "-DMESA_EGL_NO_X11_HEADERS", - "-DBORINGSSL_SHARED_LIBRARY", - "-DUSING_V8_SHARED", - "-I../..", - "-Igen", - "-I../../third_party/libwebp/src", - "-I../../third_party/khronos", - "-I../../gpu", - "-I../../third_party/ced/src", - "-I../../third_party/icu/source/common", - "-I../../third_party/icu/source/i18n", - "-I../../third_party/protobuf/src", - "-I../../skia/config", - "-I../../skia/ext", - "-I../../third_party/skia/include/c", - "-I../../third_party/skia/include/config", - "-I../../third_party/skia/include/core", - "-I../../third_party/skia/include/effects", - "-I../../third_party/skia/include/encode", - "-I../../third_party/skia/include/gpu", - "-I../../third_party/skia/include/images", - "-I../../third_party/skia/include/lazy", - "-I../../third_party/skia/include/pathops", - "-I../../third_party/skia/include/pdf", - "-I../../third_party/skia/include/pipe", - "-I../../third_party/skia/include/ports", - "-I../../third_party/skia/include/utils", - "-I../../third_party/skia/third_party/vulkan", - "-I../../third_party/skia/src/gpu", - "-I../../third_party/skia/src/sksl", - "-I../../third_party/mesa/src/include", - "-I../../third_party/libwebm/source", - "-I../../third_party/protobuf/src", - "-Igen/protoc_out", - "-I../../third_party/boringssl/src/include", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/include/nss", - "-I../../build/linux/debian_jessie_amd64-sysroot/usr/include/nspr", - "-Igen", - "-I../../third_party/WebKit", - "-Igen/third_party/WebKit", - "-I../../v8/include", - "-Igen/v8/include", - "-Igen", - "-I../../third_party/flatbuffers/src/include", - "-Igen", - "-fno-strict-aliasing", - "-Wno-builtin-macro-redefined", - "-D__DATE__=", - "-D__TIME__=", - "-D__TIMESTAMP__=", - "-funwind-tables", - "-fPIC", - "-pipe", - "-B../../third_party/binutils/Linux_x64/Release/bin", - "-pthread", - "-fcolor-diagnostics", - "-m64", - "-march=x86-64", - "-Wall", - "-Werror", - "-Wextra", - "-Wno-missing-field-initializers", - "-Wno-unused-parameter", - "-Wno-c++11-narrowing", - "-Wno-covered-switch-default", - "-Wno-unneeded-internal-declaration", - "-Wno-inconsistent-missing-override", - "-Wno-undefined-var-template", - "-Wno-nonportable-include-path", - "-Wno-address-of-packed-member", - "-Wno-unused-lambda-capture", - "-Wno-user-defined-warnings", - "-Wno-enum-compare-switch", - "-O2", - "-fno-ident", - "-fdata-sections", - "-ffunction-sections", - "-fno-omit-frame-pointer", - "-g0", - "-fvisibility=hidden", - "-Xclang", - "-load", - "-Xclang", - "../../third_party/llvm-build/Release+Asserts/lib/" - "libFindBadConstructs.so", - "-Xclang", - "-add-plugin", - "-Xclang", - "find-bad-constructs", - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "check-auto-raw-pointer", - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "check-ipc", - "-Wheader-hygiene", - "-Wstring-conversion", - "-Wtautological-overlap-compare", - "-Wexit-time-destructors", - "-Wno-header-guard", - "-Wno-exit-time-destructors", - "-std=gnu++14", - "-fno-rtti", - "-nostdinc++", - "-isystem../../buildtools/third_party/libc++/trunk/include", - "-isystem../../buildtools/third_party/libc++abi/trunk/include", - "--sysroot=../../build/linux/debian_jessie_amd64-sysroot", - "-fno-exceptions", - "-fvisibility-inlines-hidden", - "../../apps/app_lifetime_monitor.cc"}, - - /* expected */ - {"../../third_party/llvm-build/Release+Asserts/bin/clang++", - "-working-directory=/w/c/s/out/Release", - "-DV8_DEPRECATION_WARNINGS", - "-DDCHECK_ALWAYS_ON=1", - "-DUSE_UDEV", - "-DUSE_ASH=1", - "-DUSE_AURA=1", - "-DUSE_NSS_CERTS=1", - "-DUSE_OZONE=1", - "-DDISABLE_NACL", - "-DFULL_SAFE_BROWSING", - "-DSAFE_BROWSING_CSD", - "-DSAFE_BROWSING_DB_LOCAL", - "-DCHROMIUM_BUILD", - "-DFIELDTRIAL_TESTING_ENABLED", - "-DCR_CLANG_REVISION=\"310694-1\"", - "-D_FILE_OFFSET_BITS=64", - "-D_LARGEFILE_SOURCE", - "-D_LARGEFILE64_SOURCE", - "-D__STDC_CONSTANT_MACROS", - "-D__STDC_FORMAT_MACROS", - "-DCOMPONENT_BUILD", - "-DOS_CHROMEOS", - "-DNDEBUG", - "-DNVALGRIND", - "-DDYNAMIC_ANNOTATIONS_ENABLED=0", - "-DGL_GLEXT_PROTOTYPES", - "-DUSE_GLX", - "-DUSE_EGL", - "-DANGLE_ENABLE_RELEASE_ASSERTS", - "-DTOOLKIT_VIEWS=1", - "-DV8_USE_EXTERNAL_STARTUP_DATA", - "-DU_USING_ICU_NAMESPACE=0", - "-DU_ENABLE_DYLOAD=0", - "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE", - "-DUCHAR_TYPE=uint16_t", - "-DGOOGLE_PROTOBUF_NO_RTTI", - "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER", - "-DHAVE_PTHREAD", - "-DPROTOBUF_USE_DLLS", - "-DSK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS", - "-DSK_HAS_PNG_LIBRARY", - "-DSK_HAS_WEBP_LIBRARY", - "-DSK_HAS_JPEG_LIBRARY", - "-DSKIA_DLL", - "-DGR_GL_IGNORE_ES3_MSAA=0", - "-DSK_SUPPORT_GPU=1", - "-DMESA_EGL_NO_X11_HEADERS", - "-DBORINGSSL_SHARED_LIBRARY", - "-DUSING_V8_SHARED", - "-I../..", - "-Igen", - "-I../../third_party/libwebp/src", - "-I../../third_party/khronos", - "-I../../gpu", - "-I../../third_party/ced/src", - "-I../../third_party/icu/source/common", - "-I../../third_party/icu/source/i18n", - "-I../../third_party/protobuf/src", - "-I../../skia/config", - "-I../../skia/ext", - "-I../../third_party/skia/include/c", - "-I../../third_party/skia/include/config", - "-I../../third_party/skia/include/core", - "-I../../third_party/skia/include/effects", - "-I../../third_party/skia/include/encode", - "-I../../third_party/skia/include/gpu", - "-I../../third_party/skia/include/images", - "-I../../third_party/skia/include/lazy", - "-I../../third_party/skia/include/pathops", - "-I../../third_party/skia/include/pdf", - "-I../../third_party/skia/include/pipe", - "-I../../third_party/skia/include/ports", - "-I../../third_party/skia/include/utils", - "-I../../third_party/skia/third_party/vulkan", - "-I../../third_party/skia/src/gpu", - "-I../../third_party/skia/src/sksl", - "-I../../third_party/mesa/src/include", - "-I../../third_party/libwebm/source", - "-I../../third_party/protobuf/src", - "-Igen/protoc_out", - "-I../../third_party/boringssl/src/include", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/include/nss", - "-I../../build/linux/debian_jessie_amd64-sysroot/" - "usr/include/nspr", - "-Igen", - "-I../../third_party/WebKit", - "-Igen/third_party/WebKit", - "-I../../v8/include", - "-Igen/v8/include", - "-Igen", - "-I../../third_party/flatbuffers/src/include", - "-Igen", - "-fno-strict-aliasing", - "-Wno-builtin-macro-redefined", - "-D__DATE__=", - "-D__TIME__=", - "-D__TIMESTAMP__=", - "-funwind-tables", - "-fPIC", - "-pipe", - "-B../../third_party/binutils/Linux_x64/Release/bin", - "-pthread", - "-fcolor-diagnostics", - "-m64", - "-march=x86-64", - "-Wall", - "-Werror", - "-Wextra", - "-Wno-missing-field-initializers", - "-Wno-unused-parameter", - "-Wno-c++11-narrowing", - "-Wno-covered-switch-default", - "-Wno-unneeded-internal-declaration", - "-Wno-inconsistent-missing-override", - "-Wno-undefined-var-template", - "-Wno-nonportable-include-path", - "-Wno-address-of-packed-member", - "-Wno-unused-lambda-capture", - "-Wno-user-defined-warnings", - "-Wno-enum-compare-switch", - "-O2", - "-fno-ident", - "-fdata-sections", - "-ffunction-sections", - "-fno-omit-frame-pointer", - "-g0", - "-fvisibility=hidden", - "-Wheader-hygiene", - "-Wstring-conversion", - "-Wtautological-overlap-compare", - "-Wexit-time-destructors", - "-Wno-header-guard", - "-Wno-exit-time-destructors", - "-std=gnu++14", - "-fno-rtti", - "-nostdinc++", - "-isystem../../buildtools/third_party/libc++/" - "trunk/" - "include", - "-isystem../../buildtools/third_party/libc++abi/" - "trunk/" - "include", - "--sysroot=&/w/c/s/out/Release/../../build/linux/" - "debian_jessie_amd64-sysroot", - "-fno-exceptions", - "-fvisibility-inlines-hidden", - "&/w/c/s/out/Release/../../apps/app_lifetime_monitor.cc", - "-resource-dir=/w/resource_dir/", - "-Wno-unknown-warning-option", - "-fparse-all-comments"}); - } - TEST_CASE("Directory extraction") { Config init_opts; ProjectConfig config; diff --git a/src/test.cc b/src/test.cc index 22524ab72..4c8bde2a7 100644 --- a/src/test.cc +++ b/src/test.cc @@ -37,8 +37,7 @@ std::string ToString(const rapidjson::Document& document) { buffer.Clear(); document.Accept(writer); - std::string output = buffer.GetString(); - return UpdateToRnNewlines(output); + return buffer.GetString(); } void ParseTestExpectation( diff --git a/src/type_printer.cc b/src/type_printer.cc index c5aac6343..4557dada9 100644 --- a/src/type_printer.cc +++ b/src/type_printer.cc @@ -1,6 +1,6 @@ #include "type_printer.h" -#include -#include "loguru.hpp" + +#include namespace { @@ -38,7 +38,7 @@ std::string GetFunctionSignature(IndexFile* db, NamespaceHelper* ns, const CXIdxDeclInfo* decl) { int num_args = clang_Cursor_getNumArguments(decl->cursor); - std::string function_name = + std::pair function_name = ns->QualifiedName(decl->semanticContainer, decl->entityInfo->name); std::vector> args; @@ -76,7 +76,7 @@ std::string GetFunctionSignature(IndexFile* db, // Second pass: insert argument names before each comma and closing paren. int i = function_name_offset; std::string type_desc_with_names(type_desc.begin(), type_desc.begin() + i); - type_desc_with_names.append(function_name); + type_desc_with_names.append(function_name.first); for (auto& arg : args) { if (arg.first < 0) { LOG_S(ERROR) @@ -99,7 +99,7 @@ std::string GetFunctionSignature(IndexFile* db, } else { // type_desc is either a typedef, or some complicated type we cannot handle. // Append the function_name in this case. - ConcatTypeAndName(type_desc, function_name); + ConcatTypeAndName(type_desc, function_name.first); } return type_desc; diff --git a/src/utils.cc b/src/utils.cc index f20e3c02a..614e1c675 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -430,40 +430,6 @@ std::string GetDefaultResourceDirectory() { return NormalizePath(result); } -std::string UpdateToRnNewlines(std::string output) { - size_t idx = 0; - while (true) { - idx = output.find('\n', idx); - - // No more matches. - if (idx == std::string::npos) - break; - - // Skip an existing "\r\n" match. - if (idx > 0 && output[idx - 1] == '\r') { - ++idx; - continue; - } - - // Replace "\n" with "\r|n". - output.replace(output.begin() + idx, output.begin() + idx + 1, "\r\n"); - } - - return output; -}; - -TEST_SUITE("Update \\n to \\r\\n") { - TEST_CASE("all") { - REQUIRE(UpdateToRnNewlines("\n") == "\r\n"); - REQUIRE(UpdateToRnNewlines("\n\n") == "\r\n\r\n"); - REQUIRE(UpdateToRnNewlines("\r\n\n") == "\r\n\r\n"); - REQUIRE(UpdateToRnNewlines("\n\r\n") == "\r\n\r\n"); - REQUIRE(UpdateToRnNewlines("\r\n\r\n") == "\r\n\r\n"); - REQUIRE(UpdateToRnNewlines("f1\nfo2\nfoo3") == "f1\r\nfo2\r\nfoo3"); - REQUIRE(UpdateToRnNewlines("f1\r\nfo2\r\nfoo3") == "f1\r\nfo2\r\nfoo3"); - } -} - TEST_SUITE("StripFileType") { TEST_CASE("all") { REQUIRE(StripFileType("") == ""); From 233e377137f42f6e1aa1afea7b620e104f5bc96f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 10:37:03 -0700 Subject: [PATCH 055/378] . --- CMakeLists.txt | 6 +- src/filesystem.hh | 5 + src/lex_utils.cc | 110 --------------- src/lex_utils.h | 11 -- src/messages/text_document_document_link.cc | 85 ------------ src/project.cc | 2 +- src/test.cc | 2 +- src/utils.cc | 140 ++++---------------- src/utils.h | 21 +-- src/working_files.cc | 4 +- 10 files changed, 39 insertions(+), 347 deletions(-) create mode 100644 src/filesystem.hh delete mode 100644 src/messages/text_document_document_link.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index e3364e3b9..0e77fcd81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,11 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) +if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") +else() + target_link_libraries(ccls PRIVATE -lstdc++fs) +endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) # loguru calls dladdr target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) @@ -233,7 +238,6 @@ target_sources(ccls PRIVATE src/messages/text_document_did_open.cc src/messages/text_document_did_save.cc src/messages/text_document_document_highlight.cc - src/messages/text_document_document_link.cc src/messages/text_document_document_symbol.cc src/messages/text_document_hover.cc src/messages/text_document_references.cc diff --git a/src/filesystem.hh b/src/filesystem.hh new file mode 100644 index 000000000..0608bd714 --- /dev/null +++ b/src/filesystem.hh @@ -0,0 +1,5 @@ +#pragma once + +#include + +namespace fs = std::experimental::filesystem; diff --git a/src/lex_utils.cc b/src/lex_utils.cc index 5d66adf07..cb3ad0f5c 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -24,116 +24,6 @@ int GetOffsetForPosition(lsPosition position, std::string_view content) { return int(i); } -// TODO: eliminate |line_number| param. -std::optional ExtractQuotedRange(int line_number, const std::string& line) { - // Find starting and ending quote. - int start = 0; - while (start < (int)line.size()) { - char c = line[start]; - ++start; - if (c == '"' || c == '<') - break; - } - if (start == (int)line.size()) - return std::nullopt; - - int end = (int)line.size(); - while (end > 0) { - char c = line[end]; - if (c == '"' || c == '>') - break; - --end; - } - - if (start >= end) - return std::nullopt; - - return lsRange(lsPosition(line_number, start), lsPosition(line_number, end)); -} - -void LexFunctionDeclaration(const std::string& buffer_content, - lsPosition declaration_spelling, - std::optional type_name, - std::string* insert_text, - int* newlines_after_name) { - int name_start = GetOffsetForPosition(declaration_spelling, buffer_content); - - bool parse_return_type = true; - // We need to check if we have a return type (ctors and dtors do not). - if (type_name) { - int name_end = name_start; - while (name_end < buffer_content.size()) { - char c = buffer_content[name_end]; - if (isspace(c) || c == '(') - break; - ++name_end; - } - - std::string func_name = - buffer_content.substr(name_start, name_end - name_start); - if (func_name == *type_name || func_name == ("~" + *type_name)) - parse_return_type = false; - } - - // We need to fetch the return type. This can get complex, ie, - // - // std::vector foo(); - // - int return_start = name_start; - if (parse_return_type) { - int paren_balance = 0; - int angle_balance = 0; - bool expect_token = true; - while (return_start > 0) { - char c = buffer_content[return_start - 1]; - if (paren_balance == 0 && angle_balance == 0) { - if (isspace(c) && !expect_token) { - break; - } - if (!isspace(c)) - expect_token = false; - } - - if (c == ')') - ++paren_balance; - if (c == '(') { - --paren_balance; - expect_token = true; - } - - if (c == '>') - ++angle_balance; - if (c == '<') { - --angle_balance; - expect_token = true; - } - - return_start -= 1; - } - } - - // We need to fetch the arguments. Just scan for the next ';'. - *newlines_after_name = 0; - int end = name_start; - while (end < buffer_content.size()) { - char c = buffer_content[end]; - if (c == ';') - break; - if (c == '\n') - *newlines_after_name += 1; - ++end; - } - - std::string result; - result += buffer_content.substr(return_start, name_start - return_start); - if (type_name && !type_name->empty()) - result += *type_name + "::"; - result += buffer_content.substr(name_start, end - name_start); - TrimEndInPlace(result); - result += " {\n}"; - *insert_text = result; -} - std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content) { int start = GetOffsetForPosition(position, content); diff --git a/src/lex_utils.h b/src/lex_utils.h index 36328ad35..13d6a043c 100644 --- a/src/lex_utils.h +++ b/src/lex_utils.h @@ -3,22 +3,11 @@ #include "lsp.h" #include - -#include #include // Utility method to map |position| to an offset inside of |content|. int GetOffsetForPosition(lsPosition position, std::string_view content); -// TODO: eliminate |line_number| param. -std::optional ExtractQuotedRange(int line_number, const std::string& line); - -void LexFunctionDeclaration(const std::string& buffer_content, - lsPosition declaration_spelling, - std::optional type_name, - std::string* insert_text, - int* newlines_after_name); - std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content); diff --git a/src/messages/text_document_document_link.cc b/src/messages/text_document_document_link.cc deleted file mode 100644 index b44639dfb..000000000 --- a/src/messages/text_document_document_link.cc +++ /dev/null @@ -1,85 +0,0 @@ -#include "lex_utils.h" -#include "message_handler.h" -#include "queue_manager.h" -#include "working_files.h" - -#include - -namespace { -MethodType kMethodType = "textDocument/documentLink"; - -struct In_TextDocumentDocumentLink : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - // The document to provide document links for. - lsTextDocumentIdentifier textDocument; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentLink::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentLink, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentDocumentLink); - -// A document link is a range in a text document that links to an internal or -// external resource, like another text document or a web site. -struct lsDocumentLink { - // The range this link applies to. - lsRange range; - // The uri this link points to. If missing a resolve request is sent later. - std::optional target; -}; -MAKE_REFLECT_STRUCT(lsDocumentLink, range, target); - -struct Out_TextDocumentDocumentLink - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentLink, jsonrpc, id, result); - -struct Handler_TextDocumentDocumentLink - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDocumentLink* request) override { - Out_TextDocumentDocumentLink out; - out.id = request->id; - - if (config->showDocumentLinksOnIncludes) { - QueryFile* file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile* working_file = working_files->GetFileByFilename( - request->params.textDocument.uri.GetPath()); - if (!working_file) { - LOG_S(WARNING) << "Unable to find working file " - << request->params.textDocument.uri.GetPath(); - return; - } - for (const IndexInclude& include : file->def->includes) { - std::optional buffer_line = working_file->GetBufferPosFromIndexPos( - include.line, nullptr, false); - if (!buffer_line) - continue; - - // Subtract 1 from line because querydb stores 1-based lines but - // vscode expects 0-based lines. - std::optional between_quotes = ExtractQuotedRange( - *buffer_line, working_file->buffer_lines[*buffer_line]); - if (!between_quotes) - continue; - - lsDocumentLink link; - link.target = lsDocumentUri::FromPath(include.resolved_path); - link.range = *between_quotes; - out.result.push_back(link); - } - } - - QueueManager::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentLink); -} // namespace diff --git a/src/project.cc b/src/project.cc index 198d60f92..4ff67a2ad 100644 --- a/src/project.cc +++ b/src/project.cc @@ -292,7 +292,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( std::vector ReadCompilerArgumentsFromFile( const std::string& path) { std::vector args; - for (std::string line : ReadLinesWithEnding(path)) { + for (std::string line : ReadFileLines(path)) { TrimInPlace(line); if (line.empty() || StartsWith(line, "#")) continue; diff --git a/src/test.cc b/src/test.cc index 4c8bde2a7..016f03822 100644 --- a/src/test.cc +++ b/src/test.cc @@ -343,7 +343,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { std::cout << "Running " << path << std::endl; // Parse expected output from the test, parse it into JSON document. - std::vector lines_with_endings = ReadLinesWithEnding(path); + std::vector lines_with_endings = ReadFileLines(path); TextReplacer text_replacer; std::vector flags; std::unordered_map all_expected_output; diff --git a/src/utils.cc b/src/utils.cc index 614e1c675..19af1c3fa 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,10 +1,10 @@ #include "utils.h" +#include "filesystem.hh" #include "platform.h" #include #include -#include #include #include @@ -18,10 +18,6 @@ #include #include -#if !defined(__APPLE__) -#include -#endif - // DEFAULT_RESOURCE_DIRECTORY is passed with quotes for non-MSVC compilers, ie, // foo vs "foo". #if defined(_MSC_VER) @@ -31,22 +27,15 @@ #define ENSURE_STRING_MACRO_ARGUMENT(x) x #endif -// See http://stackoverflow.com/a/217605 -void TrimStartInPlace(std::string& s) { +void TrimInPlace(std::string& s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); -} -void TrimEndInPlace(std::string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))) .base(), s.end()); } -void TrimInPlace(std::string& s) { - TrimStartInPlace(s); - TrimEndInPlace(s); -} std::string Trim(std::string s) { TrimInPlace(s); return s; @@ -138,32 +127,8 @@ std::string GetBaseName(const std::string& path) { } std::string StripFileType(const std::string& path) { - size_t last_period = path.find_last_of('.'); - if (last_period != std::string::npos) - return path.substr(0, last_period); - return path; -} - -// See http://stackoverflow.com/a/29752943 -std::string ReplaceAll(const std::string& source, - const std::string& from, - const std::string& to) { - std::string result; - result.reserve(source.length()); // avoids a few memory allocations - - std::string::size_type last_pos = 0; - std::string::size_type find_pos; - - while (std::string::npos != (find_pos = source.find(from, last_pos))) { - result.append(source, last_pos, find_pos - last_pos); - result += to; - last_pos = find_pos + from.length(); - } - - // Care for the rest after last occurrence - result += source.substr(last_pos); - - return result; + fs::path p(path); + return p.parent_path() / p.stem(); } std::vector SplitString(const std::string& str, @@ -198,51 +163,25 @@ static void GetFilesInFolderHelper( bool recursive, std::string output_prefix, const std::function& handler) { - std::queue> q; - q.push(make_pair(folder, output_prefix)); + std::queue> q; + q.push(std::make_pair(fs::path(folder), fs::path(output_prefix))); while (!q.empty()) { - tinydir_dir dir; - if (tinydir_open(&dir, q.front().first.c_str()) == -1) { - LOG_S(WARNING) << "Unable to open directory " << folder; - goto bail; - } - - while (dir.has_next) { - tinydir_file file; - if (tinydir_readfile(&dir, &file) == -1) { - LOG_S(WARNING) << "Unable to read file " << file.name - << " when reading directory " << folder; - goto bail; - } - - // Skip all dot files except .ccls. - // - // The nested ifs are intentional, branching order is subtle here. - // - // Note that in the future if we do support dot directories/files, we must - // always ignore the '.' and '..' directories otherwise this will loop - // infinitely. - if (file.name[0] != '.' || strcmp(file.name, ".ccls") == 0) { - if (file.is_dir) { + for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { + auto path = it->path(); + std::string filename = path.filename(); + if (filename[0] != '.' || filename == ".ccls") { + fs::file_status status = it->symlink_status(); + if (fs::is_regular_file(status)) + handler(q.front().second / filename); + else if (fs::is_directory(status) || fs::is_symlink(status)) { if (recursive) { - std::string child_dir = q.front().second + file.name + "/"; - if (!IsSymLink(file.path)) - q.push(make_pair(file.path, child_dir)); + std::string child_dir = q.front().second / filename; + if (fs::is_directory(status)) + q.push(make_pair(path, child_dir)); } - } else { - handler(q.front().second + file.name); } } - - if (tinydir_next(&dir) == -1) { - LOG_S(WARNING) << "Unable to fetch next file when reading directory " - << folder; - goto bail; - } } - - bail: - tinydir_close(&dir); q.pop(); } } @@ -311,8 +250,7 @@ std::istream& SafeGetline(std::istream& is, std::string& t) { } bool FileExists(const std::string& filename) { - std::ifstream cache(filename); - return cache.is_open(); + return fs::exists(filename); } std::optional ReadContent(const std::string& filename) { @@ -328,31 +266,20 @@ std::optional ReadContent(const std::string& filename) { } } -std::vector ReadLinesWithEnding(std::string filename) { +std::vector ReadFileLines(std::string filename) { std::vector result; - - std::ifstream input(filename); - for (std::string line; SafeGetline(input, line);) + std::ifstream fin(filename); + for (std::string line; std::getline(fin, line);) result.push_back(line); - return result; } -std::vector ToLines(const std::string& content, - bool trim_whitespace) { +std::vector ToLines(const std::string& content) { std::vector result; - std::istringstream lines(content); - std::string line; - while (getline(lines, line)) { - if (trim_whitespace) - TrimInPlace(line); - else - RemoveLastCR(line); + while (getline(lines, line)) result.push_back(line); - } - return result; } @@ -385,27 +312,6 @@ void WriteToFile(const std::string& filename, const std::string& content) { file << content; } -float GetProcessMemoryUsedInMb() { -#if defined(__APPLE__) - return 0.f; -#else - const float kBytesToMb = 1000000; - uint64_t memory_after = spp::GetProcessMemoryUsed(); - return memory_after / kBytesToMb; -#endif -} - -std::string FormatMicroseconds(long long microseconds) { - long long milliseconds = microseconds / 1000; - long long remaining = microseconds - milliseconds; - - // Only show two digits after the dot. - while (remaining >= 100) - remaining /= 10; - - return std::to_string(milliseconds) + "." + std::to_string(remaining) + "ms"; -} - std::string GetDefaultResourceDirectory() { std::string result; diff --git a/src/utils.h b/src/utils.h index 860a8fa21..4eb42ca66 100644 --- a/src/utils.h +++ b/src/utils.h @@ -10,11 +10,6 @@ #include #include -// Trim from start (in place) -void TrimStartInPlace(std::string& s); -// Trim from end (in place) -void TrimEndInPlace(std::string& s); -// Trim from both ends (in place) void TrimInPlace(std::string& s); std::string Trim(std::string s); @@ -41,10 +36,6 @@ std::string GetBaseName(const std::string& path); // Returns |path| without the filetype, ie, "foo/bar.cc" => "foo/bar". std::string StripFileType(const std::string& path); -std::string ReplaceAll(const std::string& source, - const std::string& from, - const std::string& to); - std::vector SplitString(const std::string& str, const std::string& delimiter); @@ -95,9 +86,8 @@ std::string EscapeFileName(std::string path); // FIXME: Move ReadContent into ICacheManager? bool FileExists(const std::string& filename); std::optional ReadContent(const std::string& filename); -std::vector ReadLinesWithEnding(std::string filename); -std::vector ToLines(const std::string& content, - bool trim_whitespace); +std::vector ReadFileLines(std::string filename); +std::vector ToLines(const std::string& content); struct TextReplacer { struct Replacement { @@ -163,11 +153,4 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { }; \ } -float GetProcessMemoryUsedInMb(); - -std::string FormatMicroseconds(long long microseconds); - std::string GetDefaultResourceDirectory(); - -// Makes sure all newlines in |output| are in \r\n format. -std::string UpdateToRnNewlines(std::string output); diff --git a/src/working_files.cc b/src/working_files.cc index 52fcd5168..478a6ff59 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -215,14 +215,14 @@ WorkingFile::WorkingFile(const std::string& filename, } void WorkingFile::SetIndexContent(const std::string& index_content) { - index_lines = ToLines(index_content, false /*trim_whitespace*/); + index_lines = ToLines(index_content); index_to_buffer.clear(); buffer_to_index.clear(); } void WorkingFile::OnBufferContentUpdated() { - buffer_lines = ToLines(buffer_content, false /*trim_whitespace*/); + buffer_lines = ToLines(buffer_content); index_to_buffer.clear(); buffer_to_index.clear(); From 9aca6119eda176a2055e4374312da04daf523c39 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 11:32:28 -0700 Subject: [PATCH 056/378] . --- index_tests/outline/outline.cc | 120 ------------------------ index_tests/outline/outline2.cc | 158 -------------------------------- src/cache_manager.cc | 4 +- src/import_pipeline.cc | 4 +- src/message_handler.cc | 2 +- src/query.cc | 27 +----- src/query.h | 11 +-- src/serializer.cc | 4 +- src/test.cc | 87 ------------------ src/utils.cc | 155 ++++++++++--------------------- src/utils.h | 15 +-- 11 files changed, 63 insertions(+), 524 deletions(-) delete mode 100644 index_tests/outline/outline.cc delete mode 100644 index_tests/outline/outline2.cc diff --git a/index_tests/outline/outline.cc b/index_tests/outline/outline.cc deleted file mode 100644 index 08b07313e..000000000 --- a/index_tests/outline/outline.cc +++ /dev/null @@ -1,120 +0,0 @@ -#include - -struct MergeableUpdate { - int a; - int b; - std::vector to_add; -}; - -/* -TEXT_REPLACE: -std::__1::vector <===> std::vector -c:@N@std@ST>2#T#T@vector <===> c:@N@std@N@__1@ST>2#T#T@vector -10956461108384510180 <===> 9178760565669096175 - -OUTPUT: -{ - "includes": [{ - "line": 0, - "resolved_path": "&vector" - }], - "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 14399919566014425846, - "detailed_name": "MergeableUpdate", - "short_name": "MergeableUpdate", - "kind": 23, - "declarations": [], - "spell": "3:8-3:23|-1|1|2", - "extent": "3:1-7:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [0, 1, 2], - "instances": [], - "uses": [] - }, { - "id": 1, - "usr": 17, - "detailed_name": "", - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": [] - }, { - "id": 2, - "usr": 9178760565669096175, - "detailed_name": "std::vector", - "short_name": "vector", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [2], - "uses": ["6:8-6:14|-1|1|4"] - }, { - "id": 3, - "usr": 5401847601697785946, - "detailed_name": "", - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["6:3-6:6|0|2|4"] - }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 11633578660978286467, - "detailed_name": "int MergeableUpdate::a", - "short_name": "a", - "declarations": [], - "spell": "4:7-4:8|0|2|2", - "extent": "4:3-4:8|0|2|0", - "type": 1, - "uses": [], - "kind": 8, - "storage": 0 - }, { - "id": 1, - "usr": 14949552147532317793, - "detailed_name": "int MergeableUpdate::b", - "short_name": "b", - "declarations": [], - "spell": "5:7-5:8|0|2|2", - "extent": "5:3-5:8|0|2|0", - "type": 1, - "uses": [], - "kind": 8, - "storage": 0 - }, { - "id": 2, - "usr": 9003350345237582363, - "detailed_name": "std::vector MergeableUpdate::to_add", - "short_name": "to_add", - "declarations": [], - "spell": "6:20-6:26|0|2|2", - "extent": "6:3-6:26|0|2|0", - "type": 2, - "uses": [], - "kind": 8, - "storage": 0 - }] -} -*/ diff --git a/index_tests/outline/outline2.cc b/index_tests/outline/outline2.cc deleted file mode 100644 index c5a318615..000000000 --- a/index_tests/outline/outline2.cc +++ /dev/null @@ -1,158 +0,0 @@ -//#pragma once - -#include -#include - -struct CompilationEntry { - std::string directory; - std::string filename; - std::vector args; -}; - -std::vector LoadCompilationEntriesFromDirectory(const std::string& project_directory); - -/* -TEXT_REPLACE: -std::__1::vector <===> std::vector -std::__1::string <===> std::string -std::__cxx11::string <===> std::string -c:@N@std@string <===> c:@N@std@N@__1@T@string -c:@N@std@T@string <===> c:@N@std@N@__1@T@string -c:@N@std@N@__cxx11@T@string <===> c:@N@std@N@__1@T@string -c:@N@std@ST>2#T#T@vector <===> c:@N@std@N@__1@ST>2#T#T@vector -c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@N@__1@S@basic_string>#C#$@N@std@N@__1@S@char_traits>#C#$@N@std@N@__1@S@allocator>#C# <===> c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# -c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@N@__cxx11@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# <===> c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C# -4160338041907786 <===> 14151982074805896770 -7543170857910783654 <===> 14151982074805896770 -9802818309312685221 <===> 11244864715202245734 -7636646237071509980 <===> 14151982074805896770 -9178760565669096175 <===> 10956461108384510180 -10468929532989002392 <===> 11244864715202245734 -4160338041907786 <===> 14151982074805896770 -9802818309312685221 <===> 11244864715202245734 - -OUTPUT: -{ - "includes": [{ - "line": 2, - "resolved_path": "&string" - }, { - "line": 3, - "resolved_path": "&vector" - }], - "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 4992269036372211530, - "detailed_name": "CompilationEntry", - "short_name": "CompilationEntry", - "kind": 23, - "declarations": [], - "spell": "6:8-6:24|-1|1|2", - "extent": "6:1-10:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [0, 1, 2], - "instances": [], - "uses": ["12:13-12:29|-1|1|4"] - }, { - "id": 1, - "usr": 14151982074805896770, - "detailed_name": "std::string", - "short_name": "string", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": ["7:8-7:14|-1|1|4", "8:8-8:14|-1|1|4", "9:20-9:26|-1|1|4", "12:78-12:84|-1|1|4"] - }, { - "id": 2, - "usr": 5401847601697785946, - "detailed_name": "", - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["7:3-7:6|0|2|4", "8:3-8:6|0|2|4", "9:3-9:6|0|2|4", "9:15-9:18|0|2|4", "12:1-12:4|-1|1|4", "12:73-12:76|-1|1|4"] - }, { - "id": 3, - "usr": 10956461108384510180, - "detailed_name": "std::vector", - "short_name": "vector", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [2], - "uses": ["9:8-9:14|-1|1|4", "12:6-12:12|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 11244864715202245734, - "detailed_name": "std::vector LoadCompilationEntriesFromDirectory(const std::string &project_directory)", - "short_name": "LoadCompilationEntriesFromDirectory", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "12:31-12:66|-1|1|1", - "param_spellings": ["12:86-12:103"] - }], - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 1153224798516629792, - "detailed_name": "std::string CompilationEntry::directory", - "short_name": "directory", - "declarations": [], - "spell": "7:15-7:24|0|2|2", - "extent": "7:3-7:24|0|2|0", - "type": 1, - "uses": [], - "kind": 8, - "storage": 0 - }, { - "id": 1, - "usr": 2255668374222866345, - "detailed_name": "std::string CompilationEntry::filename", - "short_name": "filename", - "declarations": [], - "spell": "8:15-8:23|0|2|2", - "extent": "8:3-8:23|0|2|0", - "type": 1, - "uses": [], - "kind": 8, - "storage": 0 - }, { - "id": 2, - "usr": 12616880765274259414, - "detailed_name": "std::vector CompilationEntry::args", - "short_name": "args", - "declarations": [], - "spell": "9:28-9:32|0|2|2", - "extent": "9:3-9:32|0|2|0", - "type": 3, - "uses": [], - "kind": 8, - "storage": 0 - }] -} -*/ diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 4ae4e55b4..2c23f26c7 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -47,10 +47,10 @@ struct RealCacheManager : ICacheManager { std::string cache_file; size_t len = config_->projectRoot.size(); if (StartsWith(source_file, config_->projectRoot)) { - cache_file = EscapeFileName(config_->projectRoot) + '/' + + cache_file = EscapeFileName(config_->projectRoot) + EscapeFileName(source_file.substr(len)); } else { - cache_file = '@' + EscapeFileName(config_->projectRoot) + '/' + + cache_file = '@' + EscapeFileName(config_->projectRoot) + EscapeFileName(source_file); } diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 9c087ef46..bff9f65be 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -673,7 +673,7 @@ void QueryDb_DoIdMap(QueueManager* queue, // it, load the previous state from disk and rerun IdMap logic later. Do not // do this if we have already attempted in the past. if (!request->load_previous && !request->previous && - db->usr_to_file.find(NormalizedPath(request->current->path)) != + db->usr_to_file.find(LowerPathIfInsensitive(request->current->path)) != db->usr_to_file.end()) { assert(!request->load_previous); request->load_previous = true; @@ -740,7 +740,7 @@ void QueryDb_OnIndexed(QueueManager* queue, // Semantic highlighting. QueryFileId file_id = - db->usr_to_file[NormalizedPath(working_file->filename)]; + db->usr_to_file[LowerPathIfInsensitive(working_file->filename)]; QueryFile* file = &db->files[file_id.id]; EmitSemanticHighlighting(db, semantic_cache, working_file, file); } diff --git a/src/message_handler.cc b/src/message_handler.cc index 0d3a2082a..897d91376 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -131,7 +131,7 @@ bool FindFileOrFail(QueryDatabase* db, QueryFileId* out_file_id) { *out_query_file = nullptr; - auto it = db->usr_to_file.find(NormalizedPath(absolute_path)); + auto it = db->usr_to_file.find(LowerPathIfInsensitive(absolute_path)); if (it != db->usr_to_file.end()) { QueryFile& file = db->files[it->second.id]; if (file.def) { diff --git a/src/query.cc b/src/query.cc index 9fcb4c417..389971b30 100644 --- a/src/query.cc +++ b/src/query.cc @@ -305,7 +305,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, Maybe GetQueryFileIdFromPath(QueryDatabase* query_db, const std::string& path, bool create_if_missing) { - NormalizedPath normalized_path(path); + std::string normalized_path = LowerPathIfInsensitive(path); auto it = query_db->usr_to_file.find(normalized_path); if (it != query_db->usr_to_file.end()) return QueryFileId(it->second.id); @@ -730,33 +730,12 @@ std::string IndexUpdate::ToString() { return output.GetString(); } -NormalizedPath::NormalizedPath(const std::string& path) - : path(LowerPathIfCaseInsensitive(path)) {} - -bool NormalizedPath::operator==(const NormalizedPath& rhs) const { - return path == rhs.path; -} - -bool NormalizedPath::operator!=(const NormalizedPath& rhs) const { - return path != rhs.path; -} - // ------------------------ // QUERYDB THREAD FUNCTIONS // ------------------------ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove) { - // This function runs on the querydb thread. - - // When we remove an element, we just erase the state from the storage. We do - // not update array indices because that would take a huge amount of time for - // a very large index. - // - // There means that there is some memory growth that will never be reclaimed, - // but it should be pretty minimal and is solved by simply restarting the - // indexer and loading from cache, which is a fast operation. - switch (usr_kind) { case SymbolKind::Type: { for (const Usr& usr : to_remove) { @@ -816,7 +795,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { } for (const std::string& filename : update->files_removed) - files[usr_to_file[NormalizedPath(filename)].id].def = std::nullopt; + files[usr_to_file[LowerPathIfInsensitive(filename)].id].def = std::nullopt; ImportOrUpdate(update->files_def_update); RemoveUsrs(SymbolKind::Type, update->types_removed); @@ -845,7 +824,7 @@ void QueryDatabase::ImportOrUpdate( // This function runs on the querydb thread. for (auto& def : updates) { - auto it = usr_to_file.find(NormalizedPath(def.value.path)); + auto it = usr_to_file.find(LowerPathIfInsensitive(def.value.path)); assert(it != usr_to_file.end()); QueryFile& existing = files[it->second.id]; diff --git a/src/query.h b/src/query.h index ac746aa68..9fb8fcd90 100644 --- a/src/query.h +++ b/src/query.h @@ -257,15 +257,6 @@ MAKE_REFLECT_STRUCT(IndexUpdate, vars_declarations, vars_uses); -struct NormalizedPath { - explicit NormalizedPath(const std::string& path); - bool operator==(const NormalizedPath& rhs) const; - bool operator!=(const NormalizedPath& rhs) const; - - std::string path; -}; -MAKE_HASHABLE(NormalizedPath, t.path); - // The query database is heavily optimized for fast queries. It is stored // in-memory. struct QueryDatabase { @@ -279,7 +270,7 @@ struct QueryDatabase { std::vector vars; // Lookup symbol based on a usr. - spp::sparse_hash_map usr_to_file; + spp::sparse_hash_map usr_to_file; spp::sparse_hash_map usr_to_type; spp::sparse_hash_map usr_to_func; spp::sparse_hash_map usr_to_var; diff --git a/src/serializer.cc b/src/serializer.cc index 7cd1df72b..3e8bd3b9a 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -449,8 +449,6 @@ TEST_SUITE("Serializer utils") { REQUIRE(GetBaseName("foo/foo.cc") == "foo.cc"); REQUIRE(GetBaseName("/foo.cc") == "foo.cc"); REQUIRE(GetBaseName("///foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("bar/") == "bar/"); - REQUIRE(GetBaseName("foobar/bar/") == - "foobar/bar/"); // TODO: Should be bar, but good enough. + REQUIRE(GetBaseName("bar/") == "."); } } diff --git a/src/test.cc b/src/test.cc index 016f03822..69b9c13eb 100644 --- a/src/test.cc +++ b/src/test.cc @@ -81,38 +81,6 @@ void ParseTestExpectation( */ #endif - // Scan for TEXT_REPLACE: - { - bool in_output = false; - for (std::string line : lines_with_endings) { - TrimInPlace(line); - - if (StartsWith(line, "TEXT_REPLACE:")) { - assert(!in_output && "multiple TEXT_REPLACE sections"); - in_output = true; - continue; - } - - if (in_output && line.empty()) - break; - - if (in_output) { - static const std::string kKey = " <===> "; - size_t index = line.find(kKey); - LOG_IF_S(FATAL, index == std::string::npos) - << " No '" << kKey << "' in replacement string '" << line << "'" - << ", index=" << index; - - TextReplacer::Replacement replacement; - replacement.from = line.substr(0, index); - replacement.to = line.substr(index + kKey.size()); - TrimInPlace(replacement.from); - TrimInPlace(replacement.to); - replacer->replacements.push_back(replacement); - } - } - } - // Scan for EXTRA_FLAGS: { bool in_output = false; @@ -461,58 +429,3 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { return success; } - -// TODO: ctor/dtor, copy ctor -// TODO: Always pass IndexFile by pointer, ie, search and remove all IndexFile& -// refs. - -TEST_SUITE("ParseTestExpectation") { - TEST_CASE("Parse TEXT_REPLACE") { - // clang-format off - std::vector lines_with_endings = { - "/*\n", - "TEXT_REPLACE:\n", - " foo <===> \tbar \n", - "01 <===> 2\n", - "\n", - "*/\n"}; - // clang-format on - - TextReplacer text_replacer; - std::vector flags; - std::unordered_map all_expected_output; - ParseTestExpectation("foo.cc", lines_with_endings, &text_replacer, &flags, - &all_expected_output); - - REQUIRE(text_replacer.replacements.size() == 2); - REQUIRE(text_replacer.replacements[0].from == "foo"); - REQUIRE(text_replacer.replacements[0].to == "bar"); - REQUIRE(text_replacer.replacements[1].from == "01"); - REQUIRE(text_replacer.replacements[1].to == "2"); - } - - TEST_CASE("Apply TEXT_REPLACE") { - TextReplacer replacer; - replacer.replacements.push_back(TextReplacer::Replacement{"foo", "bar"}); - replacer.replacements.push_back(TextReplacer::Replacement{"01", "2"}); - replacer.replacements.push_back(TextReplacer::Replacement{"3", "456"}); - - // Equal-length. - REQUIRE(replacer.Apply("foo") == "bar"); - REQUIRE(replacer.Apply("bar") == "bar"); - - // Shorter replacement. - REQUIRE(replacer.Apply("01") == "2"); - REQUIRE(replacer.Apply("2") == "2"); - - // Longer replacement. - REQUIRE(replacer.Apply("3") == "456"); - REQUIRE(replacer.Apply("456") == "456"); - - // Content before-after replacement. - REQUIRE(replacer.Apply("aaaa01bbbb") == "aaaa2bbbb"); - - // Multiple replacements. - REQUIRE(replacer.Apply("foofoobar0123") == "barbarbar22456"); - } -} diff --git a/src/utils.cc b/src/utils.cc index 19af1c3fa..59b1c28d4 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -7,16 +7,17 @@ #include #include +#include +#include +#include #include -#include -#include -#include #include #include #include #include #include #include +using namespace std::placeholders; // DEFAULT_RESOURCE_DIRECTORY is passed with quotes for non-MSVC compilers, ie, // foo vs "foo". @@ -28,32 +29,16 @@ #endif void TrimInPlace(std::string& s) { - s.erase(s.begin(), - std::find_if(s.begin(), s.end(), - std::not1(std::ptr_fun(std::isspace)))); - s.erase(std::find_if(s.rbegin(), s.rend(), - std::not1(std::ptr_fun(std::isspace))) - .base(), - s.end()); + auto f = [](char c) { return !isspace(c); }; + s.erase(s.begin(), std::find_if(s.begin(), s.end(), f)); + s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end()); } std::string Trim(std::string s) { TrimInPlace(s); return s; } -void RemoveLastCR(std::string& s) { - if (!s.empty() && *s.rbegin() == '\r') - s.pop_back(); -} - -uint64_t HashUsr(const std::string& s) { - return HashUsr(s.c_str(), s.size()); -} -uint64_t HashUsr(const char* s) { - return HashUsr(s, strlen(s)); -} - -uint64_t HashUsr(const char* s, size_t n) { +uint64_t HashUsr(std::string_view s) { union { uint64_t ret; uint8_t out[8]; @@ -61,43 +46,31 @@ uint64_t HashUsr(const char* s, size_t n) { // k is an arbitrary key. Don't change it. const uint8_t k[16] = {0xd0, 0xe5, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x61, 0x79, 0xea, 0x70, 0xca, 0x70, 0xf0, 0x0d}; - (void)siphash(reinterpret_cast(s), n, k, out, 8); + (void)siphash(reinterpret_cast(s.data()), s.size(), k, out, 8); return ret; } -// See http://stackoverflow.com/a/2072890 -bool EndsWith(std::string_view value, std::string_view ending) { - if (ending.size() > value.size()) - return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +bool EndsWith(std::string_view s, std::string_view suffix) { + return s.size() >= suffix.size() && + std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); } -bool StartsWith(std::string_view value, std::string_view start) { - if (start.size() > value.size()) - return false; - return std::equal(start.begin(), start.end(), value.begin()); +bool StartsWith(std::string_view s, std::string_view prefix) { + return s.size() >= prefix.size() && + std::equal(prefix.begin(), prefix.end(), s.begin()); } -bool AnyStartsWith(const std::vector& values, - const std::string& start) { - return std::any_of( - std::begin(values), std::end(values), - [&start](const std::string& value) { return StartsWith(value, start); }); +bool AnyStartsWith(const std::vector& xs, + std::string_view prefix) { + return std::any_of(xs.begin(), xs.end(), std::bind(StartsWith, _1, prefix)); } -bool StartsWithAny(const std::string& value, - const std::vector& startings) { - return std::any_of(std::begin(startings), std::end(startings), - [&value](const std::string& starting) { - return StartsWith(value, starting); - }); +bool StartsWithAny(std::string_view s, const std::vector& ps) { + return std::any_of(ps.begin(), ps.end(), std::bind(StartsWith, s, _1)); } -bool EndsWithAny(const std::string& value, - const std::vector& endings) { - return std::any_of( - std::begin(endings), std::end(endings), - [&value](const std::string& ending) { return EndsWith(value, ending); }); +bool EndsWithAny(std::string_view s, const std::vector& ss) { + return std::any_of(ss.begin(), ss.end(), std::bind(EndsWith, s, _1)); } bool FindAnyPartial(const std::string& value, @@ -120,10 +93,7 @@ std::string GetDirName(std::string path) { } std::string GetBaseName(const std::string& path) { - size_t last_slash = path.find_last_of('/'); - if (last_slash != std::string::npos && (last_slash + 1) < path.size()) - return path.substr(last_slash + 1); - return path; + return fs::path(path).filename(); } std::string StripFileType(const std::string& path) { @@ -149,13 +119,15 @@ std::vector SplitString(const std::string& str, return strings; } -std::string LowerPathIfCaseInsensitive(const std::string& path) { - std::string result = path; +std::string LowerPathIfInsensitive(const std::string& path) { #if defined(_WIN32) - for (size_t i = 0; i < result.size(); ++i) - result[i] = (char)tolower(result[i]); + std::string ret = path; + for (char& c : ret) + c = tolower(c); + return ret; +#else + return path; #endif - return result; } static void GetFilesInFolderHelper( @@ -164,7 +136,7 @@ static void GetFilesInFolderHelper( std::string output_prefix, const std::function& handler) { std::queue> q; - q.push(std::make_pair(fs::path(folder), fs::path(output_prefix))); + q.emplace(fs::path(folder), fs::path(output_prefix)); while (!q.empty()) { for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { auto path = it->path(); @@ -212,58 +184,29 @@ void EnsureEndsInSlash(std::string& path) { } std::string EscapeFileName(std::string path) { - if (path.size() && path.back() == '/') - path.pop_back(); - std::replace(path.begin(), path.end(), '\\', '@'); - std::replace(path.begin(), path.end(), '/', '@'); - std::replace(path.begin(), path.end(), ':', '@'); + bool slash = path.size() && path.back() == '/'; + for (char& c : path) + if (c == '\\' || c == '/' || c == ':') + c = '@'; + if (slash) + path += '/'; return path; } -// http://stackoverflow.com/a/6089413 -std::istream& SafeGetline(std::istream& is, std::string& t) { - t.clear(); - - // The characters in the stream are read one-by-one using a std::streambuf. - // That is faster than reading them one-by-one using the std::istream. Code - // that uses streambuf this way must be guarded by a sentry object. The sentry - // object performs various tasks, such as thread synchronization and updating - // the stream state. - - std::istream::sentry se(is, true); - std::streambuf* sb = is.rdbuf(); - - for (;;) { - int c = sb->sbumpc(); - if (c == EOF) { - // Also handle the case when the last line has no line ending - if (t.empty()) - is.setstate(std::ios::eofbit); - return is; - } - - t += (char)c; - - if (c == '\n') - return is; - } -} - bool FileExists(const std::string& filename) { return fs::exists(filename); } std::optional ReadContent(const std::string& filename) { LOG_S(INFO) << "Reading " << filename; - std::ifstream cache; - cache.open(filename); - - try { - return std::string(std::istreambuf_iterator(cache), - std::istreambuf_iterator()); - } catch (std::ios_base::failure&) { - return std::nullopt; - } + char buf[4096]; + std::string ret; + FILE* f = fopen(filename.c_str(), "rb"); + if (!f) return {}; + size_t n; + while ((n = fread(buf, 1, sizeof buf, f)) > 0) + ret.append(buf, n); + return ret; } std::vector ReadFileLines(std::string filename) { @@ -302,14 +245,12 @@ std::string TextReplacer::Apply(const std::string& content) { } void WriteToFile(const std::string& filename, const std::string& content) { - std::ofstream file(filename, - std::ios::out | std::ios::trunc | std::ios::binary); - if (!file.good()) { + FILE* f = fopen(filename.c_str(), "wb"); + if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) { LOG_S(ERROR) << "Cannot write to " << filename; return; } - - file << content; + fclose(f); } std::string GetDefaultResourceDirectory() { diff --git a/src/utils.h b/src/utils.h index 4eb42ca66..16685885a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -13,19 +13,14 @@ void TrimInPlace(std::string& s); std::string Trim(std::string s); -uint64_t HashUsr(const std::string& s); -uint64_t HashUsr(const char* s); -uint64_t HashUsr(const char* s, size_t n); +uint64_t HashUsr(std::string_view s); // Returns true if |value| starts/ends with |start| or |ending|. bool StartsWith(std::string_view value, std::string_view start); bool EndsWith(std::string_view value, std::string_view ending); -bool AnyStartsWith(const std::vector& values, - const std::string& start); -bool StartsWithAny(const std::string& value, - const std::vector& startings); -bool EndsWithAny(const std::string& value, - const std::vector& endings); +bool AnyStartsWith(const std::vector& xs, std::string_view prefix); +bool StartsWithAny(std::string_view s, const std::vector& ps); +bool EndsWithAny(std::string_view s, const std::vector& ss); bool FindAnyPartial(const std::string& value, const std::vector& values); // Returns the dirname of |path|, i.e. "foo/bar.cc" => "foo", "foo" => ".", @@ -39,7 +34,7 @@ std::string StripFileType(const std::string& path); std::vector SplitString(const std::string& str, const std::string& delimiter); -std::string LowerPathIfCaseInsensitive(const std::string& path); +std::string LowerPathIfInsensitive(const std::string& path); template std::string StringJoinMap(const TValues& values, From d83be5adcc1bf46001cee72b1788c982e95d38c8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 13:41:38 -0700 Subject: [PATCH 057/378] . --- CMakeLists.txt | 1 - src/import_pipeline.cc | 30 ---------- src/lsp_diagnostic.cc | 5 -- src/messages/text_document_completion.cc | 2 +- src/test.cc | 71 ------------------------ src/timer.cc | 19 ++----- src/timer.h | 9 +-- 7 files changed, 8 insertions(+), 129 deletions(-) delete mode 100644 src/lsp_diagnostic.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e77fcd81..7768bd82b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,7 +189,6 @@ target_sources(ccls PRIVATE src/include_complete.cc src/method.cc src/lex_utils.cc - src/lsp_diagnostic.cc src/lsp.cc src/match.cc src/message_handler.cc diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index bff9f65be..8f53c8c09 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -491,30 +491,6 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { response->current->file->last_modification_time); } - #if false - #define PRINT_SECTION(name) \ - if (response->perf.name) { \ - total += response->perf.name; \ - output << " " << #name << ": " << FormatMicroseconds(response->perf.name); \ - } - std::stringstream output; - long long total = 0; - output << "[perf]"; - PRINT_SECTION(index_parse); - PRINT_SECTION(index_build); - PRINT_SECTION(index_save_to_disk); - PRINT_SECTION(index_load_cached); - PRINT_SECTION(querydb_id_map); - PRINT_SECTION(index_make_delta); - output << "\n total: " << FormatMicroseconds(total); - output << " path: " << response->current_index->path; - LOG_S(INFO) << output.rdbuf(); - #undef PRINT_SECTION - - if (response->is_interactive) - LOG_S(INFO) << "Applying IndexUpdate" << std::endl << update.ToString(); - #endif - Index_OnIndexed reply(std::move(update), response->perf); queue->on_indexed.PushBack(std::move(reply), response->is_interactive); } @@ -551,13 +527,7 @@ bool IndexMergeIndexUpdates() { if (!to_join) break; did_merge = true; - // Timer time; root->update.Merge(std::move(to_join->update)); - // time.ResetAndPrint("Joined querydb updates for files: " + - // StringJoinMap(root->update.files_def_update, - //[](const QueryFile::DefUpdate& update) { - // return update.path; - //})); } queue->on_indexed.PushFront(std::move(*root)); diff --git a/src/lsp_diagnostic.cc b/src/lsp_diagnostic.cc deleted file mode 100644 index e6a000d76..000000000 --- a/src/lsp_diagnostic.cc +++ /dev/null @@ -1,5 +0,0 @@ -#include "lsp_diagnostic.h" - -#include "match.h" -#include "queue_manager.h" -#include "working_files.h" diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 14e82af44..3c9831b05 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -165,7 +165,7 @@ void FilterAndSortCompletionResponse( if (!enable) return; - ScopedPerfTimer timer("FilterAndSortCompletionResponse"); + ScopedPerfTimer timer{"FilterAndSortCompletionResponse"}; // Used to inject more completions. #if false diff --git a/src/test.cc b/src/test.cc index 69b9c13eb..266ab030d 100644 --- a/src/test.cc +++ b/src/test.cc @@ -23,11 +23,6 @@ #include #endif -void Write(const std::vector& strs) { - for (const std::string& str : strs) - std::cout << str << std::endl; -} - std::string ToString(const rapidjson::Document& document) { rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); @@ -46,41 +41,6 @@ void ParseTestExpectation( TextReplacer* replacer, std::vector* flags, std::unordered_map* output_sections) { -#if false -#include "bar.h" - - void foo(); - - /* - // DOCS for TEXT_REPLACE: - // Each line under TEXT_REPLACE is a replacement, ie, the two entries will be - // considered equivalent. This is useful for USRs which vary across files. - - // DOCS for EXTRA_FLAGS: - // Additional flags to pass to clang. - - // DOCS for OUTPUT: - // If no name is given assume to be this file name. If there is not an output - // section for a file it is not checked. - - TEXT_REPLACE: - foo <===> bar - one <===> two - - EXTRA_FLAGS: - -std=c++14 - - OUTPUT: - {} - - OUTPUT: bar.cc - {} - - OUTPUT: bar.h - {} - */ -#endif - // Scan for EXTRA_FLAGS: { bool in_output = false; @@ -201,34 +161,6 @@ void DiffDocuments(std::string path, << "):" << std::endl; std::cout << joined_actual_output << std::endl; std::cout << std::endl; - - int max_diff = 5; - - size_t len = std::min(actual_output.size(), expected_output.size()); - for (size_t i = 0; i < len; ++i) { - if (actual_output[i] != expected_output[i]) { - if (--max_diff < 0) { - std::cout << "(... more lines may differ ...)" << std::endl; - break; - } - - std::cout << "Line " << i << " differs:" << std::endl; - std::cout << " expected: " << expected_output[i] << std::endl; - std::cout << " actual: " << actual_output[i] << std::endl; - } - } - - if (actual_output.size() > len) { - std::cout << "Additional output in actual:" << std::endl; - for (size_t i = len; i < actual_output.size(); ++i) - std::cout << " " << actual_output[i] << std::endl; - } - - if (expected_output.size() > len) { - std::cout << "Additional output in expected:" << std::endl; - for (size_t i = len; i < expected_output.size(); ++i) - std::cout << " " << expected_output[i] << std::endl; - } } void VerifySerializeToFrom(IndexFile* file) { @@ -322,9 +254,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { bool had_extra_flags = !flags.empty(); if (!AnyStartsWith(flags, "-x")) flags.push_back("-xc++"); - // Use c++14 by default, because MSVC STL is written assuming that. - if (!AnyStartsWith(flags, "-std")) - flags.push_back("-std=c++14"); flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); if (had_extra_flags) { std::cout << "For " << path << std::endl; diff --git a/src/timer.cc b/src/timer.cc index 94bc9cf58..96ec658cd 100644 --- a/src/timer.cc +++ b/src/timer.cc @@ -8,13 +8,9 @@ Timer::Timer() { long long Timer::ElapsedMicroseconds() const { std::chrono::time_point end = Clock::now(); - long long elapsed = elapsed_; - if (start_.has_value()) { - elapsed += - std::chrono::duration_cast(end - *start_) - .count(); - } - return elapsed; + return elapsed_ + + std::chrono::duration_cast(end - start_) + .count(); } long long Timer::ElapsedMicrosecondsAndReset() { @@ -38,25 +34,18 @@ void Timer::ResetAndPrint(const std::string& message) { } void Timer::Pause() { - assert(start_.has_value()); - std::chrono::time_point end = Clock::now(); long long elapsed = - std::chrono::duration_cast(end - *start_) + std::chrono::duration_cast(end - start_) .count(); elapsed_ += elapsed; - start_ = std::nullopt; } void Timer::Resume() { - assert(!start_.has_value()); start_ = Clock::now(); } -ScopedPerfTimer::ScopedPerfTimer(const std::string& message) - : message_(message) {} - ScopedPerfTimer::~ScopedPerfTimer() { timer_.ResetAndPrint(message_); } diff --git a/src/timer.h b/src/timer.h index 182da6713..061801db9 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,5 @@ #pragma once -#include - #include #include @@ -25,15 +23,14 @@ struct Timer { void Resume(); // Raw start time. - std::optional> start_; + std::chrono::time_point start_; // Elapsed time. - long long elapsed_ = 0; + long long elapsed_; }; struct ScopedPerfTimer { - ScopedPerfTimer(const std::string& message); ~ScopedPerfTimer(); - Timer timer_; std::string message_; + Timer timer_; }; From 46fc3b8323892518d8c1a39a8d02eef6e5b82dcf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 13:59:27 -0700 Subject: [PATCH 058/378] . --- CMakeLists.txt | 4 +- src/clang_indexer.cc | 4 +- src/clang_utils.cc | 8 +- src/command_line.cc | 6 +- src/config.cc | 3 + src/config.h | 3 +- src/file_consumer.cc | 2 +- src/include_complete.cc | 5 +- src/messages/ccls_did_view.cc | 40 -------- src/messages/ccls_wait.cc | 47 --------- src/messages/initialize.cc | 77 +-------------- src/messages/text_document_did_open.cc | 5 +- src/messages/text_document_formatting.cc | 62 ------------ src/platform_posix.cc | 2 +- src/port.cc | 2 +- src/port.h | 10 +- src/project.cc | 121 ++++++----------------- src/project.h | 9 +- src/query.h | 2 +- src/utils.cc | 8 ++ src/utils.h | 2 + src/work_thread.cc | 12 --- src/work_thread.h | 19 ---- 23 files changed, 74 insertions(+), 379 deletions(-) create mode 100644 src/config.cc delete mode 100644 src/messages/ccls_did_view.cc delete mode 100644 src/messages/ccls_wait.cc delete mode 100644 src/messages/text_document_formatting.cc delete mode 100644 src/work_thread.cc delete mode 100644 src/work_thread.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7768bd82b..d73ce893d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,6 +179,7 @@ target_sources(ccls PRIVATE src/clang_translation_unit.cc src/clang_utils.cc src/command_line.cc + src/config.cc src/diagnostics_engine.cc src/file_consumer.cc src/file_contents.cc @@ -209,7 +210,6 @@ target_sources(ccls PRIVATE src/timestamp_manager.cc src/type_printer.cc src/utils.cc - src/work_thread.cc src/working_files.cc) target_sources(ccls PRIVATE @@ -217,7 +217,6 @@ target_sources(ccls PRIVATE src/messages/ccls_call_hierarchy.cc src/messages/ccls_callers.cc src/messages/ccls_derived.cc - src/messages/ccls_did_view.cc src/messages/ccls_file_info.cc src/messages/ccls_freshen_index.cc src/messages/ccls_index_file.cc @@ -225,7 +224,6 @@ target_sources(ccls PRIVATE src/messages/ccls_member_hierarchy.cc src/messages/ccls_random.cc src/messages/ccls_vars.cc - src/messages/ccls_wait.cc src/messages/exit.cc src/messages/initialize.cc src/messages/shutdown.cc diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 2032056bf..f8950eac3 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -9,10 +9,10 @@ #include +#include #include #include #include -#include #include // TODO: See if we can use clang_indexLoc_getFileLocation to get a type ref on @@ -861,7 +861,7 @@ CXIdxClientFile OnIndexIncludedFile(CXClientData client_data, IndexInclude include; include.line = line; include.resolved_path = FileName(file->file); - if (!include.resolved_path.empty()) + if (include.resolved_path.size()) db->includes.push_back(include); return nullptr; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index cfd5ce6ac..20b55ff5f 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -1,5 +1,6 @@ #include "clang_utils.h" +#include "filesystem.hh" #include "platform.h" namespace { @@ -106,8 +107,11 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, std::string FileName(CXFile file) { CXString cx_name = clang_getFileName(file); - std::string name = ToString(cx_name); - return NormalizePath(name); + std::string ret = NormalizePath(ToString(cx_name)); + // Resolve /usr/include/c++/7.3.0 symlink. + if (!StartsWith(ret, g_config.projectRoot)) + ret = fs::canonical(ret); + return ret; } std::string ToString(CXString cx_string) { diff --git a/src/command_line.cc b/src/command_line.cc index eda149ee0..10027c347 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -22,7 +22,6 @@ #include "test.h" #include "timer.h" #include "timestamp_manager.h" -#include "work_thread.h" #include "working_files.h" #include @@ -35,7 +34,6 @@ #include #include #include -#include #include #include @@ -255,7 +253,7 @@ void LaunchStdinLoop(Config* config, // clients. std::cin.tie(nullptr); - WorkThread::StartThread("stdin", [request_times]() { + StartThread("stdin", [request_times]() { auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; @@ -295,7 +293,7 @@ void LaunchStdinLoop(Config* config, void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { - WorkThread::StartThread("stdout", [=]() { + StartThread("stdout", [=]() { auto* queue = QueueManager::instance(); while (true) { diff --git a/src/config.cc b/src/config.cc new file mode 100644 index 000000000..a98b1a1a9 --- /dev/null +++ b/src/config.cc @@ -0,0 +1,3 @@ +#include "config.h" + +Config g_config; diff --git a/src/config.h b/src/config.h index d7353f81a..5968b91c8 100644 --- a/src/config.h +++ b/src/config.h @@ -281,5 +281,4 @@ MAKE_REFLECT_STRUCT(Config, dumpAST); -// Expected client version. We show an error if this doesn't match. -constexpr const int kExpectedClientVersion = 3; +extern Config g_config; diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 3b1d6759a..c237c5b71 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -104,4 +104,4 @@ void FileConsumer::EmitError(CXFile file) const { LOG_S(ERROR) << "Could not get unique file id for " << file_name << " when parsing " << parse_file_; } -} \ No newline at end of file +} diff --git a/src/include_complete.cc b/src/include_complete.cc index dcbaf8bcb..2e2ef83e9 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -5,9 +5,6 @@ #include "project.h" #include "standard_includes.h" #include "timer.h" -#include "work_thread.h" - -#include namespace { @@ -116,7 +113,7 @@ void IncludeComplete::Rescan() { config_->completion.includeBlacklist); is_scanning = true; - WorkThread::StartThread("scan_includes", [this]() { + StartThread("scan_includes", [this]() { Timer timer; InsertStlIncludes(); diff --git a/src/messages/ccls_did_view.cc b/src/messages/ccls_did_view.cc deleted file mode 100644 index ece233b36..000000000 --- a/src/messages/ccls_did_view.cc +++ /dev/null @@ -1,40 +0,0 @@ -#include "clang_complete.h" -#include "message_handler.h" -#include "working_files.h" - -namespace { -MethodType kMethodType = "$ccls/textDocumentDidView"; - -struct In_CclsTextDocumentDidView : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - lsDocumentUri textDocumentUri; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_CclsTextDocumentDidView::Params, textDocumentUri); -MAKE_REFLECT_STRUCT(In_CclsTextDocumentDidView, params); -REGISTER_IN_MESSAGE(In_CclsTextDocumentDidView); - -struct Handler_CclsDidView - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsTextDocumentDidView* request) override { - std::string path = request->params.textDocumentUri.GetPath(); - - WorkingFile* working_file = working_files->GetFileByFilename(path); - if (!working_file) - return; - QueryFile* file = nullptr; - if (!FindFileOrFail(db, project, std::nullopt, path, &file)) - return; - - clang_complete->NotifyView(path); - if (file->def) { - EmitInactiveLines(working_file, file->def->inactive_regions); - EmitSemanticHighlighting(db, semantic_cache, working_file, file); - } - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsDidView); -} // namespace diff --git a/src/messages/ccls_wait.cc b/src/messages/ccls_wait.cc deleted file mode 100644 index 1e9c9b3be..000000000 --- a/src/messages/ccls_wait.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include "import_manager.h" -#include "import_pipeline.h" -#include "message_handler.h" -#include "queue_manager.h" - -#include - -namespace { -MethodType kMethodType = "$ccls/wait"; - -struct In_CclsWait : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } -}; -MAKE_REFLECT_EMPTY_STRUCT(In_CclsWait); -REGISTER_IN_MESSAGE(In_CclsWait); - -struct Handler_CclsWait : MessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(std::unique_ptr request) override { - // TODO: use status message system here, then run querydb as normal? Maybe - // this cannot be a normal message, ie, it needs to be re-entrant. - - LOG_S(INFO) << "Waiting for idle"; - int idle_count = 0; - while (true) { - bool has_work = false; - has_work |= import_pipeline_status->num_active_threads != 0; - has_work |= QueueManager::instance()->HasWork(); - has_work |= - QueryDb_ImportMain(config, db, import_manager, import_pipeline_status, - semantic_cache, working_files); - if (!has_work) - ++idle_count; - else - idle_count = 0; - - // There are race conditions between each of the three checks above, - // so we retry a bunch of times to try to avoid any. - if (idle_count > 10) - break; - } - LOG_S(INFO) << "Done waiting for idle"; - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsWait); -} // namespace diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index fd42cd342..d10b971aa 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -8,7 +8,6 @@ #include "queue_manager.h" #include "serializers/json.h" #include "timer.h" -#include "work_thread.h" #include "working_files.h" #include @@ -270,45 +269,13 @@ struct lsTextDocumentClientCapabilities { // The client supports the following `CompletionItem` specific // capabilities. std::optional completionItem; - }; - // Capabilities specific to the `textDocument/completion` - std::optional completion; + } completion; struct lsGenericDynamicReg { // Whether foo supports dynamic registration. std::optional dynamicRegistration; }; - // Capabilities specific to the `textDocument/hover` - std::optional hover; - - // Capabilities specific to the `textDocument/signatureHelp` - std::optional signatureHelp; - - // Capabilities specific to the `textDocument/references` - std::optional references; - - // Capabilities specific to the `textDocument/documentHighlight` - std::optional documentHighlight; - - // Capabilities specific to the `textDocument/documentSymbol` - std::optional documentSymbol; - - // Capabilities specific to the `textDocument/formatting` - std::optional formatting; - - // Capabilities specific to the `textDocument/rangeFormatting` - std::optional rangeFormatting; - - // Capabilities specific to the `textDocument/onTypeFormatting` - std::optional onTypeFormatting; - - // Capabilities specific to the `textDocument/definition` - std::optional definition; - - // Capabilities specific to the `textDocument/codeAction` - std::optional codeAction; - struct CodeLensRegistrationOptions : public lsGenericDynamicReg { // Code lens has a resolve provider as well. bool resolveProvider; @@ -317,9 +284,6 @@ struct lsTextDocumentClientCapabilities { // Capabilities specific to the `textDocument/codeLens` std::optional codeLens; - // Capabilities specific to the `textDocument/documentLink` - std::optional documentLink; - // Capabilities specific to the `textDocument/rename` std::optional rename; }; @@ -344,18 +308,6 @@ MAKE_REFLECT_STRUCT( MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, synchronization, completion, - hover, - signatureHelp, - references, - documentHighlight, - documentSymbol, - formatting, - rangeFormatting, - onTypeFormatting, - definition, - codeAction, - codeLens, - documentLink, rename); struct lsClientCapabilities { @@ -512,29 +464,9 @@ struct Handler_Initialize : BaseMessageHandler { // Client capabilities { const auto& cap = request->params.capabilities.textDocument; - if (cap.completion && cap.completion->completionItem) + if (cap.completion.completionItem) config->client.snippetSupport = - cap.completion->completionItem->snippetSupport.value_or(false); - } - - // Check client version. - if (config->clientVersion.has_value() && - *config->clientVersion != kExpectedClientVersion) { - Out_ShowLogMessage out; - out.display_type = Out_ShowLogMessage::DisplayType::Show; - out.params.type = lsMessageType::Error; - out.params.message = - "ccls client (v" + std::to_string(*config->clientVersion) + - ") and server (v" + std::to_string(kExpectedClientVersion) + - ") version mismatch. Please update "; - if (config->clientVersion > kExpectedClientVersion) - out.params.message += "the ccls binary."; - else - out.params.message += - "your extension client (VSIX file). Make sure to uninstall " - "the ccls extension and restart vscode before " - "reinstalling."; - out.Write(std::cout); + cap.completion.completionItem->snippetSupport.value_or(false); } // Ensure there is a resource directory. @@ -576,6 +508,7 @@ struct Handler_Initialize : BaseMessageHandler { MakeDirectoryRecursive(config->cacheDirectory + '@' + EscapeFileName(config->projectRoot)); + g_config = *config; Timer time; diag_engine->Init(config); semantic_cache->Init(config); @@ -599,7 +532,7 @@ struct Handler_Initialize : BaseMessageHandler { } LOG_S(INFO) << "Starting " << config->index.threads << " indexers"; for (int i = 0; i < config->index.threads; ++i) { - WorkThread::StartThread("indexer" + std::to_string(i), [=]() { + StartThread("indexer" + std::to_string(i), [=]() { Indexer_Main(config, diag_engine, file_consumer_shared, timestamp_manager, import_manager, import_pipeline_status, project, working_files, waiter); diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 7c10ebf8e..e1261c95b 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -72,9 +72,8 @@ struct Handler_TextDocumentDidOpen clang_complete->FlushSession(entry.filename); LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; - if (params.args.size()) { - project->SetFlagsForFile(params.args, path); - } + if (params.args.size()) + project->SetFlagsForFile(params.args, path); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); diff --git a/src/messages/text_document_formatting.cc b/src/messages/text_document_formatting.cc deleted file mode 100644 index 49290b545..000000000 --- a/src/messages/text_document_formatting.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "clang_format.h" -#include "message_handler.h" -#include "queue_manager.h" -#include "working_files.h" - -#include - -namespace { -MethodType kMethodType = "textDocument/formatting"; - -struct In_TextDocumentFormatting : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - lsTextDocumentIdentifier textDocument; - lsFormattingOptions options; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentFormatting::Params, textDocument, options); -MAKE_REFLECT_STRUCT(In_TextDocumentFormatting, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentFormatting); - -struct Out_TextDocumentFormatting - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentFormatting, jsonrpc, id, result); - -struct Handler_TextDocumentFormatting - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentFormatting* request) override { - Out_TextDocumentFormatting response; - response.id = request->id; -#if USE_CLANG_CXX - QueryFile* file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile* working_file = - working_files->GetFileByFilename(file->def->path); - - response.result = ConvertClangReplacementsIntoTextEdits( - working_file->buffer_content, - ClangFormatDocument(working_file, 0, - working_file->buffer_content.size(), - request->params.options)); -#else - LOG_S(WARNING) << "You must compile ccls with --use-clang-cxx to use " - "textDocument/formatting."; - // TODO: Fallback to execute the clang-format binary? - response.result = {}; -#endif - - QueueManager::WriteStdout(kMethodType, response); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); -} // namespace diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ad8613204..b03ec4b79 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -277,7 +277,7 @@ void TraceMe() { // If the environment variable is defined, wait for a debugger. // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. - if (getenv("CQUERY_TRACEME")) + if (getenv("CCLS_TRACEME")) raise(SIGTSTP); } diff --git a/src/port.cc b/src/port.cc index adb4cde65..d48df06ab 100644 --- a/src/port.cc +++ b/src/port.cc @@ -5,6 +5,6 @@ void ccls_unreachable_internal(const char* msg, const char* file, int line) { fprintf(stderr, "unreachable %s:%d %s\n", file, line, msg); - CQUERY_BUILTIN_UNREACHABLE; + CCLS_BUILTIN_UNREACHABLE; abort(); } diff --git a/src/port.h b/src/port.h index 5680bfa91..ef19d7724 100644 --- a/src/port.h +++ b/src/port.h @@ -12,17 +12,17 @@ // TODO GCC #if __has_builtin(__builtin_unreachable) -#define CQUERY_BUILTIN_UNREACHABLE __builtin_unreachable() +#define CCLS_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) -#define CQUERY_BUILTIN_UNREACHABLE __assume(false) +#define CCLS_BUILTIN_UNREACHABLE __assume(false) #else -#define CQUERY_BUILTIN_UNREACHABLE +#define CCLS_BUILTIN_UNREACHABLE #endif void ccls_unreachable_internal(const char* msg, const char* file, int line); #ifndef NDEBUG -#define CQUERY_UNREACHABLE(msg) \ +#define CCLS_UNREACHABLE(msg) \ ccls_unreachable_internal(msg, __FILE__, __LINE__) #else -#define CQUERY_UNREACHABLE(msg) +#define CCLS_UNREACHABLE(msg) #endif diff --git a/src/project.cc b/src/project.cc index 4ff67a2ad..fe1f88f3e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -2,6 +2,7 @@ #include "cache_manager.h" #include "clang_utils.h" +#include "filesystem.hh" #include "language.h" #include "match.h" #include "platform.h" @@ -27,41 +28,22 @@ #include #include -extern bool gTestOutputMode; - struct CompileCommandsEntry { - std::string directory; + fs::path directory; std::string file; std::string command; std::vector args; + + fs::path ResolveIfRelative(fs::path path) const { + if (path.is_absolute()) + return path; + return directory / path; + } }; MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); namespace { -bool g_disable_normalize_path_for_test = false; - -std::string NormalizePathWithTestOptOut(const std::string& path) { - if (g_disable_normalize_path_for_test) { - // Add a & so we can test to verify a path is normalized. - return "&" + path; - } - return NormalizePath(path); -} - -bool IsUnixAbsolutePath(const std::string& path) { - return !path.empty() && path[0] == '/'; -} - -bool IsWindowsAbsolutePath(const std::string& path) { - auto is_drive_letter = [](char c) { - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - }; - - return path.size() > 3 && path[1] == ':' && - (path[2] == '/' || path[2] == '\\') && is_drive_letter(path[0]); -} - enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; struct ProjectConfig { @@ -127,22 +109,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( Config* init_opts, ProjectConfig* config, const CompileCommandsEntry& entry) { - auto cleanup_maybe_relative_path = [&](const std::string& path) { - // TODO/FIXME: Normalization will fail for paths that do not exist. Should - // it return an std::optional? - assert(!path.empty()); - if (entry.directory.empty() || IsUnixAbsolutePath(path) || - IsWindowsAbsolutePath(path)) { - // We still want to normalize, as the path may contain .. characters. - return NormalizePathWithTestOptOut(path); - } - if (EndsWith(entry.directory, "/")) - return NormalizePathWithTestOptOut(entry.directory + path); - return NormalizePathWithTestOptOut(entry.directory + "/" + path); - }; - Project::Entry result; - result.filename = NormalizePathWithTestOptOut(entry.file); + result.filename = entry.file; const std::string base_name = GetBaseName(entry.file); // Expand %c %cpp %clang @@ -185,7 +153,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Add -working-directory if not provided. if (!AnyStartsWith(args, "-working-directory")) - result.args.emplace_back("-working-directory=" + entry.directory); + result.args.emplace_back("-working-directory=" + entry.directory.string()); bool next_flag_is_path = false; bool add_next_flag_to_quote_dirs = false; @@ -212,7 +180,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Finish processing path for the previous argument, which was a switch. // {"-I", "foo"} style. if (next_flag_is_path) { - std::string normalized_arg = cleanup_maybe_relative_path(arg); + std::string normalized_arg = entry.ResolveIfRelative(arg); if (add_next_flag_to_quote_dirs) config->quote_dirs.insert(normalized_arg); if (add_next_flag_to_angle_dirs) @@ -238,7 +206,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (StartsWith(arg, flag_type)) { std::string path = arg.substr(flag_type.size()); assert(!path.empty()); - path = cleanup_maybe_relative_path(path); + path = entry.ResolveIfRelative(path); if (clang_cl || StartsWithAny(arg, kNormalizePathArgs)) arg = flag_type + path; if (ShouldAddToQuoteIncludes(flag_type)) @@ -254,7 +222,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // slow. See // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. if (EndsWith(arg, base_name)) - arg = cleanup_maybe_relative_path(arg); + arg = entry.ResolveIfRelative(arg); // TODO Exclude .a .o to make link command in compile_commands.json work. // Also, clang_parseTranslationUnit2FullArgv does not seem to accept // multiple source filenames. @@ -450,13 +418,7 @@ std::vector LoadCompilationEntriesFromDirectory( our_time.Resume(); entry.directory = directory; - std::string absolute_filename; - if (IsUnixAbsolutePath(relative_filename) || - IsWindowsAbsolutePath(relative_filename)) - absolute_filename = relative_filename; - else - absolute_filename = directory + "/" + relative_filename; - entry.file = NormalizePathWithTestOptOut(absolute_filename); + entry.file = entry.ResolveIfRelative(relative_filename); result.push_back( GetCompilationEntryFromCompileCommandEntry(config, project, entry)); @@ -513,8 +475,8 @@ void Project::Load(Config* config, const std::string& root_directory) { } // Setup project entries. - absolute_path_to_entry_index_.resize(entries.size()); - for (int i = 0; i < entries.size(); ++i) + absolute_path_to_entry_index_.reserve(entries.size()); + for (size_t i = 0; i < entries.size(); ++i) absolute_path_to_entry_index_[entries[i].filename] = i; } @@ -616,9 +578,6 @@ TEST_SUITE("Project") { void CheckFlags(const std::string& directory, const std::string& file, std::vector raw, std::vector expected) { - g_disable_normalize_path_for_test = true; - gTestOutputMode = true; - Config config; ProjectConfig project; project.project_dir = "/w/c/s/"; @@ -656,7 +615,7 @@ TEST_SUITE("Project") { CheckFlags( /* raw */ {"clang", "-lstdc++", "myfile.cc"}, /* expected */ - {"clang", "-working-directory=/dir/", "-lstdc++", "&/dir/myfile.cc", + {"clang", "-working-directory=/dir/", "-lstdc++", "/dir/myfile.cc", "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); @@ -668,17 +627,18 @@ TEST_SUITE("Project") { "-fparse-all-comments"}); } +#ifdef _WIN32 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", + {"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", + {"clang", "-working-directory=E:/workdir", "E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); @@ -686,7 +646,7 @@ TEST_SUITE("Project") { /* raw */ {"clang-cl.exe", "/I./test", "E:/workdir/bar.cc"}, /* expected */ {"clang-cl.exe", "-working-directory=E:/workdir", - "/I&E:/workdir/./test", "&E:/workdir/bar.cc", + "/I&E:/workdir/./test", "E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); @@ -696,28 +656,20 @@ TEST_SUITE("Project") { /* expected */ {"cl.exe", "-working-directory=E:/workdir", "/I&E:/workdir/../third_party/test/include", - "&E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/", + "E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); } +#endif 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/", + "/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"}); - } - TEST_CASE("Directory extraction") { Config init_opts; ProjectConfig config; @@ -752,11 +704,11 @@ TEST_SUITE("Project") { GetCompilationEntryFromCompileCommandEntry(&init_opts, &config, entry); std::unordered_set angle_expected{ - "&/a_absolute1", "&/a_absolute2", "&/base/a_relative1", - "&/base/a_relative2"}; + "/a_absolute1", "/a_absolute2", "/base/a_relative1", + "/base/a_relative2"}; std::unordered_set quote_expected{ - "&/q_absolute1", "&/q_absolute2", "&/base/q_relative1", - "&/base/q_relative2"}; + "/q_absolute1", "/q_absolute2", "/base/q_relative1", + "/base/q_relative2"}; REQUIRE(config.angle_dirs == angle_expected); REQUIRE(config.quote_dirs == quote_expected); } @@ -817,23 +769,6 @@ TEST_SUITE("Project") { } } - TEST_CASE("IsWindowsAbsolutePath works correctly") { - REQUIRE(IsWindowsAbsolutePath("C:/Users/projects/")); - REQUIRE(IsWindowsAbsolutePath("C:/Users/projects")); - REQUIRE(IsWindowsAbsolutePath("C:/Users/projects")); - REQUIRE(IsWindowsAbsolutePath("C:\\Users\\projects")); - REQUIRE(IsWindowsAbsolutePath("C:\\\\Users\\\\projects")); - REQUIRE(IsWindowsAbsolutePath("c:\\\\Users\\\\projects")); - REQUIRE(IsWindowsAbsolutePath("A:\\\\Users\\\\projects")); - - REQUIRE(!IsWindowsAbsolutePath("C:/")); - REQUIRE(!IsWindowsAbsolutePath("../abc/test")); - REQUIRE(!IsWindowsAbsolutePath("5:/test")); - REQUIRE(!IsWindowsAbsolutePath("ccls/project/file.cc")); - REQUIRE(!IsWindowsAbsolutePath("")); - REQUIRE(!IsWindowsAbsolutePath("/etc/linux/path")); - } - TEST_CASE("Entry inference prefers same file endings") { Project p; { diff --git a/src/project.h b/src/project.h index 18e7bbd84..71fbd19af 100644 --- a/src/project.h +++ b/src/project.h @@ -3,13 +3,12 @@ #include "config.h" #include "method.h" -#include -#include -#include - #include #include +#include #include +#include +#include #include class QueueManager; @@ -29,7 +28,7 @@ struct Project { std::vector angle_include_directories; std::vector entries; - spp::sparse_hash_map absolute_path_to_entry_index_; + std::unordered_map absolute_path_to_entry_index_; // Loads a project for the given |directory|. // diff --git a/src/query.h b/src/query.h index 9fb8fcd90..0ff4f3ef2 100644 --- a/src/query.h +++ b/src/query.h @@ -270,7 +270,7 @@ struct QueryDatabase { std::vector vars; // Lookup symbol based on a usr. - spp::sparse_hash_map usr_to_file; + std::unordered_map usr_to_file; spp::sparse_hash_map usr_to_type; spp::sparse_hash_map usr_to_func; spp::sparse_hash_map usr_to_var; diff --git a/src/utils.cc b/src/utils.cc index 59b1c28d4..593cf0a81 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include using namespace std::placeholders; @@ -277,6 +278,13 @@ std::string GetDefaultResourceDirectory() { return NormalizePath(result); } +void StartThread(const std::string& thread_name, std::function entry) { + new std::thread([thread_name, entry]() { + SetCurrentThreadName(thread_name); + entry(); + }); +} + TEST_SUITE("StripFileType") { TEST_CASE("all") { REQUIRE(StripFileType("") == ""); diff --git a/src/utils.h b/src/utils.h index 16685885a..baba2774b 100644 --- a/src/utils.h +++ b/src/utils.h @@ -149,3 +149,5 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { } std::string GetDefaultResourceDirectory(); + +void StartThread(const std::string& thread_name, std::function entry); diff --git a/src/work_thread.cc b/src/work_thread.cc deleted file mode 100644 index b627485fd..000000000 --- a/src/work_thread.cc +++ /dev/null @@ -1,12 +0,0 @@ -#include "work_thread.h" - -#include "platform.h" - -// static -void WorkThread::StartThread(const std::string& thread_name, - std::function entry_point) { - new std::thread([thread_name, entry_point]() { - SetCurrentThreadName(thread_name); - entry_point(); - }); -} \ No newline at end of file diff --git a/src/work_thread.h b/src/work_thread.h deleted file mode 100644 index d11c237a7..000000000 --- a/src/work_thread.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -// Helper methods for starting threads that do some work. Enables test code to -// wait for all work to complete. -struct WorkThread { - // Launch a new thread. |entry_point| will be called continously. It should - // return true if it there is still known work to be done. - static void StartThread(const std::string& thread_name, - std::function entry_point); - - // Static-only class. - WorkThread() = delete; -}; \ No newline at end of file From d8fbc752d04aefc6d9ce1d047e1aa2dc623e8d68 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 31 Mar 2018 17:49:32 -0700 Subject: [PATCH 059/378] . --- src/cache_manager.cc | 26 +++++++++---------- src/cache_manager.h | 2 +- src/messages/ccls_freshen_index.cc | 2 +- src/messages/ccls_index_file.cc | 2 +- src/messages/text_document_did_change.cc | 2 +- src/messages/text_document_did_open.cc | 2 +- src/messages/text_document_did_save.cc | 2 +- .../workspace_did_change_watched_files.cc | 4 +-- src/project.cc | 6 ++--- 9 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 2c23f26c7..0fc06613f 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -14,14 +14,14 @@ namespace { // Manages loading caches from file paths for the indexer process. struct RealCacheManager : ICacheManager { - explicit RealCacheManager(Config* config) : config_(config) {} + explicit RealCacheManager() {} ~RealCacheManager() override = default; void WriteToCache(IndexFile& file) override { std::string cache_path = GetCachePath(file.path); WriteToFile(cache_path, file.file_contents); - std::string indexed_content = Serialize(config_->cacheFormat, file); + std::string indexed_content = Serialize(g_config.cacheFormat, file); WriteToFile(AppendSerializationFormat(cache_path), indexed_content); } @@ -38,27 +38,27 @@ struct RealCacheManager : ICacheManager { if (!file_content || !serialized_indexed_content) return nullptr; - return Deserialize(config_->cacheFormat, path, *serialized_indexed_content, + return Deserialize(g_config.cacheFormat, path, *serialized_indexed_content, *file_content, IndexFile::kMajorVersion); } std::string GetCachePath(const std::string& source_file) { - assert(!config_->cacheDirectory.empty()); + assert(!g_config.cacheDirectory.empty()); std::string cache_file; - size_t len = config_->projectRoot.size(); - if (StartsWith(source_file, config_->projectRoot)) { - cache_file = EscapeFileName(config_->projectRoot) + + size_t len = g_config.projectRoot.size(); + if (StartsWith(source_file, g_config.projectRoot)) { + cache_file = EscapeFileName(g_config.projectRoot) + EscapeFileName(source_file.substr(len)); } else { - cache_file = '@' + EscapeFileName(config_->projectRoot) + + cache_file = '@' + EscapeFileName(g_config.projectRoot) + EscapeFileName(source_file); } - return config_->cacheDirectory + cache_file; + return g_config.cacheDirectory + cache_file; } std::string AppendSerializationFormat(const std::string& base) { - switch (config_->cacheFormat) { + switch (g_config.cacheFormat) { case SerializeFormat::Json: return base + ".json"; case SerializeFormat::MessagePack: @@ -67,8 +67,6 @@ struct RealCacheManager : ICacheManager { assert(false); return ".json"; } - - Config* config_; }; struct FakeCacheManager : ICacheManager { @@ -105,8 +103,8 @@ struct FakeCacheManager : ICacheManager { } // namespace // static -std::shared_ptr ICacheManager::Make(Config* config) { - return std::make_shared(config); +std::shared_ptr ICacheManager::Make() { + return std::make_shared(); } // static diff --git a/src/cache_manager.h b/src/cache_manager.h index f175544b7..0904f0981 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -18,7 +18,7 @@ struct ICacheManager { std::string json; }; - static std::shared_ptr Make(Config* config); + static std::shared_ptr Make(); static std::shared_ptr MakeFake( const std::vector& entries); diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 8e25a7b2b..b56701db3 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -40,7 +40,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { GroupMatch matcher(request->params.whitelist, request->params.blacklist); // Unmark all files whose timestamp has changed. - std::shared_ptr cache_manager = ICacheManager::Make(config); + std::shared_ptr cache_manager = ICacheManager::Make(); std::queue q; // |need_index| stores every filename ever enqueued. diff --git a/src/messages/ccls_index_file.cc b/src/messages/ccls_index_file.cc index 4dfac6967..0e4ecd860 100644 --- a/src/messages/ccls_index_file.cc +++ b/src/messages/ccls_index_file.cc @@ -33,7 +33,7 @@ struct Handler_CclsIndexFile : BaseMessageHandler { QueueManager::instance()->index_request.PushBack( Index_Request(NormalizePath(request->params.path), request->params.args, request->params.is_interactive, request->params.contents, - ICacheManager::Make(config))); + ICacheManager::Make())); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsIndexFile); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 95be3ab57..4f978bc36 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -33,7 +33,7 @@ struct Handler_TextDocumentDidChange Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content, ICacheManager::Make(config)), + *content, ICacheManager::Make()), true); } } diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index e1261c95b..06c83fa2e 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -41,7 +41,7 @@ struct Handler_TextDocumentDidOpen Timer time; std::string path = params.textDocument.uri.GetPath(); - std::shared_ptr cache_manager = ICacheManager::Make(config); + std::shared_ptr cache_manager = ICacheManager::Make(); WorkingFile* working_file = working_files->OnOpen(params.textDocument); std::optional cached_file_contents = cache_manager->LoadCachedFileContents(path); diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 57a3310be..9596ddb43 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -55,7 +55,7 @@ struct Handler_TextDocumentDidSave Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content, ICacheManager::Make(config)), + *content, ICacheManager::Make()), true); } } diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index ac2a1bd19..19b4ad13b 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -56,7 +56,7 @@ struct Handler_WorkspaceDidChangeWatchedFiles else { QueueManager::instance()->index_request.PushBack( Index_Request(path, entry.args, is_interactive, *content, - ICacheManager::Make(config))); + ICacheManager::Make())); if (is_interactive) clang_complete->NotifySave(path); } @@ -65,7 +65,7 @@ struct Handler_WorkspaceDidChangeWatchedFiles case lsFileChangeType::Deleted: QueueManager::instance()->index_request.PushBack( Index_Request(path, entry.args, is_interactive, std::string(), - ICacheManager::Make(config))); + ICacheManager::Make())); break; } } diff --git a/src/project.cc b/src/project.cc index fe1f88f3e..7357557d7 100644 --- a/src/project.cc +++ b/src/project.cc @@ -568,9 +568,9 @@ void Project::Index(Config* config, return; } bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - queue->index_request.PushBack( - Index_Request(entry.filename, entry.args, is_interactive, *content, - ICacheManager::Make(config), id)); + queue->index_request.PushBack(Index_Request(entry.filename, entry.args, + is_interactive, *content, + ICacheManager::Make(), id)); }); } From 78250bde34feaee344019abf87ad7d49e6ec7bb9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 1 Apr 2018 20:55:10 -0700 Subject: [PATCH 060/378] Fuzzy --- CMakeLists.txt | 2 +- src/fuzzy_match.cc | 10 ++++++++-- src/platform_posix.cc | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d73ce893d..861258091 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ add_executable(ccls "") # debug: -g # release: -O3 -DNDEBUG -# Enable C++14 (Required) +# Enable C++17 (Required) set_property(TARGET ccls PROPERTY CXX_STANDARD 17) set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) # Disable gnu extensions except for Cygwin which needs them to build properly diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 6e271665d..006290d57 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -46,7 +46,9 @@ void CalculateRoles(std::string_view s, int roles[], int* class_set) { } // namespace int FuzzyMatcher::MissScore(int j, bool last) { - int s = last ? -10 : 0; + int s = -3; + if (last) + s -= 10; if (text_role[j] == Head) s -= 10; return s; @@ -54,8 +56,10 @@ int FuzzyMatcher::MissScore(int j, bool last) { int FuzzyMatcher::MatchScore(int i, int j, bool last) { int s = 0; + // Case matching. if (pat[i] == text[j]) { s++; + // pat contains uppercase letters or prefix matching. if ((pat_set & 1 << Upper) || i == j) s++; } @@ -65,8 +69,10 @@ int FuzzyMatcher::MatchScore(int i, int j, bool last) { else if (text_role[j] == Tail) s -= 10; } + // Matching a tail while previous char wasn't matched. if (text_role[j] == Tail && i && !last) s -= 30; + // First char of pat matches a tail. if (i == 0 && text_role[j] == Tail) s -= 40; return s; @@ -119,7 +125,7 @@ int FuzzyMatcher::Match(std::string_view text) { // character has a penulty. int ret = kMinScore; for (int j = pat.size(); j <= n; j++) - ret = std::max(ret, dp[pat.size() & 1][j][1] - 3 * (n - j)); + ret = std::max(ret, dp[pat.size() & 1][j][1] - 2 * (n - j)); return ret; } diff --git a/src/platform_posix.cc b/src/platform_posix.cc index b03ec4b79..d41cee680 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -284,9 +284,12 @@ void TraceMe() { std::string GetExternalCommandOutput(const std::vector& command, std::string_view input) { int pin[2], pout[2]; - if (pipe(pin) < 0) + if (pipe(pin) < 0) { + perror("pipe(stdin)"); return ""; + } if (pipe(pout) < 0) { + perror("pipe(stdout)"); close(pin[0]); close(pin[1]); return ""; @@ -316,6 +319,7 @@ std::string GetExternalCommandOutput(const std::vector& command, ssize_t n; while ((n = read(pin[0], buf, sizeof buf)) > 0) ret.append(buf, n); + close(pin[0]); waitpid(child, NULL, 0); return ret; } From c0b4d69268825b577eda3e3b96c462072e295847 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 2 Apr 2018 00:22:12 -0700 Subject: [PATCH 061/378] Simplify optional. --- src/clang_indexer.cc | 12 ++++++------ src/iindexer.cc | 8 ++++---- src/iindexer.h | 2 +- src/import_pipeline.cc | 10 +++++----- src/indexer.h | 4 ++-- src/test.cc | 3 +-- 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index f8950eac3..489eed31a 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -2153,7 +2153,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } } -std::optional>> Parse( +std::vector> Parse( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -2163,7 +2163,7 @@ std::optional>> Parse( ClangIndex* index, bool dump_ast) { if (!config->index.enabled) - return std::nullopt; + return {}; file = NormalizePath(file); @@ -2183,7 +2183,7 @@ std::optional>> Parse( CXTranslationUnit_KeepGoing | CXTranslationUnit_DetailedPreprocessingRecord); if (!tu) - return std::nullopt; + return {}; perf->index_parse = timer.ElapsedMicrosecondsAndReset(); @@ -2194,7 +2194,7 @@ std::optional>> Parse( args, unsaved_files); } -std::optional>> ParseWithTu( +std::vector> ParseWithTu( Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, @@ -2239,7 +2239,7 @@ std::optional>> ParseWithTu( if (index_result != CXError_Success) { LOG_S(ERROR) << "Indexing " << file << " failed with errno=" << index_result; - return std::nullopt; + return {}; } clang_IndexAction_dispose(index_action); @@ -2301,7 +2301,7 @@ std::optional>> ParseWithTu( entry->dependencies.end()); } - return std::move(result); + return result; } void ConcatTypeAndName(std::string& type, const std::string& name) { diff --git a/src/iindexer.cc b/src/iindexer.cc index 16085bc38..1c77005d9 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -6,7 +6,7 @@ namespace { struct ClangIndexer : IIndexer { ~ClangIndexer() override = default; - std::optional>> Index( + std::vector> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -50,7 +50,7 @@ struct TestIndexer : IIndexer { ~TestIndexer() override = default; - std::optional>> Index( + std::vector> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -61,14 +61,14 @@ struct TestIndexer : IIndexer { if (it == indexes.end()) { // Don't return any indexes for unexpected data. assert(false && "no indexes"); - return std::nullopt; + return {}; } // FIXME: allow user to control how many times we return the index for a // specific file (atm it is always 1) auto result = std::move(it->second); indexes.erase(it); - return std::move(result); + return result; } std::unordered_map>> diff --git a/src/iindexer.h b/src/iindexer.h index d66489906..df0e2d8b0 100644 --- a/src/iindexer.h +++ b/src/iindexer.h @@ -34,7 +34,7 @@ struct IIndexer { std::initializer_list entries); virtual ~IIndexer() = default; - virtual std::optional>> Index( + virtual std::vector> Index( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 8f53c8c09..9e0eb3468 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -393,7 +393,7 @@ void ParseFile(Config* config, auto indexes = indexer->Index(config, file_consumer_shared, path_to_index, entry.args, file_contents, &perf); - if (!indexes) { + if (indexes.empty()) { if (config->index.enabled && !std::holds_alternative(request.id)) { Out_Error out; @@ -405,7 +405,7 @@ void ParseFile(Config* config, return; } - for (std::unique_ptr& new_index : *indexes) { + for (std::unique_ptr& new_index : indexes) { Timer time; // Only emit diagnostics for non-interactive sessions, which makes it easier @@ -556,11 +556,11 @@ void IndexWithTuFromCodeCompletion( ClangIndex index; auto indexes = ParseWithTu(config, file_consumer_shared, &perf, tu, &index, path, args, file_contents); - if (!indexes) - return; + if (indexes.empty()) + return; std::vector result; - for (std::unique_ptr& new_index : *indexes) { + for (std::unique_ptr& new_index : indexes) { Timer time; std::shared_ptr cache_manager; diff --git a/src/indexer.h b/src/indexer.h index e52ddb3d5..8857c2bdb 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -517,7 +517,7 @@ struct NamespaceHelper { // |desired_index_file| is the (h or cc) file which has actually changed. // |dependencies| are the existing dependencies of |import_file| if this is a // reparse. -std::optional>> Parse( +std::vector> Parse( Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, @@ -526,7 +526,7 @@ std::optional>> Parse( PerformanceImportFile* perf, ClangIndex* index, bool dump_ast = false); -std::optional>> ParseWithTu( +std::vector> ParseWithTu( Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, diff --git a/src/test.cc b/src/test.cc index 266ab030d..07d083bc1 100644 --- a/src/test.cc +++ b/src/test.cc @@ -267,7 +267,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { PerformanceImportFile perf; auto dbs = Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index, false /*dump_ast*/); - assert(dbs); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; @@ -298,7 +297,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { }; // Get output from index operation. - IndexFile* db = FindDbForPathEnding(expected_path, *dbs); + IndexFile* db = FindDbForPathEnding(expected_path, dbs); assert(db); if (!db->diagnostics_.empty()) { std::cout << "For " << path << std::endl; From d9bcaecf25fdd72c3f7a6b59d731b6988f98ecda Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 3 Apr 2018 23:05:41 -0700 Subject: [PATCH 062/378] Use global config. --- src/cache_manager.cc | 20 ++-- src/clang_complete.cc | 22 ++--- src/clang_complete.h | 5 +- src/clang_indexer.cc | 34 +++---- src/clang_utils.cc | 2 +- src/command_line.cc | 29 +++--- src/config.cc | 2 +- src/config.h | 14 +-- src/diagnostics_engine.cc | 8 +- src/diagnostics_engine.h | 2 +- src/fuzzy_match.cc | 2 +- src/iindexer.cc | 6 +- src/iindexer.h | 2 - src/import_pipeline.cc | 50 +++++----- src/import_pipeline.h | 8 +- src/include_complete.cc | 43 +++++---- src/include_complete.h | 3 +- src/indexer.h | 2 - src/lex_utils.cc | 1 - src/lsp.cc | 1 - src/message_handler.cc | 6 +- src/message_handler.h | 3 +- src/messages/ccls_base.cc | 10 +- src/messages/ccls_callers.cc | 4 +- src/messages/ccls_derived.cc | 10 +- src/messages/ccls_freshen_index.cc | 3 +- src/messages/ccls_random.cc | 10 +- src/messages/ccls_vars.cc | 5 +- src/messages/initialize.cc | 31 +++---- src/messages/text_document_code_lens.cc | 2 +- src/messages/text_document_completion.cc | 14 +-- src/messages/text_document_definition.cc | 6 +- src/messages/text_document_did_change.cc | 2 +- src/messages/text_document_did_save.cc | 2 +- src/messages/text_document_references.cc | 6 +- src/messages/text_document_type_definition.cc | 2 +- .../workspace_did_change_configuration.cc | 5 +- src/messages/workspace_symbol.cc | 12 +-- src/project.cc | 92 ++++++++----------- src/project.h | 8 +- src/query_utils.cc | 11 +-- src/query_utils.h | 4 +- src/test.cc | 6 +- 43 files changed, 211 insertions(+), 299 deletions(-) diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 0fc06613f..19e7bb59c 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -21,7 +21,7 @@ struct RealCacheManager : ICacheManager { std::string cache_path = GetCachePath(file.path); WriteToFile(cache_path, file.file_contents); - std::string indexed_content = Serialize(g_config.cacheFormat, file); + std::string indexed_content = Serialize(g_config->cacheFormat, file); WriteToFile(AppendSerializationFormat(cache_path), indexed_content); } @@ -38,34 +38,32 @@ struct RealCacheManager : ICacheManager { if (!file_content || !serialized_indexed_content) return nullptr; - return Deserialize(g_config.cacheFormat, path, *serialized_indexed_content, + return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, *file_content, IndexFile::kMajorVersion); } std::string GetCachePath(const std::string& source_file) { - assert(!g_config.cacheDirectory.empty()); + assert(!g_config->cacheDirectory.empty()); std::string cache_file; - size_t len = g_config.projectRoot.size(); - if (StartsWith(source_file, g_config.projectRoot)) { - cache_file = EscapeFileName(g_config.projectRoot) + + size_t len = g_config->projectRoot.size(); + if (StartsWith(source_file, g_config->projectRoot)) { + cache_file = EscapeFileName(g_config->projectRoot) + EscapeFileName(source_file.substr(len)); } else { - cache_file = '@' + EscapeFileName(g_config.projectRoot) + + cache_file = '@' + EscapeFileName(g_config->projectRoot) + EscapeFileName(source_file); } - return g_config.cacheDirectory + cache_file; + return g_config->cacheDirectory + cache_file; } std::string AppendSerializationFormat(const std::string& base) { - switch (g_config.cacheFormat) { + switch (g_config->cacheFormat) { case SerializeFormat::Json: return base + ".json"; case SerializeFormat::MessagePack: return base + ".mpack"; } - assert(false); - return ".json"; } }; diff --git a/src/clang_complete.cc b/src/clang_complete.cc index d76dbf817..465df0422 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -383,7 +383,7 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, unsaved, Flags()); // Build diagnostics. - if (manager->config_->diagnostics.onParse && *tu) { + if (g_config->diagnostics.onParse && *tu) { // If we're emitting diagnostics, do an immediate reparse, otherwise we will // emit stale/bad diagnostics. *tu = ClangTranslationUnit::Reparse(std::move(*tu), unsaved); @@ -450,7 +450,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { completion_manager->completion_request_.Dequeue(); // Drop older requests if we're not buffering. - while (completion_manager->config_->completion.dropOldRequests && + while (g_config->completion.dropOldRequests && !completion_manager->completion_request_.IsEmpty()) { completion_manager->on_dropped_(request->id); request = completion_manager->completion_request_.Dequeue(); @@ -528,7 +528,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { clang_getCompletionBriefComment(result.CompletionString)); // label/detail/filterText/insertText/priority - if (completion_manager->config_->completion.detailedLabel) { + if (g_config->completion.detailedLabel) { ls_completion_item.detail = ToString( clang_getCompletionParent(result.CompletionString, nullptr)); @@ -538,10 +538,10 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { // label/filterText/insertText BuildCompletionItemTexts( ls_result, result.CompletionString, - completion_manager->config_->client.snippetSupport); + g_config->client.snippetSupport); for (auto i = first_idx; i < ls_result.size(); ++i) { - if (completion_manager->config_->client.snippetSupport && + if (g_config->client.snippetSupport && ls_result[i].insertTextFormat == lsInsertTextFormat::Snippet) { ls_result[i].insertText += "$0"; @@ -558,8 +558,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { ls_completion_item.detail, ls_completion_item.insertText, do_insert, ls_completion_item.insertTextFormat, &ls_completion_item.parameters_, - completion_manager->config_->client.snippetSupport); - if (completion_manager->config_->client.snippetSupport && + g_config->client.snippetSupport); + if (g_config->client.snippetSupport && ls_completion_item.insertTextFormat == lsInsertTextFormat::Snippet) { ls_completion_item.insertText += "$0"; @@ -658,14 +658,12 @@ ClangCompleteManager::CompletionRequest::CompletionRequest( on_complete(on_complete), emit_diagnostics(emit_diagnostics) {} -ClangCompleteManager::ClangCompleteManager(Config* config, - Project* project, +ClangCompleteManager::ClangCompleteManager(Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic, OnIndex on_index, OnDropped on_dropped) - : config_(config), - project_(project), + : project_(project), working_files_(working_files), on_diagnostic_(on_diagnostic), on_index_(on_index), @@ -683,8 +681,6 @@ ClangCompleteManager::ClangCompleteManager(Config* config, }); } -ClangCompleteManager::~ClangCompleteManager() {} - void ClangCompleteManager::CodeComplete( const lsRequestId& id, const lsTextDocumentPositionParams& completion_location, diff --git a/src/clang_complete.h b/src/clang_complete.h index 8080c0e5b..015609a8b 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -72,13 +72,11 @@ struct ClangCompleteManager { bool emit_diagnostics = false; }; - ClangCompleteManager(Config* config, - Project* project, + ClangCompleteManager(Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic, OnIndex on_index, OnDropped on_dropped); - ~ClangCompleteManager(); // Start a code completion at the given location. |on_complete| will run when // completion results are available. |on_complete| may run on any thread. @@ -120,7 +118,6 @@ struct ClangCompleteManager { const int kMaxCompletionSessions = 5; // Global state. - Config* config_; Project* project_; WorkingFiles* working_files_; OnDiagnostic on_diagnostic_; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 489eed31a..fac4d7401 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -13,7 +13,6 @@ #include #include #include -#include // TODO: See if we can use clang_indexLoc_getFileLocation to get a type ref on // |Foobar| in DISALLOW_COPY(Foobar) @@ -279,8 +278,6 @@ struct ConstructorCache { }; struct IndexParam { - Config* config = nullptr; - std::unordered_set seen_cx_files; std::vector seen_files; FileContentsMap file_contents; @@ -300,10 +297,9 @@ struct IndexParam { NamespaceHelper ns; ConstructorCache ctors; - IndexParam(Config* config, - ClangTranslationUnit* tu, + IndexParam(ClangTranslationUnit* tu, FileConsumer* file_consumer) - : config(config), tu(tu), file_consumer(file_consumer) {} + : tu(tu), file_consumer(file_consumer) {} #if CINDEX_HAVE_PRETTY CXPrintingPolicy print_policy = nullptr; @@ -585,7 +581,7 @@ void SetVarDetail(IndexVar* var, // string. Shorten it to just "lambda". if (type_name.find("(lambda at") != std::string::npos) type_name = "lambda"; - if (param->config->index.comments) + if (g_config->index.comments) def.comments = cursor.get_comments(); def.storage = GetStorageClass(clang_Cursor_getStorageClass(cursor.cx_cursor)); @@ -870,10 +866,8 @@ CXIdxClientFile OnIndexIncludedFile(CXClientData client_data, ClangCursor::VisitResult DumpVisitor(ClangCursor cursor, ClangCursor parent, int* level) { - for (int i = 0; i < *level; ++i) - std::cerr << " "; - std::cerr << ToString(cursor.get_kind()) << " " << cursor.get_spell_name() - << std::endl; + fprintf(stderr, "%*s%s %s\n", *level * 2, "", + ToString(cursor.get_kind()).c_str(), cursor.get_spell_name().c_str()); *level += 1; cursor.VisitChildren(&DumpVisitor, level); @@ -1248,7 +1242,7 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, var_def->def.hover = "#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent); var_def->def.kind = lsSymbolKind::Macro; - if (param->config->index.comments) + if (g_config->index.comments) var_def->def.comments = cursor.get_comments(); var_def->def.spell = SetUse(db, decl_loc_spelling, parent, Role::Definition); @@ -1615,7 +1609,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { IndexFuncId func_id = db->ToFuncId(decl_cursor_resolved.cx_cursor); IndexFunc* func = db->Resolve(func_id); - if (param->config->index.comments) + if (g_config->index.comments) func->def.comments = cursor.get_comments(); func->def.kind = GetSymbolKind(decl->entityInfo->kind); func->def.storage = @@ -1763,7 +1757,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetTypeName(type, decl_cursor, decl->semanticContainer, decl->entityInfo->name, param); type->def.kind = GetSymbolKind(decl->entityInfo->kind); - if (param->config->index.comments) + if (g_config->index.comments) type->def.comments = decl_cursor.get_comments(); // For Typedef/CXXTypeAlias spanning a few lines, display the declaration @@ -1808,7 +1802,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, param); type->def.kind = GetSymbolKind(decl->entityInfo->kind); - if (param->config->index.comments) + if (g_config->index.comments) type->def.comments = cursor.get_comments(); // } @@ -2099,7 +2093,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { bool is_template = ref->referencedEntity->templateKind != CXIdxEntityCXXTemplateKind::CXIdxEntity_NonTemplate; - if (param->config->index.attributeMakeCallsToCtor && is_template && + if (g_config->index.attributeMakeCallsToCtor && is_template && str_begin("make", ref->referencedEntity->name)) { // Try to find the return type of called function. That type will have // the constructor function we add a usage to. @@ -2154,7 +2148,6 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } std::vector> Parse( - Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, const std::vector& args, @@ -2162,7 +2155,7 @@ std::vector> Parse( PerformanceImportFile* perf, ClangIndex* index, bool dump_ast) { - if (!config->index.enabled) + if (!g_config->index.enabled) return {}; file = NormalizePath(file); @@ -2190,12 +2183,11 @@ std::vector> Parse( if (dump_ast) Dump(clang_getTranslationUnitCursor(tu->cx_tu)); - return ParseWithTu(config, file_consumer_shared, perf, tu.get(), index, file, + return ParseWithTu(file_consumer_shared, perf, tu.get(), index, file, args, unsaved_files); } std::vector> ParseWithTu( - Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, ClangTranslationUnit* tu, @@ -2218,7 +2210,7 @@ std::vector> ParseWithTu( callback.indexEntityReference = &OnIndexReference; FileConsumer file_consumer(file_consumer_shared, file); - IndexParam param(config, tu, &file_consumer); + IndexParam param(tu, &file_consumer); for (const CXUnsavedFile& contents : file_contents) { param.file_contents[contents.Filename] = FileContents( contents.Filename, std::string(contents.Contents, contents.Length)); diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 20b55ff5f..4a62db7df 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -109,7 +109,7 @@ std::string FileName(CXFile file) { CXString cx_name = clang_getFileName(file); std::string ret = NormalizePath(ToString(cx_name)); // Resolve /usr/include/c++/7.3.0 symlink. - if (!StartsWith(ret, g_config.projectRoot)) + if (!StartsWith(ret, g_config->projectRoot)) ret = fs::canonical(ret); return ret; } diff --git a/src/command_line.cc b/src/command_line.cc index 10027c347..215290ea0 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -110,8 +110,7 @@ See more on https://github.com/MaskRay/ccls/wiki // QUERYDB MAIN //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -bool QueryDbMainLoop(Config* config, - QueryDatabase* db, +bool QueryDbMainLoop(QueryDatabase* db, MultiQueueWaiter* waiter, Project* project, FileConsumerSharedState* file_consumer_shared, @@ -147,7 +146,7 @@ bool QueryDbMainLoop(Config* config, // TODO: consider rate-limiting and checking for IPC messages so we don't // block requests / we can serve partial requests. - if (QueryDb_ImportMain(config, db, import_manager, status, semantic_cache, + if (QueryDb_ImportMain(db, import_manager, status, semantic_cache, working_files)) { did_work = true; } @@ -156,7 +155,6 @@ bool QueryDbMainLoop(Config* config, } void RunQueryDbThread(const std::string& bin_name, - Config* config, MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter) { Project project; @@ -166,14 +164,14 @@ void RunQueryDbThread(const std::string& bin_name, DiagnosticsEngine diag_engine; ClangCompleteManager clang_complete( - config, &project, &working_files, + &project, &working_files, [&](std::string path, std::vector diagnostics) { diag_engine.Publish(&working_files, path, diagnostics); }, [&](ClangTranslationUnit* tu, const std::vector& unsaved, const std::string& path, const std::vector& args) { - IndexWithTuFromCodeCompletion(config, &file_consumer_shared, tu, - unsaved, path, args); + IndexWithTuFromCodeCompletion(&file_consumer_shared, tu, unsaved, path, + args); }, [](lsRequestId id) { if (!std::holds_alternative(id)) { @@ -187,7 +185,7 @@ void RunQueryDbThread(const std::string& bin_name, } }); - IncludeComplete include_complete(config, &project); + IncludeComplete include_complete(&project); auto global_code_complete_cache = std::make_unique(); auto non_global_code_complete_cache = std::make_unique(); auto signature_cache = std::make_unique(); @@ -198,7 +196,6 @@ void RunQueryDbThread(const std::string& bin_name, // Setup shared references. for (MessageHandler* handler : *MessageHandler::message_handlers) { - handler->config = config; handler->db = &db; handler->waiter = indexer_waiter; handler->project = &project; @@ -221,7 +218,7 @@ void RunQueryDbThread(const std::string& bin_name, SetCurrentThreadName("querydb"); while (true) { bool did_work = QueryDbMainLoop( - config, &db, querydb_waiter, &project, &file_consumer_shared, + &db, querydb_waiter, &project, &file_consumer_shared, &import_manager, &import_pipeline_status, ×tamp_manager, &semantic_cache, &working_files, &clang_complete, &include_complete, global_code_complete_cache.get(), non_global_code_complete_cache.get(), @@ -247,8 +244,7 @@ void RunQueryDbThread(const std::string& bin_name, // blocks. // // |ipc| is connected to a server. -void LaunchStdinLoop(Config* config, - std::unordered_map* request_times) { +void LaunchStdinLoop(std::unordered_map* request_times) { // If flushing cin requires flushing cout there could be deadlocks in some // clients. std::cin.tie(nullptr); @@ -317,13 +313,12 @@ void LaunchStdoutThread(std::unordered_map* request_times, } void LanguageServerMain(const std::string& bin_name, - Config* config, MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter, MultiQueueWaiter* stdout_waiter) { std::unordered_map request_times; - LaunchStdinLoop(config, &request_times); + LaunchStdinLoop(&request_times); // We run a dedicated thread for writing to stdout because there can be an // unknown number of delays when output information. @@ -331,7 +326,7 @@ void LanguageServerMain(const std::string& bin_name, // Start querydb which takes over this thread. The querydb will launch // indexer threads as needed. - RunQueryDbThread(bin_name, config, querydb_waiter, indexer_waiter); + RunQueryDbThread(bin_name, querydb_waiter, indexer_waiter); } int main(int argc, char** argv) { @@ -410,9 +405,7 @@ int main(int argc, char** argv) { } } - // std::cerr << "Running language server" << std::endl; - auto config = std::make_unique(); - LanguageServerMain(argv[0], config.get(), &querydb_waiter, &indexer_waiter, + LanguageServerMain(argv[0], &querydb_waiter, &indexer_waiter, &stdout_waiter); } diff --git a/src/config.cc b/src/config.cc index a98b1a1a9..68cdecc4c 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,3 +1,3 @@ #include "config.h" -Config g_config; +std::unique_ptr g_config; diff --git a/src/config.h b/src/config.h index 5968b91c8..196e564ff 100644 --- a/src/config.h +++ b/src/config.h @@ -2,6 +2,7 @@ #include "serializer.h" +#include #include /* @@ -197,6 +198,10 @@ struct Config { // be logged. bool logSkippedPaths = false; + // Allow indexing on textDocument/didChange. + // May be too slow for big projects, so it is off by default. + bool onDidChange = false; + // Number of indexer threads. If 0, 80% of cores are used. int threads = 0; @@ -212,10 +217,6 @@ struct Config { bool sort = true; } workspaceSymbol; - // Allow indexing on textDocument/didChange. - // May be too slow for big projects, so it is off by default. - bool enableIndexOnDidChange = false; - struct Xref { // If true, |Location[]| response will include lexical container. bool container = false; @@ -249,6 +250,7 @@ MAKE_REFLECT_STRUCT(Config::Index, comments, enabled, logSkippedPaths, + onDidChange, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, maxNum, sort); @@ -276,9 +278,7 @@ MAKE_REFLECT_STRUCT(Config, index, workspaceSymbol, xref, - - enableIndexOnDidChange, dumpAST); -extern Config g_config; +extern std::unique_ptr g_config; diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 75dfe4a48..3e7ce0f7f 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -4,10 +4,10 @@ #include -void DiagnosticsEngine::Init(Config* config) { - frequencyMs_ = config->diagnostics.frequencyMs; - match_ = std::make_unique(config->diagnostics.whitelist, - config->diagnostics.blacklist); +void DiagnosticsEngine::Init() { + frequencyMs_ = g_config->diagnostics.frequencyMs; + match_ = std::make_unique(g_config->diagnostics.whitelist, + g_config->diagnostics.blacklist); } void DiagnosticsEngine::Publish(WorkingFiles* working_files, diff --git a/src/diagnostics_engine.h b/src/diagnostics_engine.h index ec1066fbd..2d3e7aeeb 100644 --- a/src/diagnostics_engine.h +++ b/src/diagnostics_engine.h @@ -9,7 +9,7 @@ class DiagnosticsEngine { int frequencyMs_; public: - void Init(Config*); + void Init(); void Publish(WorkingFiles* working_files, std::string path, std::vector diagnostics); diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 006290d57..8bbd6b8cb 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -160,7 +160,7 @@ TEST_SUITE("fuzzy_match") { CHECK(Ranks("ab", {"ab", "aoo_boo", "acb"})); CHECK(Ranks("CC", {"CamelCase", "camelCase", "camelcase"})); CHECK(Ranks("cC", {"camelCase", "CamelCase", "camelcase"})); - CHECK(Ranks("c c", {"camel case", "camelCase", "CamelCase", "camelcase", + CHECK(Ranks("c c", {"camelCase", "camel case", "CamelCase", "camelcase", "camel ace"})); CHECK(Ranks("Da.Te", {"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"})); diff --git a/src/iindexer.cc b/src/iindexer.cc index 1c77005d9..9b28942d4 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -7,19 +7,18 @@ struct ClangIndexer : IIndexer { ~ClangIndexer() override = default; std::vector> Index( - Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf) override { bool dump_ast = false; - for (const std::string& pattern : config->dumpAST) + for (const std::string& pattern : g_config->dumpAST) if (file.find(pattern) != std::string::npos) { dump_ast = true; break; } - return Parse(config, file_consumer_shared, file, args, file_contents, perf, + return Parse(file_consumer_shared, file, args, file_contents, perf, &index, dump_ast); } @@ -51,7 +50,6 @@ struct TestIndexer : IIndexer { ~TestIndexer() override = default; std::vector> Index( - Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, const std::vector& args, diff --git a/src/iindexer.h b/src/iindexer.h index df0e2d8b0..84b73a847 100644 --- a/src/iindexer.h +++ b/src/iindexer.h @@ -12,7 +12,6 @@ // like IndexFile // - rename this file to indexer.h -struct Config; struct IndexFile; struct FileContents; struct FileConsumerSharedState; @@ -35,7 +34,6 @@ struct IIndexer { virtual ~IIndexer() = default; virtual std::vector> Index( - Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, const std::vector& args, diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 9e0eb3468..3f8d89398 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -95,15 +95,15 @@ long long GetCurrentTimeInMilliseconds() { } struct ActiveThread { - ActiveThread(Config* config, ImportPipelineStatus* status) - : config_(config), status_(status) { - if (config_->progressReportFrequencyMs < 0) + ActiveThread(ImportPipelineStatus* status) + : status_(status) { + if (g_config->progressReportFrequencyMs < 0) return; ++status_->num_active_threads; } ~ActiveThread() { - if (config_->progressReportFrequencyMs < 0) + if (g_config->progressReportFrequencyMs < 0) return; --status_->num_active_threads; @@ -122,7 +122,7 @@ struct ActiveThread { out.params.activeThreads = status_->num_active_threads; // Ignore this progress update if the last update was too recent. - if (config_->progressReportFrequencyMs != 0) { + if (g_config->progressReportFrequencyMs != 0) { // Make sure we output a status update if queue lengths are zero. bool all_zero = out.params.indexRequestCount == 0 && out.params.doIdMapCount == 0 && @@ -133,13 +133,12 @@ struct ActiveThread { GetCurrentTimeInMilliseconds() < status_->next_progress_output) return; status_->next_progress_output = - GetCurrentTimeInMilliseconds() + config_->progressReportFrequencyMs; + GetCurrentTimeInMilliseconds() + g_config->progressReportFrequencyMs; } QueueManager::WriteStdout(kMethodType_Unknown, out); } - Config* config_; ImportPipelineStatus* status_; }; @@ -356,8 +355,7 @@ std::vector PreloadFileContents( return file_contents; } -void ParseFile(Config* config, - DiagnosticsEngine* diag_engine, +void ParseFile(DiagnosticsEngine* diag_engine, WorkingFiles* working_files, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, @@ -390,11 +388,11 @@ void ParseFile(Config* config, std::vector result; PerformanceImportFile perf; - auto indexes = indexer->Index(config, file_consumer_shared, path_to_index, - entry.args, file_contents, &perf); + auto indexes = indexer->Index(file_consumer_shared, path_to_index, entry.args, + file_contents, &perf); if (indexes.empty()) { - if (config->index.enabled && + if (g_config->index.enabled && !std::holds_alternative(request.id)) { Out_Error out; out.id = request.id; @@ -428,7 +426,6 @@ void ParseFile(Config* config, } bool IndexMain_DoParse( - Config* config, DiagnosticsEngine* diag_engine, WorkingFiles* working_files, FileConsumerSharedState* file_consumer_shared, @@ -444,7 +441,7 @@ bool IndexMain_DoParse( Project::Entry entry; entry.filename = request->path; entry.args = request->args; - ParseFile(config, diag_engine, working_files, file_consumer_shared, + ParseFile(diag_engine, working_files, file_consumer_shared, timestamp_manager, modification_timestamp_fetcher, import_manager, indexer, request.value(), entry); return true; @@ -544,7 +541,6 @@ ImportPipelineStatus::ImportPipelineStatus() // real-time indexing. // TODO: add option to disable this. void IndexWithTuFromCodeCompletion( - Config* config, FileConsumerSharedState* file_consumer_shared, ClangTranslationUnit* tu, const std::vector& file_contents, @@ -554,10 +550,10 @@ void IndexWithTuFromCodeCompletion( PerformanceImportFile perf; ClangIndex index; - auto indexes = ParseWithTu(config, file_consumer_shared, &perf, tu, &index, - path, args, file_contents); + auto indexes = ParseWithTu(file_consumer_shared, &perf, tu, &index, path, + args, file_contents); if (indexes.empty()) - return; + return; std::vector result; for (std::unique_ptr& new_index : indexes) { @@ -579,8 +575,7 @@ void IndexWithTuFromCodeCompletion( QueueManager::instance()->do_id_map.EnqueueAll(std::move(result)); } -void Indexer_Main(Config* config, - DiagnosticsEngine* diag_engine, +void Indexer_Main(DiagnosticsEngine* diag_engine, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, ImportManager* import_manager, @@ -597,7 +592,7 @@ void Indexer_Main(Config* config, bool did_work = false; { - ActiveThread active_thread(config, status); + ActiveThread active_thread(status); // TODO: process all off IndexMain_DoIndex before calling // IndexMain_DoCreateIndexUpdate for better icache behavior. We need to @@ -608,7 +603,7 @@ 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, diag_engine, working_files, + did_work = IndexMain_DoParse(diag_engine, working_files, file_consumer_shared, timestamp_manager, &modification_timestamp_fetcher, import_manager, indexer.get()) || @@ -723,15 +718,14 @@ void QueryDb_OnIndexed(QueueManager* queue, } // namespace -bool QueryDb_ImportMain(Config* config, - QueryDatabase* db, +bool QueryDb_ImportMain(QueryDatabase* db, ImportManager* import_manager, ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files) { auto* queue = QueueManager::instance(); - ActiveThread active_thread(config, status); + ActiveThread active_thread(status); bool did_work = false; @@ -760,16 +754,17 @@ bool QueryDb_ImportMain(Config* config, TEST_SUITE("ImportPipeline") { struct Fixture { Fixture() { + g_config = std::make_unique(); QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); queue = QueueManager::instance(); cache_manager = ICacheManager::MakeFake({}); indexer = IIndexer::MakeTestIndexer({}); - diag_engine.Init(&config); + diag_engine.Init(); } bool PumpOnce() { - return IndexMain_DoParse(&config, &diag_engine, &working_files, + return IndexMain_DoParse(&diag_engine, &working_files, &file_consumer_shared, ×tamp_manager, &modification_timestamp_fetcher, &import_manager, indexer.get()); @@ -788,7 +783,6 @@ TEST_SUITE("ImportPipeline") { MultiQueueWaiter stdout_waiter; QueueManager* queue = nullptr; - Config config; DiagnosticsEngine diag_engine; WorkingFiles working_files; FileConsumerSharedState file_consumer_shared; diff --git a/src/import_pipeline.h b/src/import_pipeline.h index 7ede6ae63..f7e750f9c 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -9,7 +9,6 @@ #include struct ClangTranslationUnit; -struct Config; class DiagnosticsEngine; struct FileConsumerSharedState; struct ImportManager; @@ -28,15 +27,13 @@ struct ImportPipelineStatus { }; void IndexWithTuFromCodeCompletion( - Config* config, FileConsumerSharedState* file_consumer_shared, ClangTranslationUnit* tu, const std::vector& file_contents, const std::string& path, const std::vector& args); -void Indexer_Main(Config* config, - DiagnosticsEngine* diag_engine, +void Indexer_Main(DiagnosticsEngine* diag_engine, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, ImportManager* import_manager, @@ -45,8 +42,7 @@ void Indexer_Main(Config* config, WorkingFiles* working_files, MultiQueueWaiter* waiter); -bool QueryDb_ImportMain(Config* config, - QueryDatabase* db, +bool QueryDb_ImportMain(QueryDatabase* db, ImportManager* import_manager, ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, diff --git a/src/include_complete.cc b/src/include_complete.cc index 2e2ef83e9..f9d55f92a 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -13,14 +13,14 @@ struct CompletionCandidate { lsCompletionItem completion_item; }; -std::string ElideLongPath(Config* config, const std::string& path) { - if (config->completion.includeMaxPathSize <= 0) +std::string ElideLongPath(const std::string& path) { + if (g_config->completion.includeMaxPathSize <= 0) return path; - if ((int)path.size() <= config->completion.includeMaxPathSize) + if ((int)path.size() <= g_config->completion.includeMaxPathSize) return path; - size_t start = path.size() - config->completion.includeMaxPathSize; + size_t start = path.size() - g_config->completion.includeMaxPathSize; return ".." + path.substr(start + 2); } @@ -73,12 +73,11 @@ bool TrimPath(Project* project, return angle; } -lsCompletionItem BuildCompletionItem(Config* config, - const std::string& path, +lsCompletionItem BuildCompletionItem(const std::string& path, bool use_angle_brackets, bool is_stl) { lsCompletionItem item; - item.label = ElideLongPath(config, path); + item.label = ElideLongPath(path); item.detail = path; // the include path, used in de-duplicating item.textEdit = lsTextEdit(); item.textEdit->newText = path; @@ -96,8 +95,8 @@ lsCompletionItem BuildCompletionItem(Config* config, } // namespace -IncludeComplete::IncludeComplete(Config* config, Project* project) - : is_scanning(false), config_(config), project_(project) {} +IncludeComplete::IncludeComplete(Project* project) + : is_scanning(false), project_(project) {} void IncludeComplete::Rescan() { if (is_scanning) @@ -107,17 +106,17 @@ void IncludeComplete::Rescan() { absolute_path_to_completion_item.clear(); inserted_paths.clear(); - if (!match_ && (!config_->completion.includeWhitelist.empty() || - !config_->completion.includeBlacklist.empty())) - match_ = std::make_unique(config_->completion.includeWhitelist, - config_->completion.includeBlacklist); + if (!match_ && (g_config->completion.includeWhitelist.size() || + g_config->completion.includeBlacklist.size())) + match_ = std::make_unique(g_config->completion.includeWhitelist, + g_config->completion.includeBlacklist); is_scanning = true; StartThread("scan_includes", [this]() { Timer timer; InsertStlIncludes(); - InsertIncludesFromDirectory(config_->projectRoot, + InsertIncludesFromDirectory(g_config->projectRoot, false /*use_angle_brackets*/); for (const std::string& dir : project_->quote_include_directories) InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); @@ -150,16 +149,16 @@ 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, g_config->completion.includeSuffixWhitelist)) return; if (match_ && !match_->IsMatch(absolute_path)) return; std::string trimmed_path = absolute_path; bool use_angle_brackets = - TrimPath(project_, config_->projectRoot, &trimmed_path); - lsCompletionItem item = BuildCompletionItem( - config_, trimmed_path, use_angle_brackets, false /*is_stl*/); + TrimPath(project_, g_config->projectRoot, &trimmed_path); + lsCompletionItem item = + BuildCompletionItem(trimmed_path, use_angle_brackets, false /*is_stl*/); std::unique_lock lock(completion_items_mutex, std::defer_lock); if (is_scanning) @@ -180,15 +179,15 @@ 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, g_config->completion.includeSuffixWhitelist)) return; if (match_ && !match_->IsMatch(directory + path)) return; CompletionCandidate candidate; candidate.absolute_path = directory + path; - candidate.completion_item = BuildCompletionItem( - config_, path, use_angle_brackets, false /*is_stl*/); + candidate.completion_item = + BuildCompletionItem(path, use_angle_brackets, false /*is_stl*/); results.push_back(candidate); }); @@ -202,7 +201,7 @@ void IncludeComplete::InsertStlIncludes() { std::lock_guard lock(completion_items_mutex); for (const char* stl_header : kStandardLibraryIncludes) { completion_items.push_back(BuildCompletionItem( - config_, stl_header, true /*use_angle_brackets*/, true /*is_stl*/)); + stl_header, true /*use_angle_brackets*/, true /*is_stl*/)); } } diff --git a/src/include_complete.h b/src/include_complete.h index 474381132..9cbee1abb 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -10,7 +10,7 @@ struct GroupMatch; struct Project; struct IncludeComplete { - IncludeComplete(Config* config, Project* project); + IncludeComplete(Project* project); // Starts scanning directories. Clears existing cache. void Rescan(); @@ -45,7 +45,6 @@ struct IncludeComplete { std::unordered_map inserted_paths; // Cached references - Config* config_; Project* project_; std::unique_ptr match_; }; diff --git a/src/indexer.h b/src/indexer.h index 8857c2bdb..8a6decea7 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -518,7 +518,6 @@ struct NamespaceHelper { // |dependencies| are the existing dependencies of |import_file| if this is a // reparse. std::vector> Parse( - Config* config, FileConsumerSharedState* file_consumer_shared, std::string file, const std::vector& args, @@ -527,7 +526,6 @@ std::vector> Parse( ClangIndex* index, bool dump_ast = false); std::vector> ParseWithTu( - Config* config, FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, ClangTranslationUnit* tu, diff --git a/src/lex_utils.cc b/src/lex_utils.cc index cb3ad0f5c..deb6ece98 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -3,7 +3,6 @@ #include #include -#include // VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent // text documents. diff --git a/src/lsp.cc b/src/lsp.cc index eb1825a68..251a52d79 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -7,7 +7,6 @@ #include #include -#include MessageRegistry* MessageRegistry::instance_ = nullptr; diff --git a/src/message_handler.cc b/src/message_handler.cc index 897d91376..cdc2d98a2 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -101,9 +101,9 @@ SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) { SemanticHighlightSymbolCache::SemanticHighlightSymbolCache() : cache_(kCacheSize) {} -void SemanticHighlightSymbolCache::Init(Config* config) { - match_ = std::make_unique(config->highlight.whitelist, - config->highlight.blacklist); +void SemanticHighlightSymbolCache::Init() { + match_ = std::make_unique(g_config->highlight.whitelist, + g_config->highlight.blacklist); } std::shared_ptr diff --git a/src/message_handler.h b/src/message_handler.h index ea6c67e34..ca6c7a2f3 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -55,7 +55,7 @@ struct SemanticHighlightSymbolCache { std::unique_ptr match_; SemanticHighlightSymbolCache(); - void Init(Config*); + void Init(); std::shared_ptr GetCacheForFile(const std::string& path); }; @@ -103,7 +103,6 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, static type type##message_handler_instance_; struct MessageHandler { - Config* config = nullptr; QueryDatabase* db = nullptr; MultiQueueWaiter* waiter = nullptr; Project* project = nullptr; diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index f1c31f29d..cc6819865 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -33,15 +33,13 @@ struct Handler_CclsBase : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { if (const auto* def = db->GetType(sym).AnyDef()) - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db, def->bases), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, + GetDeclarations(db, def->bases)); break; } else if (sym.kind == SymbolKind::Func) { if (const auto* def = db->GetFunc(sym).AnyDef()) - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db, def->bases), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, + GetDeclarations(db, def->bases)); break; } } diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc index 0e7904fc0..db781be98 100644 --- a/src/messages/ccls_callers.cc +++ b/src/messages/ccls_callers.cc @@ -35,9 +35,7 @@ struct Handler_CclsCallers : BaseMessageHandler { uses.push_back(func_ref); for (Use func_ref : GetUsesForAllDerived(db, func)) uses.push_back(func_ref); - out.result = - GetLsLocationExs(db, working_files, uses, config->xref.container, - config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, uses); break; } } diff --git a/src/messages/ccls_derived.cc b/src/messages/ccls_derived.cc index ad415acee..d8676211a 100644 --- a/src/messages/ccls_derived.cc +++ b/src/messages/ccls_derived.cc @@ -30,15 +30,13 @@ struct Handler_CclsDerived : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { QueryType& type = db->GetType(sym); - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db, type.derived), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, + GetDeclarations(db, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db, func.derived), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, + GetDeclarations(db, func.derived)); break; } } diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index b56701db3..10220b538 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -87,8 +87,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { Timer time; // Send index requests for every file. - project->Index(config, QueueManager::instance(), working_files, - std::monostate()); + project->Index(QueueManager::instance(), working_files, std::monostate()); time.ResetAndPrint("[perf] Dispatched $ccls/freshenIndex index requests"); } }; diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index f24471e76..ce0bb4379 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -132,12 +132,10 @@ struct Handler_CclsRandom : BaseMessageHandler { for (int i = 0; i < n; i++) { sum += x[i]; if (sum >= roulette) { - Maybe use = GetDefinitionExtent(db, syms[i]); - if (!use) - continue; - if (auto ls_loc = GetLsLocationEx(db, working_files, *use, - config->xref.container)) - out.result.push_back(*ls_loc); + if (Maybe use = GetDefinitionExtent(db, syms[i])) + if (auto ls_loc = GetLsLocationEx(db, working_files, *use, + g_config->xref.container)) + out.result.push_back(*ls_loc); break; } } diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index b9426487e..a19803c56 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -43,9 +43,8 @@ struct Handler_CclsVars : BaseMessageHandler { // fallthrough case SymbolKind::Type: { QueryType& type = db->types[id.id]; - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db, type.instances), - config->xref.container, config->xref.maxNum); + out.result = GetLsLocationExs(db, working_files, + GetDeclarations(db, type.instances)); break; } } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index d10b971aa..1bc34c10d 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -428,6 +428,7 @@ struct Handler_Initialize : BaseMessageHandler { JsonWriter json_writer(&writer); Reflect(json_writer, request->params.initializationOptions); LOG_S(INFO) << "Init parameters: " << output.GetString(); + std::unique_ptr config; if (request->params.rootUri) { std::string project_path = @@ -437,9 +438,9 @@ struct Handler_Initialize : BaseMessageHandler { { if (request->params.initializationOptions) - *config = *request->params.initializationOptions; + config = std::make_unique(*request->params.initializationOptions); else - *config = Config(); + config = std::make_unique(); rapidjson::Document reader; reader.Parse(g_init_options.c_str()); if (!reader.HasParseError()) { @@ -508,32 +509,29 @@ struct Handler_Initialize : BaseMessageHandler { MakeDirectoryRecursive(config->cacheDirectory + '@' + EscapeFileName(config->projectRoot)); - g_config = *config; + g_config = std::move(config); Timer time; - diag_engine->Init(config); - semantic_cache->Init(config); + diag_engine->Init(); + semantic_cache->Init(); // Open up / load the project. - project->Load(config, project_path); + project->Load(project_path); time.ResetAndPrint("[perf] Loaded compilation entries (" + std::to_string(project->entries.size()) + " files)"); // Start indexer threads. Start this after loading the project, as that // may take a long time. Indexer threads will emit status/progress // reports. - if (config->index.threads == 0) { + if (g_config->index.threads == 0) { // If the user has not specified how many indexers to run, try to // guess an appropriate value. Default to 80% utilization. - const float kDefaultTargetUtilization = 0.8f; - config->index.threads = (int)(std::thread::hardware_concurrency() * - kDefaultTargetUtilization); - if (config->index.threads <= 0) - config->index.threads = 1; + g_config->index.threads = + std::max(int(std::thread::hardware_concurrency() * 0.8), 1); } - LOG_S(INFO) << "Starting " << config->index.threads << " indexers"; - for (int i = 0; i < config->index.threads; ++i) { + LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; + for (int i = 0; i < g_config->index.threads; ++i) { StartThread("indexer" + std::to_string(i), [=]() { - Indexer_Main(config, diag_engine, file_consumer_shared, + Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, import_manager, import_pipeline_status, project, working_files, waiter); }); @@ -544,8 +542,7 @@ struct Handler_Initialize : BaseMessageHandler { include_complete->Rescan(); time.Reset(); - project->Index(config, QueueManager::instance(), working_files, - request->id); + project->Index(QueueManager::instance(), working_files, request->id); // We need to support multiple concurrent index processes. time.ResetAndPrint("[perf] Dispatched initial index requests"); } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 521268c05..cbe065cb5 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -206,7 +206,7 @@ struct Handler_TextDocumentCodeLens case SymbolKind::Var: { QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = var.AnyDef(); - if (!def || (def->is_local() && !config->codeLens.localVariables)) + if (!def || (def->is_local() && !g_config->codeLens.localVariables)) continue; bool force_display = true; diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 3c9831b05..b0f629603 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -160,9 +160,8 @@ char* tofixedbase64(T input, char* out) { // when given 1000+ completion items. void FilterAndSortCompletionResponse( Out_TextDocumentComplete* complete_response, - const std::string& complete_text, - bool enable) { - if (!enable) + const std::string& complete_text) { + if (!g_config->completion.filterAndSort) return; ScopedPerfTimer timer{"FilterAndSortCompletionResponse"}; @@ -327,8 +326,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { return k == result.keyword; })) { out.result.items = preprocessorKeywordCompletionItems(result.match); - FilterAndSortCompletionResponse(&out, result.keyword, - config->completion.filterAndSort); + FilterAndSortCompletionResponse(&out, result.keyword); } } else if (result.keyword.compare("include") == 0) { { @@ -342,8 +340,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) out.result.items.push_back(item); } - FilterAndSortCompletionResponse(&out, result.pattern, - config->completion.filterAndSort); + FilterAndSortCompletionResponse(&out, result.pattern); DecorateIncludePaths(result.match, &out.result.items); } @@ -365,8 +362,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { out.result.items = results; // Emit completion results. - FilterAndSortCompletionResponse(&out, existing_completion, - config->completion.filterAndSort); + FilterAndSortCompletionResponse(&out, existing_completion); QueueManager::WriteStdout(kMethodType, out); // Cache completion results. diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index e6e4caf73..15216aceb 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -105,9 +105,7 @@ struct Handler_TextDocumentDefinition if (uses.empty() && on_def) uses.push_back(*on_def); } - AddRange(&out.result, - GetLsLocationExs(db, working_files, uses, config->xref.container, - config->xref.maxNum)); + AddRange(&out.result, GetLsLocationExs(db, working_files, uses)); if (!out.result.empty()) break; } @@ -172,7 +170,7 @@ struct Handler_TextDocumentDefinition Maybe use = GetDefinitionSpell(db, db->symbols[best_i]); assert(use); if (auto ls_loc = GetLsLocationEx(db, working_files, *use, - config->xref.container)) + g_config->xref.container)) out.result.push_back(*ls_loc); } } diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 4f978bc36..5f5d2a71c 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -25,7 +25,7 @@ struct Handler_TextDocumentDidChange void Run(In_TextDocumentDidChange* request) override { std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); - if (config->enableIndexOnDidChange) { + if (g_config->index.onDidChange) { std::optional content = ReadContent(path); if (!content) { LOG_S(ERROR) << "Unable to read file content after saving " << path; diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 9596ddb43..29ceffa8c 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -47,7 +47,7 @@ struct Handler_TextDocumentDidSave // mutex and check to see if we should skip the current request. // if so, ignore that index response. // TODO: send as priority request - if (!config->enableIndexOnDidChange) { + if (!g_config->index.onDidChange) { std::optional content = ReadContent(path); if (!content) { LOG_S(ERROR) << "Unable to read file content after saving " << path; diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index 40f99531b..ba90af9a4 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -56,7 +56,7 @@ struct Handler_TextDocumentReferences Out_TextDocumentReferences out; out.id = request->id; - bool container = config->xref.container; + bool container = g_config->xref.container; for (const SymbolRef& sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { @@ -94,8 +94,8 @@ struct Handler_TextDocumentReferences break; } - if ((int)out.result.size() >= config->xref.maxNum) - out.result.resize(config->xref.maxNum); + if ((int)out.result.size() >= g_config->xref.maxNum) + out.result.resize(g_config->xref.maxNum); QueueManager::WriteStdout(kMethodType, out); } }; diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 4226c558a..738636e6d 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -50,7 +50,7 @@ struct Handler_TextDocumentTypeDefinition for (const auto& def : type.def) if (def.spell) { if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, - config->xref.container)) + g_config->xref.container)) out.result.push_back(*ls_loc); } break; diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index c2ad85cbf..8d81b892d 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -28,13 +28,12 @@ struct Handler_WorkspaceDidChangeConfiguration MethodType GetMethodType() const override { return kMethodType; } void Run(In_WorkspaceDidChangeConfiguration* request) override { Timer time; - project->Load(config, config->projectRoot); + project->Load(g_config->projectRoot); time.ResetAndPrint("[perf] Loaded compilation entries (" + std::to_string(project->entries.size()) + " files)"); time.Reset(); - project->Index(config, QueueManager::instance(), working_files, - std::monostate()); + project->Index(QueueManager::instance(), working_files, std::monostate()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 4294bd058..06140b507 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -77,8 +77,8 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { // db->detailed_names indices of each lsSymbolInformation in out.result std::vector result_indices; std::vector unsorted_results; - inserted_results.reserve(config->workspaceSymbol.maxNum); - result_indices.reserve(config->workspaceSymbol.maxNum); + inserted_results.reserve(g_config->workspaceSymbol.maxNum); + result_indices.reserve(g_config->workspaceSymbol.maxNum); // We use detailed_names without parameters for matching. @@ -93,14 +93,14 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { if (InsertSymbolIntoResult(db, working_files, db->symbols[i], &unsorted_results)) { result_indices.push_back(i); - if (unsorted_results.size() >= config->workspaceSymbol.maxNum) + if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum) break; } } } // Find subsequence matches. - if (unsorted_results.size() < config->workspaceSymbol.maxNum) { + if (unsorted_results.size() < g_config->workspaceSymbol.maxNum) { std::string query_without_space; query_without_space.reserve(query.size()); for (char c : query) @@ -118,14 +118,14 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { if (InsertSymbolIntoResult(db, working_files, db->symbols[i], &unsorted_results)) { result_indices.push_back(i); - if (unsorted_results.size() >= config->workspaceSymbol.maxNum) + if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum) break; } } } } - if (config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { + if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { // Sort results with a fuzzy matching algorithm. int longest = 0; for (int i : result_indices) diff --git a/src/project.cc b/src/project.cc index 7357557d7..9370c3acd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -21,10 +21,7 @@ #include #endif -#include -#include #include -#include #include #include @@ -61,7 +58,7 @@ struct ProjectConfig { // of clang for the same platform are incompatible). Note that libclang always generate it's own pch // internally. For details, see https://github.com/Valloric/ycmd/issues/892 . std::vector kBlacklistMulti = { - "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang", "-include", "-include-pch"}; + "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang"}; // Blacklisted flags which are always removed from the command line. std::vector kBlacklist = { @@ -106,7 +103,6 @@ LanguageId SourceFileLanguage(const std::string& path) { } Project::Entry GetCompilationEntryFromCompileCommandEntry( - Config* init_opts, ProjectConfig* config, const CompileCommandsEntry& entry) { Project::Entry result; @@ -240,7 +236,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Add -resource-dir so clang can correctly resolve system includes like // if (!AnyStartsWith(result.args, "-resource-dir")) - result.args.push_back("-resource-dir=" + init_opts->resourceDirectory); + result.args.push_back("-resource-dir=" + g_config->resourceDirectory); // There could be a clang version mismatch between what the project uses and // what ccls uses. Make sure we do not emit warnings for mismatched options. @@ -249,7 +245,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Using -fparse-all-comments enables documentation in the indexer and in // code completion. - if (init_opts->index.comments > 1 && + if (g_config->index.comments > 1 && !AnyStartsWith(result.args, "-fparse-all-comments")) { result.args.push_back("-fparse-all-comments"); } @@ -269,8 +265,7 @@ std::vector ReadCompilerArgumentsFromFile( return args; } -std::vector LoadFromDirectoryListing(Config* init_opts, - ProjectConfig* config) { +std::vector LoadFromDirectoryListing(ProjectConfig* config) { std::vector result; config->mode = ProjectMode::DotCcls; LOG_IF_S(WARNING, !FileExists(config->project_dir + "/.ccls") && @@ -322,24 +317,22 @@ std::vector LoadFromDirectoryListing(Config* init_opts, if (e.args.empty()) e.args.push_back("%clang"); // Add a Dummy. e.args.push_back(e.file); - result.push_back( - GetCompilationEntryFromCompileCommandEntry(init_opts, config, e)); + result.push_back(GetCompilationEntryFromCompileCommandEntry(config, e)); } return result; } std::vector LoadCompilationEntriesFromDirectory( - Config* config, ProjectConfig* project, const std::string& opt_compilation_db_dir) { // If there is a .ccls file always load using directory listing. if (FileExists(project->project_dir + ".ccls")) - return LoadFromDirectoryListing(config, project); + return LoadFromDirectoryListing(project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. - std::string comp_db_dir; - if (config->compilationDatabaseCommand.empty()) { + fs::path comp_db_dir; + if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir @@ -356,32 +349,35 @@ std::vector LoadCompilationEntriesFromDirectory( rapidjson::StringBuffer input; rapidjson::Writer writer(input); JsonWriter json_writer(&writer); - Reflect(json_writer, *config); + Reflect(json_writer, *g_config); std::string contents = GetExternalCommandOutput( - std::vector{config->compilationDatabaseCommand, + std::vector{g_config->compilationDatabaseCommand, project->project_dir}, input.GetString()); - std::ofstream(comp_db_dir + "/compile_commands.json") << contents; + FILE* fout = fopen((comp_db_dir / "compile_commands.json").c_str(), "wb"); + fwrite(contents.c_str(), contents.size(), 1, fout); + fclose(fout); #endif } - LOG_S(INFO) << "Trying to load compile_commands.json"; + fs::path comp_db_path = comp_db_dir / "compile_commands.json"; + LOG_S(INFO) << "Trying to load " << comp_db_path.string(); CXCompilationDatabase_Error cx_db_load_error; CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( comp_db_dir.c_str(), &cx_db_load_error); - if (!config->compilationDatabaseCommand.empty()) { + if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 // TODO #else - unlink((comp_db_dir + "/compile_commands.json").c_str()); + unlink(comp_db_path.c_str()); rmdir(comp_db_dir.c_str()); #endif } if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { - LOG_S(INFO) << "Unable to load compile_commands.json located at \"" - << comp_db_dir << "\"; using directory listing instead."; - return LoadFromDirectoryListing(config, project); + LOG_S(INFO) << "Unable to load " << comp_db_path.string() + << "; using directory listing instead."; + return LoadFromDirectoryListing(project); } Timer clang_time; @@ -421,7 +417,7 @@ std::vector LoadCompilationEntriesFromDirectory( entry.file = entry.ResolveIfRelative(relative_filename); result.push_back( - GetCompilationEntryFromCompileCommandEntry(config, project, entry)); + GetCompilationEntryFromCompileCommandEntry(project, entry)); our_time.Pause(); } @@ -452,13 +448,13 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace -void Project::Load(Config* config, const std::string& root_directory) { +void Project::Load(const std::string& root_directory) { // Load data. ProjectConfig project; - project.extra_flags = config->extraClangArguments; + project.extra_flags = g_config->extraClangArguments; project.project_dir = root_directory; entries = LoadCompilationEntriesFromDirectory( - config, &project, config->compilationDatabaseDirectory); + &project, g_config->compilationDatabaseDirectory); // Cleanup / postprocess include directories. quote_include_directories.assign(project.quote_dirs.begin(), @@ -539,28 +535,24 @@ Project::Entry Project::FindCompilationEntryForFile( } void Project::ForAllFilteredFiles( - Config* config, std::function action) { - GroupMatch matcher(config->index.whitelist, config->index.blacklist); + GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); for (int i = 0; i < entries.size(); ++i) { const Project::Entry& entry = entries[i]; std::string failure_reason; if (matcher.IsMatch(entry.filename, &failure_reason)) action(i, entries[i]); - else { - if (config->index.logSkippedPaths) { - LOG_S(INFO) << "[" << i + 1 << "/" << entries.size() << "]: Failed " - << failure_reason << "; skipping " << entry.filename; - } + else if (g_config->index.logSkippedPaths) { + LOG_S(INFO) << "[" << i + 1 << "/" << entries.size() << "]: Failed " + << failure_reason << "; skipping " << entry.filename; } } } -void Project::Index(Config* config, - QueueManager* queue, +void Project::Index(QueueManager* queue, WorkingFiles* wfiles, lsRequestId id) { - ForAllFilteredFiles(config, [&](int i, const Project::Entry& entry) { + ForAllFilteredFiles([&](int i, const Project::Entry& entry) { std::optional content = ReadContent(entry.filename); if (!content) { LOG_S(ERROR) << "When loading project, canont read file " @@ -578,30 +570,22 @@ TEST_SUITE("Project") { void CheckFlags(const std::string& directory, const std::string& file, std::vector raw, std::vector expected) { - Config config; + g_config = std::make_unique(); + g_config->resourceDirectory = "/w/resource_dir/"; ProjectConfig project; project.project_dir = "/w/c/s/"; - config.resourceDirectory = "/w/resource_dir/"; CompileCommandsEntry entry; entry.directory = directory; entry.args = raw; entry.file = file; Project::Entry result = - GetCompilationEntryFromCompileCommandEntry(&config, &project, entry); + GetCompilationEntryFromCompileCommandEntry(&project, entry); if (result.args != expected) { - std::cout << "Raw: " << StringJoin(raw) << std::endl; - std::cout << "Expected: " << StringJoin(expected) << std::endl; - std::cout << "Actual: " << StringJoin(result.args) << std::endl; - } - for (int i = 0; i < std::min(result.args.size(), expected.size()); ++i) { - if (result.args[i] != expected[i]) { - std::cout << std::endl; - std::cout << "mismatch at " << i << std::endl; - std::cout << " expected: " << expected[i] << std::endl; - std::cout << " actual: " << result.args[i] << std::endl; - } + fprintf(stderr, "Raw: %s\n", StringJoin(raw).c_str()); + fprintf(stderr, "Expected: %s\n", StringJoin(expected).c_str()); + fprintf(stderr, "Actual: %s\n", StringJoin(result.args).c_str()); } REQUIRE(result.args == expected); } @@ -671,7 +655,7 @@ TEST_SUITE("Project") { } TEST_CASE("Directory extraction") { - Config init_opts; + g_config = std::make_unique(); ProjectConfig config; config.project_dir = "/w/c/s/"; @@ -701,7 +685,7 @@ TEST_SUITE("Project") { "foo.cc"}; entry.file = "foo.cc"; Project::Entry result = - GetCompilationEntryFromCompileCommandEntry(&init_opts, &config, entry); + GetCompilationEntryFromCompileCommandEntry(&config, entry); std::unordered_set angle_expected{ "/a_absolute1", "/a_absolute2", "/base/a_relative1", diff --git a/src/project.h b/src/project.h index 71fbd19af..d67562ab8 100644 --- a/src/project.h +++ b/src/project.h @@ -40,7 +40,7 @@ struct Project { // will affect flags in their subtrees (relative paths are relative to the // project root, not subdirectories). For compile_commands.json, its entries // are indexed. - void Load(Config* config, const std::string& root_directory); + void Load(const std::string& root_directory); // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure. @@ -55,11 +55,7 @@ struct Project { // Run |action| on every file in the project. void ForAllFilteredFiles( - Config* config, std::function action); - void Index(Config* config, - QueueManager* queue, - WorkingFiles* wfiles, - lsRequestId id); + void Index(QueueManager* queue, WorkingFiles* wfiles, lsRequestId id); }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 72e756c19..e30b6d43f 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -251,17 +251,16 @@ std::optional GetLsLocationEx(QueryDatabase* db, std::vector GetLsLocationExs(QueryDatabase* db, WorkingFiles* working_files, - const std::vector& uses, - bool container, - int limit) { + const std::vector& uses) { std::vector ret; for (Use use : uses) - if (auto loc = GetLsLocationEx(db, working_files, use, container)) + if (auto loc = + GetLsLocationEx(db, working_files, use, g_config->xref.container)) ret.push_back(*loc); std::sort(ret.begin(), ret.end()); ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); - if (ret.size() > limit) - ret.resize(limit); + if (ret.size() > g_config->xref.maxNum) + ret.resize(g_config->xref.maxNum); return ret; } diff --git a/src/query_utils.h b/src/query_utils.h index a3bd30dfa..0365394a5 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -41,9 +41,7 @@ std::optional GetLsLocationEx(QueryDatabase* db, bool container); std::vector GetLsLocationExs(QueryDatabase* db, WorkingFiles* working_files, - const std::vector& refs, - bool container, - int limit); + const std::vector& refs); // Returns a symbol. The symbol will have *NOT* have a location assigned. std::optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, diff --git a/src/test.cc b/src/test.cc index 07d083bc1..7ba6b89e8 100644 --- a/src/test.cc +++ b/src/test.cc @@ -262,11 +262,11 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { flags.push_back(path); // Run test. - Config config; + g_config = std::make_unique(); FileConsumerSharedState file_consumer_shared; PerformanceImportFile perf; - auto dbs = Parse(&config, &file_consumer_shared, path, flags, {}, &perf, - &index, false /*dump_ast*/); + auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, + false /*dump_ast*/); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; From 1dc55843e7b8e61241fe0bca7e0114f2458ce76b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 4 Apr 2018 00:43:37 -0700 Subject: [PATCH 063/378] Remove unused fs code. --- CMakeLists.txt | 1 - src/import_pipeline.cc | 6 +-- src/messages/initialize.cc | 5 +- src/platform.cc | 96 -------------------------------------- src/platform.h | 28 ----------- src/platform_posix.cc | 79 ------------------------------- src/platform_win.cc | 31 ------------ src/test.cc | 8 ++-- 8 files changed, 10 insertions(+), 244 deletions(-) delete mode 100644 src/platform.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 861258091..f95f61715 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,7 +195,6 @@ target_sources(ccls PRIVATE src/message_handler.cc src/platform_posix.cc src/platform_win.cc - src/platform.cc src/port.cc src/position.cc src/project.cc diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 3f8d89398..334b0e72d 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -97,13 +97,13 @@ long long GetCurrentTimeInMilliseconds() { struct ActiveThread { ActiveThread(ImportPipelineStatus* status) : status_(status) { - if (g_config->progressReportFrequencyMs < 0) + if (g_config && g_config->progressReportFrequencyMs < 0) return; ++status_->num_active_threads; } ~ActiveThread() { - if (g_config->progressReportFrequencyMs < 0) + if (g_config && g_config->progressReportFrequencyMs < 0) return; --status_->num_active_threads; @@ -122,7 +122,7 @@ struct ActiveThread { out.params.activeThreads = status_->num_active_threads; // Ignore this progress update if the last update was too recent. - if (g_config->progressReportFrequencyMs != 0) { + if (g_config && g_config->progressReportFrequencyMs != 0) { // Make sure we output a status update if queue lengths are zero. bool all_zero = out.params.indexRequestCount == 0 && out.params.doIdMapCount == 0 && diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 1bc34c10d..5af936cd2 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,5 +1,6 @@ #include "cache_manager.h" #include "diagnostics_engine.h" +#include "filesystem.hh" #include "import_pipeline.h" #include "include_complete.h" #include "message_handler.h" @@ -504,9 +505,9 @@ struct Handler_Initialize : BaseMessageHandler { config->projectRoot = project_path; // Create two cache directories for files inside and outside of the // project. - MakeDirectoryRecursive(config->cacheDirectory + + fs::create_directories(config->cacheDirectory + EscapeFileName(config->projectRoot)); - MakeDirectoryRecursive(config->cacheDirectory + '@' + + fs::create_directories(config->cacheDirectory + '@' + EscapeFileName(config->projectRoot)); g_config = std::move(config); diff --git a/src/platform.cc b/src/platform.cc deleted file mode 100644 index 84e2ece6f..000000000 --- a/src/platform.cc +++ /dev/null @@ -1,96 +0,0 @@ -#include "platform.h" - -#include -#include - -#include -#include -#include -#include -#include - -namespace { - -// See http://stackoverflow.com/a/236803 -template -void Split(const std::string& s, char delim, Out result) { - std::stringstream ss; - ss.str(s); - std::string item; - while (std::getline(ss, item, delim)) { - if (!item.empty()) - *(result++) = item; - } -} -std::vector Split(const std::string& s, char delim) { - std::vector elems; - Split(s, delim, std::back_inserter(elems)); - return elems; -} - -std::string Join(const std::vector& entries, - char delim, - size_t end) { - std::string result; - bool first = true; - for (size_t i = 0; i < end; ++i) { - if (!first) - result += delim; - first = false; - result += entries[i]; - } - return result; -} - -} // namespace - -PlatformMutex::~PlatformMutex() = default; - -PlatformScopedMutexLock::~PlatformScopedMutexLock() = default; - -PlatformSharedMemory::~PlatformSharedMemory() = default; - -void MakeDirectoryRecursive(std::string path) { - path = NormalizePath(path); - - if (TryMakeDirectory(path)) - return; - - std::string prefix = ""; - if (path[0] == '/') - prefix = "/"; - - std::vector components = Split(path, '/'); - - // Find first parent directory which doesn't exist. - int first_success = -1; - for (size_t j = 0; j < components.size(); ++j) { - size_t i = components.size() - j; - if (TryMakeDirectory(prefix + Join(components, '/', i))) { - first_success = i; - break; - } - } - - if (first_success == -1) { - LOG_S(FATAL) << "Failed to make any parent directory for " << path; - exit(1); - } - - // Make all child directories. - for (size_t i = first_success + 1; i <= components.size(); ++i) { - if (TryMakeDirectory(prefix + Join(components, '/', i)) == false) { - LOG_S(FATAL) << "Failed making directory for " << path - << " even after creating parent directories"; - exit(1); - } - } -} - -TEST_SUITE("Platform") { - TEST_CASE("Split strings") { - std::vector actual = Split("/a/b/c/", '/'); - std::vector expected{"a", "b", "c"}; - REQUIRE(actual == expected); - } -} diff --git a/src/platform.h b/src/platform.h index 770012143..e29036068 100644 --- a/src/platform.h +++ b/src/platform.h @@ -7,46 +7,18 @@ #include #include -struct PlatformMutex { - virtual ~PlatformMutex(); -}; -struct PlatformScopedMutexLock { - virtual ~PlatformScopedMutexLock(); -}; -struct PlatformSharedMemory { - virtual ~PlatformSharedMemory(); - void* data; - size_t capacity; - std::string name; -}; - void PlatformInit(); std::string GetExecutablePath(); -std::string GetWorkingDirectory(); std::string NormalizePath(const std::string& path); -// Creates a directory at |path|. Creates directories recursively if needed. -void MakeDirectoryRecursive(std::string path); -// Tries to create the directory given by |absolute_path|. Returns true if -// successful or if the directory already exists. Returns false otherwise. This -// does not attempt to recursively create directories. -bool TryMakeDirectory(const std::string& absolute_path); void SetCurrentThreadName(const std::string& thread_name); std::optional GetLastModificationTime(const std::string& absolute_path); -void MoveFileTo(const std::string& destination, const std::string& source); -void CopyFileTo(const std::string& destination, const std::string& source); - -bool IsSymLink(const std::string& path); - // Free any unused memory and return it to the system. void FreeUnusedMemory(); -// If true objective-c index tests will be run. -bool RunObjectiveCIndexTests(); - // Stop self and wait for SIGCONT. void TraceMe(); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index d41cee680..ea9da8cae 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -150,29 +150,11 @@ std::string GetExecutablePath() { #endif } -std::string GetWorkingDirectory() { - char result[FILENAME_MAX]; - if (!getcwd(result, sizeof(result))) - return ""; - std::string working_dir = std::string(result, strlen(result)); - EnsureEndsInSlash(working_dir); - return working_dir; -} - std::string NormalizePath(const std::string& path) { std::optional resolved = RealPathNotExpandSymlink(path); return resolved ? *resolved : path; } -bool TryMakeDirectory(const std::string& absolute_path) { - const mode_t kMode = 0777; // UNIX style permissions - if (mkdir(absolute_path.c_str(), kMode) == -1) { - // Success if the directory exists. - return errno == EEXIST; - } - return true; -} - void SetCurrentThreadName(const std::string& thread_name) { loguru::set_thread_name(thread_name.c_str()); #if defined(__APPLE__) @@ -206,73 +188,12 @@ std::optional GetLastModificationTime(const std::string& absolute_path) return buf.st_mtime; } -void MoveFileTo(const std::string& dest, const std::string& source) { - // TODO/FIXME - do a real move. - CopyFileTo(dest, source); -} - -// See http://stackoverflow.com/q/13198627 -void CopyFileTo(const std::string& dest, const std::string& source) { - int fd_from = open(source.c_str(), O_RDONLY); - if (fd_from < 0) - return; - - int fd_to = open(dest.c_str(), O_WRONLY | O_CREAT, 0666); - if (fd_to < 0) - goto out_error; - - char buf[4096]; - ssize_t nread; - while (nread = read(fd_from, buf, sizeof buf), nread > 0) { - char* out_ptr = buf; - ssize_t nwritten; - - do { - nwritten = write(fd_to, out_ptr, nread); - - if (nwritten >= 0) { - nread -= nwritten; - out_ptr += nwritten; - } else if (errno != EINTR) - goto out_error; - } while (nread > 0); - } - - if (nread == 0) { - if (close(fd_to) < 0) { - fd_to = -1; - goto out_error; - } - close(fd_from); - - return; - } - -out_error: - close(fd_from); - if (fd_to >= 0) - close(fd_to); -} - -bool IsSymLink(const std::string& path) { - struct stat buf; - return lstat(path.c_str(), &buf) == 0 && S_ISLNK(buf.st_mode); -} - void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); #endif } -bool RunObjectiveCIndexTests() { -#if defined(__APPLE__) - return true; -#else - return false; -#endif -} - void TraceMe() { // If the environment variable is defined, wait for a debugger. // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue diff --git a/src/platform_win.cc b/src/platform_win.cc index 2ddb96a8a..c6c4df3fa 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -34,13 +34,6 @@ std::string GetExecutablePath() { return NormalizePath(result); } -// See http://stackoverflow.com/a/19535628 -std::string GetWorkingDirectory() { - char result[MAX_PATH]; - std::string binary_path(result, GetModuleFileName(NULL, result, MAX_PATH)); - return binary_path.substr(0, binary_path.find_last_of("\\/") + 1); -} - std::string NormalizePath(const std::string& path) { DWORD retval = 0; TCHAR buffer[MAX_PATH] = TEXT(""); @@ -57,14 +50,6 @@ std::string NormalizePath(const std::string& path) { return result; } -bool TryMakeDirectory(const std::string& absolute_path) { - if (_mkdir(absolute_path.c_str()) == -1) { - // Success if the directory exists. - return errno == EEXIST; - } - return true; -} - // See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx const DWORD MS_VC_EXCEPTION = 0x406D1388; #pragma pack(push, 8) @@ -117,24 +102,8 @@ std::optional GetLastModificationTime(const std::string& absolute_path) return buf.st_mtime; } -void MoveFileTo(const std::string& destination, const std::string& source) { - MoveFile(source.c_str(), destination.c_str()); -} - -void CopyFileTo(const std::string& destination, const std::string& source) { - CopyFile(source.c_str(), destination.c_str(), false /*failIfExists*/); -} - -bool IsSymLink(const std::string& path) { - return false; -} - void FreeUnusedMemory() {} -bool RunObjectiveCIndexTests() { - return false; -} - // TODO Wait for debugger to attach void TraceMe() {} diff --git a/src/test.cc b/src/test.cc index 7ba6b89e8..2453ed03d 100644 --- a/src/test.cc +++ b/src/test.cc @@ -224,11 +224,11 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { bool is_fail_allowed = false; if (EndsWithAny(path, {".m", ".mm"})) { - if (!RunObjectiveCIndexTests()) { - std::cout << "Skipping \"" << path << "\" since this platform does not " +#ifndef __APPLE__ + std::cout << "Skipping \"" << path << "\" since this platform does not " << "support running Objective-C tests." << std::endl; - continue; - } + continue; +#endif // objective-c tests are often not updated right away. do not bring down // CI if they fail. From 9f9420519e1c960976eeb04c5cb5a5931711fdb9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 5 Apr 2018 00:15:21 -0700 Subject: [PATCH 064/378] Set typeDefinitionProvider --- src/command_line.cc | 3 +-- src/messages/initialize.cc | 15 +-------------- src/threaded_queue.h | 6 +----- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/command_line.cc b/src/command_line.cc index 215290ea0..3604aca31 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -138,8 +138,7 @@ bool QueryDbMainLoop(QueryDatabase* db, } if (message) { - LOG_S(FATAL) << "Exiting; no handler for " << message->GetMethodType(); - exit(1); + LOG_S(ERROR) << "No handler for " << message->GetMethodType(); } } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 5af936cd2..37440fa9f 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -175,6 +175,7 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, completionProvider, signatureHelpProvider, definitionProvider, + typeDefinitionProvider, referencesProvider, documentHighlightProvider, documentSymbolProvider, @@ -484,20 +485,6 @@ struct Handler_Initialize : BaseMessageHandler { Out_InitializeResponse out; out.id = request->id; - // out.result.capabilities.textDocumentSync = - // lsTextDocumentSyncOptions(); - // out.result.capabilities.textDocumentSync->openClose = true; - // out.result.capabilities.textDocumentSync->change = - // lsTextDocumentSyncKind::Full; - // out.result.capabilities.textDocumentSync->willSave = true; - // out.result.capabilities.textDocumentSync->willSaveWaitUntil = - // true; - -#if USE_CLANG_CXX - out.result.capabilities.documentFormattingProvider = true; - out.result.capabilities.documentRangeFormattingProvider = true; -#endif - QueueManager::WriteStdout(kMethodType, out); // Set project root. diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 5b3608a82..f72950e05 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -2,18 +2,14 @@ #include "utils.h" -#include - -#include #include #include #include #include +#include #include #include -// TODO: cleanup includes. - struct BaseThreadQueue { virtual bool IsEmpty() = 0; virtual ~BaseThreadQueue() = default; From 348240b44f2110950f383c53c966eba6127b5dbf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 5 Apr 2018 17:00:07 -0700 Subject: [PATCH 065/378] Add qual_name_offset to Index* structs; improve workspace/symbol and documentSymbol --- index_tests/class_forward_declaration.cc | 1 + index_tests/constructors/constructor.cc | 5 + index_tests/constructors/destructor.cc | 5 + .../constructors/implicit_constructor.cc | 5 + index_tests/constructors/invalid_reference.cc | 2 + index_tests/constructors/make_functions.cc | 21 ++++ .../declaration_vs_definition/class.cc | 1 + .../declaration_vs_definition/class_member.cc | 3 + .../class_member_static.cc | 3 + index_tests/declaration_vs_definition/func.cc | 1 + .../func_associated_function_params.cc | 4 + .../declaration_vs_definition/method.cc | 4 + index_tests/enums/enum_class_decl.cc | 5 + index_tests/enums/enum_decl.cc | 3 + index_tests/enums/enum_inherit.cc | 8 ++ index_tests/enums/enum_usage.cc | 4 + index_tests/foobar.cc | 6 ++ index_tests/function_declaration.cc | 1 + .../function_declaration_definition.cc | 1 + index_tests/function_definition.cc | 1 + index_tests/inheritance/class_inherit.cc | 2 + .../class_inherit_templated_parent.cc | 8 ++ .../inheritance/class_multiple_inherit.cc | 4 + index_tests/inheritance/function_override.cc | 4 + .../inheritance/interface_pure_virtual.cc | 2 + .../inheritance/multiple_base_functions.cc | 6 ++ index_tests/lambdas/lambda.cc | 7 ++ index_tests/macros/complex.cc | 5 + index_tests/macros/foo.cc | 6 ++ index_tests/method_declaration.cc | 2 + index_tests/method_definition.cc | 2 + index_tests/method_inline_declaration.cc | 2 + index_tests/multi_file/funky_enum.cc | 5 + index_tests/multi_file/impl.cc | 14 +++ index_tests/multi_file/simple_impl.cc | 3 + index_tests/multi_file/static.cc | 4 + index_tests/namespaces/anonymous_function.cc | 2 + .../namespaces/function_declaration.cc | 3 + index_tests/namespaces/function_definition.cc | 3 + index_tests/namespaces/method_declaration.cc | 4 + index_tests/namespaces/method_definition.cc | 4 + .../namespaces/method_inline_declaration.cc | 4 + index_tests/namespaces/namespace_alias.cc | 10 ++ index_tests/namespaces/namespace_reference.cc | 7 ++ index_tests/operators/operator.cc | 5 + .../outline/static_function_in_type.cc | 11 ++ index_tests/preprocessor/include_guard.cc | 1 + .../func_specialized_template_param.cc | 3 + .../implicit_variable_instantiation.cc | 9 ++ .../templates/member_ref_in_template.cc | 5 + ...ass_template_func_usage_folded_into_one.cc | 7 ++ ...ace_template_type_usage_folded_into_one.cc | 5 + index_tests/templates/specialization.cc | 26 +++++ .../templates/specialized_func_definition.cc | 3 + ...mplate_class_func_usage_folded_into_one.cc | 5 + ...ass_template_func_usage_folded_into_one.cc | 5 + ...mplate_class_type_usage_folded_into_one.cc | 6 ++ ...emplate_class_var_usage_folded_into_one.cc | 5 + .../template_func_usage_folded_into_one.cc | 4 + .../template_type_usage_folded_into_one.cc | 3 + .../template_var_usage_folded_into_one.cc | 6 ++ index_tests/types/anonymous_struct.cc | 7 ++ index_tests/types/typedefs.cc | 3 + index_tests/unions/union_decl.cc | 5 + index_tests/unions/union_usage.cc | 7 ++ .../usage/func_called_from_constructor.cc | 3 + .../usage/func_called_from_macro_argument.cc | 3 + .../usage/func_called_from_template.cc | 3 + .../usage/func_called_implicit_ctor.cc | 4 + index_tests/usage/func_usage_addr_func.cc | 4 + index_tests/usage/func_usage_addr_method.cc | 4 + index_tests/usage/func_usage_call_func.cc | 2 + index_tests/usage/func_usage_call_method.cc | 4 + .../usage/func_usage_class_inline_var_def.cc | 4 + .../usage/func_usage_forward_decl_func.cc | 2 + .../usage/func_usage_forward_decl_method.cc | 4 + index_tests/usage/func_usage_template_func.cc | 3 + .../usage/type_usage_as_template_parameter.cc | 6 ++ ...ype_usage_as_template_parameter_complex.cc | 10 ++ ...type_usage_as_template_parameter_simple.cc | 3 + .../usage/type_usage_declare_extern.cc | 2 + index_tests/usage/type_usage_declare_field.cc | 5 + index_tests/usage/type_usage_declare_local.cc | 5 + index_tests/usage/type_usage_declare_param.cc | 5 + .../type_usage_declare_param_prototype.cc | 3 + .../usage/type_usage_declare_param_unnamed.cc | 2 + .../usage/type_usage_declare_qualifiers.cc | 8 ++ .../usage/type_usage_declare_static.cc | 2 + .../usage/type_usage_on_return_type.cc | 7 ++ .../usage/type_usage_typedef_and_using.cc | 10 ++ .../type_usage_typedef_and_using_template.cc | 3 + index_tests/usage/type_usage_various.cc | 4 + index_tests/usage/usage_inside_of_call.cc | 8 ++ .../usage/usage_inside_of_call_simple.cc | 3 + index_tests/usage/var_usage_call_function.cc | 3 + index_tests/usage/var_usage_class_member.cc | 8 ++ .../usage/var_usage_class_member_static.cc | 5 + index_tests/usage/var_usage_cstyle_cast.cc | 3 + index_tests/usage/var_usage_extern.cc | 3 + index_tests/usage/var_usage_func_parameter.cc | 3 + index_tests/usage/var_usage_local.cc | 3 + index_tests/usage/var_usage_shadowed_local.cc | 4 + .../usage/var_usage_shadowed_parameter.cc | 4 + index_tests/usage/var_usage_static.cc | 3 + index_tests/vars/class_member.cc | 2 + index_tests/vars/class_static_member.cc | 2 + .../vars/class_static_member_decl_only.cc | 3 + index_tests/vars/deduce_auto_type.cc | 4 + index_tests/vars/function_local.cc | 3 + index_tests/vars/function_param.cc | 4 + index_tests/vars/function_param_unnamed.cc | 1 + index_tests/vars/function_shadow_local.cc | 4 + index_tests/vars/function_shadow_param.cc | 4 + index_tests/vars/global_variable.cc | 2 + index_tests/vars/global_variable_decl_only.cc | 2 + .../vars/type_instance_on_using_type.cc | 4 + src/clang_indexer.cc | 94 ++++++++++------ src/indexer.h | 100 +++++++----------- src/message_handler.cc | 5 +- src/messages/ccls_call_hierarchy.cc | 23 ++-- src/messages/ccls_inheritance_hierarchy.cc | 31 +++--- src/messages/ccls_member_hierarchy.cc | 55 +++++----- src/messages/text_document_definition.cc | 14 +-- src/messages/workspace_symbol.cc | 8 +- src/query.cc | 38 ++----- src/query.h | 9 +- src/query_utils.cc | 2 +- src/serializer.cc | 3 + src/test.cc | 4 +- src/type_printer.cc | 31 +++--- src/type_printer.h | 7 +- 131 files changed, 737 insertions(+), 215 deletions(-) diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index e2194d759..231a7c445 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -12,6 +12,7 @@ class Foo; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index e779b786d..b36665ad1 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -17,6 +17,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": ["3:3-3:6|-1|1|4"], @@ -34,6 +35,7 @@ void foo() { "id": 0, "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, @@ -50,6 +52,7 @@ void foo() { "id": 1, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -66,6 +69,7 @@ void foo() { "id": 0, "usr": 10983126130596230582, "detailed_name": "Foo f", + "qual_name_offset": 4, "short_name": "f", "declarations": [], "spell": "7:7-7:8|1|3|2", @@ -78,6 +82,7 @@ void foo() { "id": 1, "usr": 17165811951126099095, "detailed_name": "Foo *f2", + "qual_name_offset": 5, "short_name": "f2", "hover": "Foo *f2 = new Foo()", "declarations": [], diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 12482769c..59c464090 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -22,6 +22,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": ["3:3-3:6|-1|1|4", "4:4-4:7|-1|1|4"], @@ -39,6 +40,7 @@ void foo() { "id": 0, "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, @@ -55,6 +57,7 @@ void foo() { "id": 1, "usr": 7440261702884428359, "detailed_name": "void Foo::~Foo() noexcept", + "qual_name_offset": 5, "short_name": "~Foo", "kind": 6, "storage": 1, @@ -71,6 +74,7 @@ void foo() { "id": 2, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -87,6 +91,7 @@ void foo() { "id": 0, "usr": 1893354193220338759, "detailed_name": "Foo f", + "qual_name_offset": 4, "short_name": "f", "declarations": [], "spell": "8:7-8:8|2|3|2", diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index 30589861b..bd7b719e7 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -16,6 +16,7 @@ void Make() { "id": 0, "usr": 13487927231218873822, "detailed_name": "Type", + "qual_name_offset": 0, "short_name": "Type", "kind": 23, "declarations": ["2:3-2:7|-1|1|4"], @@ -33,6 +34,7 @@ void Make() { "id": 0, "usr": 10530961286677896857, "detailed_name": "void Type::Type()", + "qual_name_offset": 5, "short_name": "Type", "kind": 9, "storage": 1, @@ -49,6 +51,7 @@ void Make() { "id": 1, "usr": 3957104924306079513, "detailed_name": "void Make()", + "qual_name_offset": 5, "short_name": "Make", "kind": 12, "storage": 1, @@ -65,6 +68,7 @@ void Make() { "id": 0, "usr": 449111627548814328, "detailed_name": "Type foo0", + "qual_name_offset": 5, "short_name": "foo0", "declarations": [], "spell": "6:8-6:12|1|3|2", @@ -77,6 +81,7 @@ void Make() { "id": 1, "usr": 17097499197730163115, "detailed_name": "Type foo1", + "qual_name_offset": 5, "short_name": "foo1", "declarations": [], "spell": "7:8-7:12|1|3|2", diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 31bacba3f..6b8087932 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -16,6 +16,7 @@ Foo::Foo() {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["4:6-4:9|-1|1|4"], @@ -33,6 +34,7 @@ Foo::Foo() {} "id": 0, "usr": 17319723337446061757, "detailed_name": "void Foo::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index ab2d2cd50..a2c3a4bec 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -32,6 +32,7 @@ OUTPUT: make_functions.h "id": 0, "usr": 12993848456528750350, "detailed_name": "Bar", + "qual_name_offset": 0, "short_name": "Bar", "kind": 23, "declarations": [], @@ -48,6 +49,7 @@ OUTPUT: make_functions.h "id": 1, "usr": 14935975554338052500, "detailed_name": "Foobar", + "qual_name_offset": 0, "short_name": "Foobar", "kind": 5, "declarations": ["5:3-5:9|-1|1|4", "6:3-6:9|-1|1|4", "7:3-7:9|-1|1|4", "8:3-8:9|-1|1|4"], @@ -65,6 +67,7 @@ OUTPUT: make_functions.h "id": 0, "usr": 13131778807733950299, "detailed_name": "void Foobar::Foobar()", + "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, @@ -81,6 +84,7 @@ OUTPUT: make_functions.h "id": 1, "usr": 13028995015627606181, "detailed_name": "void Foobar::Foobar(int)", + "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, @@ -97,6 +101,7 @@ OUTPUT: make_functions.h "id": 2, "usr": 3765833212244435302, "detailed_name": "void Foobar::Foobar(int &&, Bar *, bool *)", + "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, @@ -113,6 +118,7 @@ OUTPUT: make_functions.h "id": 3, "usr": 17321436359755983845, "detailed_name": "void Foobar::Foobar(int, Bar *, bool *)", + "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, @@ -139,6 +145,7 @@ OUTPUT: make_functions.cc "id": 0, "usr": 9281343527065946499, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -155,6 +162,7 @@ OUTPUT: make_functions.cc "id": 1, "usr": 10771590811355716928, "detailed_name": "Args", + "qual_name_offset": 0, "short_name": "Args", "kind": 26, "declarations": [], @@ -171,6 +179,7 @@ OUTPUT: make_functions.cc "id": 2, "usr": 11897454629873246477, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -187,6 +196,7 @@ OUTPUT: make_functions.cc "id": 3, "usr": 3337128087216004141, "detailed_name": "Args", + "qual_name_offset": 0, "short_name": "Args", "kind": 26, "declarations": [], @@ -203,6 +213,7 @@ OUTPUT: make_functions.cc "id": 4, "usr": 14935975554338052500, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -217,6 +228,7 @@ OUTPUT: make_functions.cc "id": 5, "usr": 12993848456528750350, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -232,6 +244,7 @@ OUTPUT: make_functions.cc "id": 0, "usr": 15793662558620604611, "detailed_name": "T *MakeUnique(Args &&... args)", + "qual_name_offset": 3, "short_name": "MakeUnique", "kind": 12, "storage": 1, @@ -247,6 +260,7 @@ OUTPUT: make_functions.cc "id": 1, "usr": 2532818908869373467, "detailed_name": "T *maKE_NoRefs(Args... args)", + "qual_name_offset": 3, "short_name": "maKE_NoRefs", "kind": 12, "storage": 1, @@ -262,6 +276,7 @@ OUTPUT: make_functions.cc "id": 2, "usr": 2816883305867289955, "detailed_name": "void caller22()", + "qual_name_offset": 5, "short_name": "caller22", "kind": 12, "storage": 1, @@ -277,6 +292,7 @@ OUTPUT: make_functions.cc "id": 3, "usr": 13131778807733950299, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, @@ -290,6 +306,7 @@ OUTPUT: make_functions.cc "id": 4, "usr": 13028995015627606181, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, @@ -303,6 +320,7 @@ OUTPUT: make_functions.cc "id": 5, "usr": 3765833212244435302, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, @@ -316,6 +334,7 @@ OUTPUT: make_functions.cc "id": 6, "usr": 17321436359755983845, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, @@ -330,6 +349,7 @@ OUTPUT: make_functions.cc "id": 0, "usr": 8463700030555379526, "detailed_name": "Args &&... args", + "qual_name_offset": 11, "short_name": "args", "declarations": [], "spell": "4:25-4:29|0|3|2", @@ -341,6 +361,7 @@ OUTPUT: make_functions.cc "id": 1, "usr": 3908732770590594660, "detailed_name": "Args... args", + "qual_name_offset": 8, "short_name": "args", "declarations": [], "spell": "9:24-9:28|1|3|2", diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index 00e22bc45..e8c79d619 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -14,6 +14,7 @@ class Foo; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index ccbbd2c91..e51cbddcd 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -11,6 +11,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -27,6 +28,7 @@ class Foo { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -43,6 +45,7 @@ class Foo { "id": 0, "usr": 9736582033442720743, "detailed_name": "int Foo::foo", + "qual_name_offset": 4, "short_name": "foo", "declarations": [], "spell": "2:7-2:10|0|2|2", diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 838913bc7..6dcb0b312 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -13,6 +13,7 @@ int Foo::foo; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -29,6 +30,7 @@ int Foo::foo; "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -45,6 +47,7 @@ int Foo::foo; "id": 0, "usr": 8942920329766232482, "detailed_name": "int Foo::foo", + "qual_name_offset": 4, "short_name": "foo", "declarations": ["2:14-2:17|0|2|1"], "spell": "5:10-5:13|0|2|2", diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index 8e69aeb16..7c73e6f08 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -14,6 +14,7 @@ void foo(); "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index e3aba26f4..ee705c0d2 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -13,6 +13,7 @@ int foo(int a, int b) { return 0; } "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -28,6 +29,7 @@ int foo(int a, int b) { return 0; } "id": 0, "usr": 2747674671862363334, "detailed_name": "int foo(int a, int b)", + "qual_name_offset": 4, "short_name": "foo", "kind": 12, "storage": 1, @@ -53,6 +55,7 @@ int foo(int a, int b) { return 0; } "id": 0, "usr": 14555488990109936920, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "5:13-5:14|0|3|2", @@ -65,6 +68,7 @@ int foo(int a, int b) { return 0; } "id": 1, "usr": 10963664335057337329, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "declarations": [], "spell": "5:20-5:21|0|3|2", diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 1be15a33f..9ce1eb05e 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -15,6 +15,7 @@ void Foo::def() {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -32,6 +33,7 @@ void Foo::def() {} "id": 0, "usr": 4012226004228259562, "detailed_name": "void Foo::declonly()", + "qual_name_offset": 5, "short_name": "declonly", "kind": 6, "storage": 1, @@ -49,6 +51,7 @@ void Foo::def() {} "id": 1, "usr": 10939323144126021546, "detailed_name": "void Foo::purevirtual()", + "qual_name_offset": 5, "short_name": "purevirtual", "kind": 6, "storage": 1, @@ -66,6 +69,7 @@ void Foo::def() {} "id": 2, "usr": 15416083548883122431, "detailed_name": "void Foo::def()", + "qual_name_offset": 5, "short_name": "def", "kind": 6, "storage": 1, diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 6d1cd6fb7..9c0b8adcb 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -13,6 +13,7 @@ enum class Foo : uint8_t { "id": 0, "usr": 5, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -27,6 +28,7 @@ enum class Foo : uint8_t { "id": 1, "usr": 2010430204259339553, "detailed_name": "uint8_t", + "qual_name_offset": 0, "short_name": "uint8_t", "kind": 252, "hover": "typedef unsigned char uint8_t", @@ -45,6 +47,7 @@ enum class Foo : uint8_t { "id": 2, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], @@ -63,6 +66,7 @@ enum class Foo : uint8_t { "id": 0, "usr": 439339022761937396, "detailed_name": "Foo::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], @@ -76,6 +80,7 @@ enum class Foo : uint8_t { "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 9240c5a53..d7a3ec929 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -12,6 +12,7 @@ enum Foo { "id": 0, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], @@ -30,6 +31,7 @@ enum Foo { "id": 0, "usr": 439339022761937396, "detailed_name": "Foo::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], @@ -43,6 +45,7 @@ enum Foo { "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 9ee6bcdfc..7f4a12c5e 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -19,6 +19,7 @@ enum class E : int32_t { "id": 0, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], @@ -35,6 +36,7 @@ enum class E : int32_t { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -49,6 +51,7 @@ enum class E : int32_t { "id": 2, "usr": 14939241684006947339, "detailed_name": "int32_t", + "qual_name_offset": 0, "short_name": "int32_t", "kind": 252, "hover": "typedef int int32_t", @@ -67,6 +70,7 @@ enum class E : int32_t { "id": 3, "usr": 2986879766914123941, "detailed_name": "E", + "qual_name_offset": 0, "short_name": "E", "kind": 10, "declarations": [], @@ -85,6 +89,7 @@ enum class E : int32_t { "id": 0, "usr": 439339022761937396, "detailed_name": "Foo::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], @@ -98,6 +103,7 @@ enum class E : int32_t { "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], @@ -111,6 +117,7 @@ enum class E : int32_t { "id": 2, "usr": 16614320383091394267, "detailed_name": "E::E0", + "qual_name_offset": 0, "short_name": "E0", "hover": "E::E0 = 0", "declarations": [], @@ -124,6 +131,7 @@ enum class E : int32_t { "id": 3, "usr": 16847439761518576294, "detailed_name": "E::E20", + "qual_name_offset": 0, "short_name": "E20", "hover": "E::E20 = 20", "declarations": [], diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index c019a36c3..d18ace6ab 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -14,6 +14,7 @@ Foo x = Foo::A; "id": 0, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], @@ -32,6 +33,7 @@ Foo x = Foo::A; "id": 0, "usr": 439339022761937396, "detailed_name": "Foo::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], @@ -45,6 +47,7 @@ Foo x = Foo::A; "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], @@ -58,6 +61,7 @@ Foo x = Foo::A; "id": 2, "usr": 10677751717622394455, "detailed_name": "Foo x", + "qual_name_offset": 4, "short_name": "x", "hover": "Foo x = Foo::A", "declarations": [], diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 0d240d274..68e2e44a7 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -17,6 +17,7 @@ Foo b; "id": 0, "usr": 6697181287623958829, "detailed_name": "A", + "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], @@ -33,6 +34,7 @@ Foo b; "id": 1, "usr": 13892793056005362145, "detailed_name": "B", + "qual_name_offset": 0, "short_name": "B", "kind": 10, "declarations": [], @@ -49,6 +51,7 @@ Foo b; "id": 2, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -65,6 +68,7 @@ Foo b; "id": 3, "usr": 13938528237873543349, "detailed_name": "Foo::Inner", + "qual_name_offset": 0, "short_name": "Inner", "kind": 23, "declarations": [], @@ -83,6 +87,7 @@ Foo b; "id": 0, "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", + "qual_name_offset": 14, "short_name": "a", "declarations": [], "spell": "9:15-9:16|-1|1|2", @@ -95,6 +100,7 @@ Foo b; "id": 1, "usr": 12028309045033782423, "detailed_name": "Foo b", + "qual_name_offset": 7, "short_name": "b", "declarations": [], "spell": "10:8-10:9|-1|1|2", diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index a9bb6ae13..5f325e411 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -10,6 +10,7 @@ void foo(int a, int b); "id": 0, "usr": 2747674671862363334, "detailed_name": "void foo(int a, int b)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index 7b1f40306..cee467903 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -12,6 +12,7 @@ void foo() {} "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index f4ccb8825..ea8f26802 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -10,6 +10,7 @@ void foo() {} "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index f4e214c9e..1833bb096 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -10,6 +10,7 @@ class Derived : public Parent {}; "id": 0, "usr": 3866412049634585509, "detailed_name": "Parent", + "qual_name_offset": 0, "short_name": "Parent", "kind": 5, "declarations": ["2:24-2:30|-1|1|4"], @@ -26,6 +27,7 @@ class Derived : public Parent {}; "id": 1, "usr": 10963370434658308541, "detailed_name": "Derived", + "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": [], diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index bc12cca6f..3056a4ffa 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -21,6 +21,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 0, "usr": 11930058224338108382, "detailed_name": "Base1", + "qual_name_offset": 0, "short_name": "Base1", "kind": 5, "declarations": ["8:18-8:23|-1|1|4", "13:17-13:22|-1|1|4"], @@ -37,6 +38,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 1, "usr": 11118288764693061434, "detailed_name": "Base2", + "qual_name_offset": 0, "short_name": "Base2", "kind": 5, "declarations": ["11:18-11:23|-1|1|4", "13:27-13:32|-1|1|4"], @@ -53,6 +55,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 2, "usr": 5863733211528032190, "detailed_name": "Derived1", + "qual_name_offset": 0, "short_name": "Derived1", "kind": 5, "declarations": ["13:43-13:51|-1|1|4"], @@ -69,6 +72,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 3, "usr": 9, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -83,6 +87,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 4, "usr": 10651399730831737929, "detailed_name": "Derived2", + "qual_name_offset": 0, "short_name": "Derived2", "kind": 5, "declarations": ["13:56-13:64|-1|1|4"], @@ -99,6 +104,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 5, "usr": 7916588271848318236, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -115,6 +121,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 6, "usr": 10963370434658308541, "detailed_name": "Derived", + "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": ["13:33-13:40|-1|1|4", "13:65-13:72|-1|1|4"], @@ -133,6 +140,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "id": 0, "usr": 12990052348105569112, "detailed_name": "unsigned int T", + "qual_name_offset": 13, "short_name": "T", "declarations": [], "spell": "7:23-7:24|-1|1|2", diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index 785a1bf95..01f3d8a70 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -12,6 +12,7 @@ class Derived : public MiddleA, public MiddleB {}; "id": 0, "usr": 3897841498936210886, "detailed_name": "Root", + "qual_name_offset": 0, "short_name": "Root", "kind": 5, "declarations": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"], @@ -28,6 +29,7 @@ class Derived : public MiddleA, public MiddleB {}; "id": 1, "usr": 11863524815063131483, "detailed_name": "MiddleA", + "qual_name_offset": 0, "short_name": "MiddleA", "kind": 5, "declarations": ["4:24-4:31|-1|1|4"], @@ -44,6 +46,7 @@ class Derived : public MiddleA, public MiddleB {}; "id": 2, "usr": 14022569716337624303, "detailed_name": "MiddleB", + "qual_name_offset": 0, "short_name": "MiddleB", "kind": 5, "declarations": ["4:40-4:47|-1|1|4"], @@ -60,6 +63,7 @@ class Derived : public MiddleA, public MiddleB {}; "id": 3, "usr": 10963370434658308541, "detailed_name": "Derived", + "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": [], diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 36b5d32d7..90cfca91b 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -14,6 +14,7 @@ class Derived : public Root { "id": 0, "usr": 3897841498936210886, "detailed_name": "Root", + "qual_name_offset": 0, "short_name": "Root", "kind": 5, "declarations": ["4:24-4:28|-1|1|4"], @@ -30,6 +31,7 @@ class Derived : public Root { "id": 1, "usr": 10963370434658308541, "detailed_name": "Derived", + "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": [], @@ -47,6 +49,7 @@ class Derived : public Root { "id": 0, "usr": 9948027785633571339, "detailed_name": "void Root::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, @@ -64,6 +67,7 @@ class Derived : public Root { "id": 1, "usr": 6666242542855173890, "detailed_name": "void Derived::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index 69251384d..d9f147c3a 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -11,6 +11,7 @@ class IFoo { "id": 0, "usr": 9949214233977131946, "detailed_name": "IFoo", + "qual_name_offset": 0, "short_name": "IFoo", "kind": 5, "declarations": [], @@ -28,6 +29,7 @@ class IFoo { "id": 0, "usr": 3277829753446788562, "detailed_name": "void IFoo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 6550bb37d..254dfcf6b 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -17,6 +17,7 @@ struct Derived : Base0, Base1 { "id": 0, "usr": 11628904180681204356, "detailed_name": "Base0", + "qual_name_offset": 0, "short_name": "Base0", "kind": 23, "declarations": ["2:12-2:17|-1|1|4", "7:18-7:23|-1|1|4"], @@ -33,6 +34,7 @@ struct Derived : Base0, Base1 { "id": 1, "usr": 15826803741381445676, "detailed_name": "Base1", + "qual_name_offset": 0, "short_name": "Base1", "kind": 23, "declarations": ["5:12-5:17|-1|1|4", "7:25-7:30|-1|1|4"], @@ -49,6 +51,7 @@ struct Derived : Base0, Base1 { "id": 2, "usr": 10963370434658308541, "detailed_name": "Derived", + "qual_name_offset": 0, "short_name": "Derived", "kind": 23, "declarations": ["8:4-8:11|-1|1|4"], @@ -66,6 +69,7 @@ struct Derived : Base0, Base1 { "id": 0, "usr": 16347272523198263017, "detailed_name": "void Base0::~Base0() noexcept", + "qual_name_offset": 5, "short_name": "~Base0", "kind": 6, "storage": 1, @@ -82,6 +86,7 @@ struct Derived : Base0, Base1 { "id": 1, "usr": 8401779086123965305, "detailed_name": "void Base1::~Base1() noexcept", + "qual_name_offset": 5, "short_name": "~Base1", "kind": 6, "storage": 1, @@ -98,6 +103,7 @@ struct Derived : Base0, Base1 { "id": 2, "usr": 13164726294460837993, "detailed_name": "void Derived::~Derived() noexcept", + "qual_name_offset": 5, "short_name": "~Derived", "kind": 6, "storage": 1, diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index e670cc625..5ed38fa39 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -20,6 +20,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -34,6 +35,7 @@ void foo() { "id": 1, "usr": 14635009347499519042, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -49,6 +51,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -64,6 +67,7 @@ void foo() { "id": 1, "usr": 17926497908620168464, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, @@ -78,6 +82,7 @@ void foo() { "id": 0, "usr": 12666114896600231317, "detailed_name": "int x", + "qual_name_offset": 4, "short_name": "x", "declarations": [], "spell": "2:7-2:8|0|3|2", @@ -90,6 +95,7 @@ void foo() { "id": 1, "usr": 2981279427664991319, "detailed_name": "lambda dosomething", + "qual_name_offset": 7, "short_name": "dosomething", "declarations": [], "spell": "4:8-4:19|0|3|2", @@ -102,6 +108,7 @@ void foo() { "id": 2, "usr": 12879188959314906706, "detailed_name": "int y", + "qual_name_offset": 4, "short_name": "y", "declarations": [], "spell": "4:31-4:32|0|3|2", diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 827a67e1f..ae3e23c27 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -20,6 +20,7 @@ FOO(make1(), make2); "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -35,6 +36,7 @@ FOO(make1(), make2); "id": 0, "usr": 14400399977994209582, "detailed_name": "int make1()", + "qual_name_offset": 4, "short_name": "make1", "kind": 12, "storage": 1, @@ -50,6 +52,7 @@ FOO(make1(), make2); "id": 1, "usr": 9720930732776154610, "detailed_name": "int a()", + "qual_name_offset": 4, "short_name": "a", "kind": 12, "storage": 1, @@ -69,6 +72,7 @@ FOO(make1(), make2); "id": 0, "usr": 2878407290385495202, "detailed_name": "const int make2", + "qual_name_offset": 10, "short_name": "make2", "hover": "const int make2 = 5", "declarations": [], @@ -82,6 +86,7 @@ FOO(make1(), make2); "id": 1, "usr": 4261071340275951718, "detailed_name": "FOO", + "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO(aaa, bbb)\n int a();\n int a() { return aaa + bbb; }", "declarations": [], diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 888034438..f03b19de5 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -16,6 +16,7 @@ int x = A; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["5:12-5:15|-1|1|4"], @@ -32,6 +33,7 @@ int x = A; "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -47,6 +49,7 @@ int x = A; "id": 0, "usr": 13788753348312146871, "detailed_name": "void Foo::Foo(Foo &&)", + "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, @@ -64,6 +67,7 @@ int x = A; "id": 0, "usr": 10677751717622394455, "detailed_name": "int x", + "qual_name_offset": 4, "short_name": "x", "hover": "int x = A", "declarations": [], @@ -77,6 +81,7 @@ int x = A; "id": 1, "usr": 7651988378939587454, "detailed_name": "A", + "qual_name_offset": 0, "short_name": "A", "hover": "#define A 5", "declarations": [], @@ -89,6 +94,7 @@ int x = A; "id": 2, "usr": 2056319845419860263, "detailed_name": "DISALLOW", + "qual_name_offset": 0, "short_name": "DISALLOW", "hover": "#define DISALLOW(type) type(type&&) = delete;", "declarations": [], diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index 1b2698dd4..54f5cec85 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -15,6 +15,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -32,6 +33,7 @@ class Foo { "id": 0, "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 8da4a2afe..5ee733c24 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -13,6 +13,7 @@ void Foo::foo() const {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -30,6 +31,7 @@ void Foo::foo() const {} "id": 0, "usr": 6446764306530590711, "detailed_name": "void Foo::foo() const", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index 85cfb39cb..8dcd54489 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -11,6 +11,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -28,6 +29,7 @@ class Foo { "id": 0, "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index d445744fa..44a27cfde 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -14,6 +14,7 @@ OUTPUT: funky_enum.h "id": 0, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 0, "declarations": [], @@ -30,6 +31,7 @@ OUTPUT: funky_enum.h "id": 0, "usr": 439339022761937396, "detailed_name": "Foo::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], @@ -43,6 +45,7 @@ OUTPUT: funky_enum.h "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 1", "declarations": [], @@ -56,6 +59,7 @@ OUTPUT: funky_enum.h "id": 2, "usr": 8524995777615948802, "detailed_name": "Foo::C", + "qual_name_offset": 0, "short_name": "C", "hover": "Foo::C = 2", "declarations": [], @@ -78,6 +82,7 @@ OUTPUT: funky_enum.cc "id": 0, "usr": 16985894625255407295, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 1e3fb85cf..d35cd4496 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -13,6 +13,7 @@ OUTPUT: header.h "id": 0, "usr": 8420119006782424779, "detailed_name": "Base", + "qual_name_offset": 0, "short_name": "Base", "kind": 23, "declarations": ["5:26-5:30|-1|1|4"], @@ -29,6 +30,7 @@ OUTPUT: header.h "id": 1, "usr": 16750616846959666305, "detailed_name": "SameFileDerived", + "qual_name_offset": 0, "short_name": "SameFileDerived", "kind": 23, "declarations": [], @@ -45,6 +47,7 @@ OUTPUT: header.h "id": 2, "usr": 619345544228965342, "detailed_name": "Foo0", + "qual_name_offset": 0, "short_name": "Foo0", "kind": 252, "hover": "using Foo0 = SameFileDerived", @@ -63,6 +66,7 @@ OUTPUT: header.h "id": 3, "usr": 529393482671181129, "detailed_name": "Foo2", + "qual_name_offset": 0, "short_name": "Foo2", "kind": 5, "declarations": [], @@ -79,6 +83,7 @@ OUTPUT: header.h "id": 4, "usr": 4481210672785600703, "detailed_name": "Foo3", + "qual_name_offset": 0, "short_name": "Foo3", "kind": 10, "declarations": [], @@ -95,6 +100,7 @@ OUTPUT: header.h "id": 5, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -110,6 +116,7 @@ OUTPUT: header.h "id": 0, "usr": 11650481237659640387, "detailed_name": "void Foo1()", + "qual_name_offset": 5, "short_name": "Foo1", "kind": 12, "storage": 1, @@ -126,6 +133,7 @@ OUTPUT: header.h "id": 0, "usr": 6141718166919284735, "detailed_name": "Foo3::A", + "qual_name_offset": 0, "short_name": "A", "hover": "Foo3::A = 0", "declarations": [], @@ -139,6 +147,7 @@ OUTPUT: header.h "id": 1, "usr": 17716334512218775320, "detailed_name": "Foo3::B", + "qual_name_offset": 0, "short_name": "B", "hover": "Foo3::B = 1", "declarations": [], @@ -152,6 +161,7 @@ OUTPUT: header.h "id": 2, "usr": 7285646116511901840, "detailed_name": "Foo3::C", + "qual_name_offset": 0, "short_name": "C", "hover": "Foo3::C = 2", "declarations": [], @@ -165,6 +175,7 @@ OUTPUT: header.h "id": 3, "usr": 2638219001294786365, "detailed_name": "int Foo4", + "qual_name_offset": 4, "short_name": "Foo4", "declarations": [], "spell": "17:5-17:9|-1|1|2", @@ -177,6 +188,7 @@ OUTPUT: header.h "id": 4, "usr": 8395885290297540138, "detailed_name": "int Foo5", + "qual_name_offset": 4, "short_name": "Foo5", "declarations": [], "spell": "18:12-18:16|-1|1|2", @@ -199,6 +211,7 @@ OUTPUT: impl.cc "id": 0, "usr": 5817708529036841195, "detailed_name": "void Impl()", + "qual_name_offset": 5, "short_name": "Impl", "kind": 12, "storage": 1, @@ -214,6 +227,7 @@ OUTPUT: impl.cc "id": 1, "usr": 11650481237659640387, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index d322603a4..1c67f9414 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -14,6 +14,7 @@ OUTPUT: simple_header.h "id": 0, "usr": 16236105532929924676, "detailed_name": "void header()", + "qual_name_offset": 5, "short_name": "header", "kind": 12, "storage": 1, @@ -41,6 +42,7 @@ OUTPUT: simple_impl.cc "id": 0, "usr": 3373269392705484958, "detailed_name": "void impl()", + "qual_name_offset": 5, "short_name": "impl", "kind": 12, "storage": 1, @@ -56,6 +58,7 @@ OUTPUT: simple_impl.cc "id": 1, "usr": 16236105532929924676, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "storage": 0, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 8ad0f72de..c5cfebcc1 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -11,6 +11,7 @@ OUTPUT: static.h "id": 0, "usr": 9411323049603567600, "detailed_name": "Buffer", + "qual_name_offset": 0, "short_name": "Buffer", "kind": 23, "declarations": [], @@ -28,6 +29,7 @@ OUTPUT: static.h "id": 0, "usr": 14576076421851654759, "detailed_name": "void Buffer::CreateSharedBuffer()", + "qual_name_offset": 5, "short_name": "CreateSharedBuffer", "kind": 254, "storage": 3, @@ -55,6 +57,7 @@ OUTPUT: static.cc "id": 0, "usr": 9411323049603567600, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -70,6 +73,7 @@ OUTPUT: static.cc "id": 0, "usr": 14576076421851654759, "detailed_name": "void Buffer::CreateSharedBuffer()", + "qual_name_offset": 5, "short_name": "CreateSharedBuffer", "kind": 254, "storage": 1, diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 17905fe29..701ab8555 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -11,6 +11,7 @@ void foo(); "id": 0, "usr": 7144845543074395457, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -26,6 +27,7 @@ void foo(); "id": 0, "usr": 5010253035933134245, "detailed_name": "void (anon)::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 7c6ba361d..18f81f7ca 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -11,6 +11,7 @@ void foo(int a, int b); "id": 0, "usr": 2029211996748007610, "detailed_name": "hello", + "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], @@ -27,6 +28,7 @@ void foo(int a, int b); "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -42,6 +44,7 @@ void foo(int a, int b); "id": 0, "usr": 18343102288837190527, "detailed_name": "void hello::foo(int a, int b)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index 5ccd8254f..1ae23ab38 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -11,6 +11,7 @@ void foo() {} "id": 0, "usr": 2029211996748007610, "detailed_name": "hello", + "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], @@ -27,6 +28,7 @@ void foo() {} "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -42,6 +44,7 @@ void foo() {} "id": 0, "usr": 243328841292951622, "detailed_name": "void hello::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index 37687fd38..d66e1ab37 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -13,6 +13,7 @@ class Foo { "id": 0, "usr": 2029211996748007610, "detailed_name": "hello", + "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], @@ -29,6 +30,7 @@ class Foo { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -43,6 +45,7 @@ class Foo { "id": 2, "usr": 4508214972876735896, "detailed_name": "hello::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -60,6 +63,7 @@ class Foo { "id": 0, "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 4df6edf13..2149a0377 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -15,6 +15,7 @@ void Foo::foo() {} "id": 0, "usr": 2029211996748007610, "detailed_name": "hello", + "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], @@ -31,6 +32,7 @@ void Foo::foo() {} "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -45,6 +47,7 @@ void Foo::foo() {} "id": 2, "usr": 4508214972876735896, "detailed_name": "hello::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -62,6 +65,7 @@ void Foo::foo() {} "id": 0, "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index 9d0b940fc..d38f8f8cf 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -13,6 +13,7 @@ class Foo { "id": 0, "usr": 2029211996748007610, "detailed_name": "hello", + "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], @@ -29,6 +30,7 @@ class Foo { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -43,6 +45,7 @@ class Foo { "id": 2, "usr": 4508214972876735896, "detailed_name": "hello::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -60,6 +63,7 @@ class Foo { "id": 0, "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 8fa504385..2c8280f5e 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -22,6 +22,7 @@ void func() { "id": 0, "usr": 926793467007732869, "detailed_name": "foo", + "qual_name_offset": 0, "short_name": "foo", "kind": 3, "declarations": [], @@ -38,6 +39,7 @@ void func() { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -52,6 +54,7 @@ void func() { "id": 2, "usr": 17805385787823406700, "detailed_name": "foo::bar", + "qual_name_offset": 0, "short_name": "bar", "kind": 3, "declarations": [], @@ -68,6 +71,7 @@ void func() { "id": 3, "usr": 14450849931009540802, "detailed_name": "foo::bar::baz", + "qual_name_offset": 0, "short_name": "baz", "kind": 3, "declarations": [], @@ -84,6 +88,7 @@ void func() { "id": 4, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -98,6 +103,7 @@ void func() { "id": 5, "usr": 11879713791858506216, "detailed_name": "fbz", + "qual_name_offset": 0, "short_name": "fbz", "kind": 0, "declarations": [], @@ -115,6 +121,7 @@ void func() { "id": 0, "usr": 10818727483146447186, "detailed_name": "void func()", + "qual_name_offset": 5, "short_name": "func", "kind": 12, "storage": 1, @@ -131,6 +138,7 @@ void func() { "id": 0, "usr": 15042442838933090518, "detailed_name": "int foo::bar::baz::qux", + "qual_name_offset": 4, "short_name": "qux", "hover": "int foo::bar::baz::qux = 42", "declarations": [], @@ -144,6 +152,7 @@ void func() { "id": 1, "usr": 6030927277961448585, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = foo::bar::baz::qux", "declarations": [], @@ -157,6 +166,7 @@ void func() { "id": 2, "usr": 7657277353101371136, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "hover": "int b = fbz::qux", "declarations": [], diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index a8383d89c..cf559e1c7 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -18,6 +18,7 @@ void Runner() { "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -34,6 +35,7 @@ void Runner() { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -48,6 +50,7 @@ void Runner() { "id": 2, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -63,6 +66,7 @@ void Runner() { "id": 0, "usr": 17328473273923617489, "detailed_name": "void ns::Accept(int a)", + "qual_name_offset": 5, "short_name": "Accept", "kind": 12, "storage": 1, @@ -79,6 +83,7 @@ void Runner() { "id": 1, "usr": 631910859630953711, "detailed_name": "void Runner()", + "qual_name_offset": 5, "short_name": "Runner", "kind": 12, "storage": 1, @@ -95,6 +100,7 @@ void Runner() { "id": 0, "usr": 12898699035586282159, "detailed_name": "int ns::Foo", + "qual_name_offset": 4, "short_name": "Foo", "declarations": [], "spell": "2:7-2:10|0|2|2", @@ -107,6 +113,7 @@ void Runner() { "id": 1, "usr": 3649375698083002347, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "3:19-3:20|0|3|2", diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index dc8151b0f..0624270b3 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -15,6 +15,7 @@ Foo &operator += (const Foo&, const int&); "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -32,6 +33,7 @@ Foo &operator += (const Foo&, const int&); "id": 0, "usr": 7874436189163837815, "detailed_name": "void Foo::operator()(int)", + "qual_name_offset": 5, "short_name": "operator()", "kind": 6, "storage": 1, @@ -48,6 +50,7 @@ Foo &operator += (const Foo&, const int&); "id": 1, "usr": 3545323327609582678, "detailed_name": "void Foo::operator()(bool)", + "qual_name_offset": 5, "short_name": "operator()", "kind": 6, "storage": 1, @@ -65,6 +68,7 @@ Foo &operator += (const Foo&, const int&); "id": 2, "usr": 3986818119971932909, "detailed_name": "int Foo::operator()(int a, int b)", + "qual_name_offset": 4, "short_name": "operator()", "kind": 6, "storage": 1, @@ -82,6 +86,7 @@ Foo &operator += (const Foo&, const int&); "id": 3, "usr": 8288368475529136092, "detailed_name": "Foo &operator+=(const Foo &, const int &)", + "qual_name_offset": 5, "short_name": "operator+=", "kind": 12, "storage": 1, diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 682ca165d..9d05094f5 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -15,6 +15,7 @@ OUTPUT: static_function_in_type.h "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -31,6 +32,7 @@ OUTPUT: static_function_in_type.h "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -45,6 +47,7 @@ OUTPUT: static_function_in_type.h "id": 2, "usr": 1972401196751872203, "detailed_name": "ns::Manager", + "qual_name_offset": 0, "short_name": "Manager", "kind": 5, "declarations": ["3:7-3:14|0|2|1"], @@ -59,6 +62,7 @@ OUTPUT: static_function_in_type.h "id": 3, "usr": 17262466801709381811, "detailed_name": "ns::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -76,6 +80,7 @@ OUTPUT: static_function_in_type.h "id": 0, "usr": 17019747379608639279, "detailed_name": "void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 5, "short_name": "Register", "kind": 254, "storage": 3, @@ -103,6 +108,7 @@ OUTPUT: static_function_in_type.cc "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -119,6 +125,7 @@ OUTPUT: static_function_in_type.cc "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -133,6 +140,7 @@ OUTPUT: static_function_in_type.cc "id": 2, "usr": 17262466801709381811, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -147,6 +155,7 @@ OUTPUT: static_function_in_type.cc "id": 3, "usr": 1972401196751872203, "detailed_name": "ns::Manager", + "qual_name_offset": 0, "short_name": "Manager", "kind": 0, "declarations": [], @@ -162,6 +171,7 @@ OUTPUT: static_function_in_type.cc "id": 0, "usr": 17019747379608639279, "detailed_name": "void ns::Foo::Register(ns::Manager *m)", + "qual_name_offset": 5, "short_name": "Register", "kind": 254, "storage": 1, @@ -179,6 +189,7 @@ OUTPUT: static_function_in_type.cc "id": 0, "usr": 13569879755236306838, "detailed_name": "ns::Manager *m", + "qual_name_offset": 13, "short_name": "m", "declarations": [], "spell": "5:29-5:30|0|3|2", diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 764e434ca..592fab713 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -14,6 +14,7 @@ "id": 0, "usr": 11674328179498211370, "detailed_name": "FOO", + "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO", "declarations": [], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index cdcb516c9..d1da2699e 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -16,6 +16,7 @@ void Foo::Bar(Template&) {} "id": 0, "usr": 17107291254533526269, "detailed_name": "Template", + "qual_name_offset": 0, "short_name": "Template", "kind": 5, "declarations": [], @@ -32,6 +33,7 @@ void Foo::Bar(Template&) {} "id": 1, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -49,6 +51,7 @@ void Foo::Bar(Template&) {} "id": 0, "usr": 8412238651648388423, "detailed_name": "void Foo::Bar(Template &)", + "qual_name_offset": 5, "short_name": "Bar", "kind": 6, "storage": 1, diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index b4ef6130c..42a89405a 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -23,6 +23,7 @@ namespace ns { "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -39,6 +40,7 @@ namespace ns { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -53,6 +55,7 @@ namespace ns { "id": 2, "usr": 1532099849728741556, "detailed_name": "ns::VarType", + "qual_name_offset": 0, "short_name": "VarType", "kind": 10, "declarations": [], @@ -69,6 +72,7 @@ namespace ns { "id": 3, "usr": 12688716854043726585, "detailed_name": "ns::Holder", + "qual_name_offset": 0, "short_name": "Holder", "kind": 5, "declarations": [], @@ -85,6 +89,7 @@ namespace ns { "id": 4, "usr": 2205716167465743256, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -99,6 +104,7 @@ namespace ns { "id": 5, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -115,6 +121,7 @@ namespace ns { "id": 0, "usr": 4731849186641714451, "detailed_name": "const ns::VarType ns::Holder::static_var", + "qual_name_offset": 18, "short_name": "static_var", "hover": "const ns::VarType ns::Holder::static_var = (VarType)0x0", "declarations": ["6:30-6:40|3|2|1"], @@ -128,6 +135,7 @@ namespace ns { "id": 1, "usr": 12898699035586282159, "detailed_name": "int ns::Foo", + "qual_name_offset": 4, "short_name": "Foo", "hover": "int ns::Foo = Holder::static_var", "declarations": [], @@ -141,6 +149,7 @@ namespace ns { "id": 2, "usr": 9008550860229740818, "detailed_name": "int ns::Foo2", + "qual_name_offset": 4, "short_name": "Foo2", "hover": "int ns::Foo2 = Holder::static_var", "declarations": [], diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index 7044a041a..f3bed2b21 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -29,6 +29,7 @@ void foo() { "id": 0, "usr": 8402783583255987702, "detailed_name": "C", + "qual_name_offset": 0, "short_name": "C", "kind": 5, "declarations": [], @@ -45,6 +46,7 @@ void foo() { "id": 1, "usr": 14750650276757822712, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -62,6 +64,7 @@ void foo() { "id": 0, "usr": 8905286151237717330, "detailed_name": "void C::bar()", + "qual_name_offset": 5, "short_name": "bar", "kind": 6, "storage": 1, @@ -79,6 +82,7 @@ void foo() { "id": 1, "usr": 6875364467121018690, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -95,6 +99,7 @@ void foo() { "id": 0, "usr": 5866801090710377175, "detailed_name": "T C::x", + "qual_name_offset": 2, "short_name": "x", "declarations": [], "spell": "3:5-3:6|0|2|2", diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index c7e77d6e7..da7af9dd0 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -20,6 +20,7 @@ namespace ns { "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -36,6 +37,7 @@ namespace ns { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -50,6 +52,7 @@ namespace ns { "id": 2, "usr": 14042997404480181958, "detailed_name": "ns::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -66,6 +69,7 @@ namespace ns { "id": 3, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -81,6 +85,7 @@ namespace ns { "id": 0, "usr": 8221803074608342407, "detailed_name": "int ns::Foo::foo()", + "qual_name_offset": 4, "short_name": "foo", "kind": 254, "storage": 3, @@ -98,6 +103,7 @@ namespace ns { "id": 0, "usr": 15768138241775955040, "detailed_name": "int ns::a", + "qual_name_offset": 4, "short_name": "a", "hover": "int ns::a = Foo::foo()", "declarations": [], @@ -111,6 +117,7 @@ namespace ns { "id": 1, "usr": 3182917058194750998, "detailed_name": "int ns::b", + "qual_name_offset": 4, "short_name": "b", "hover": "int ns::b = Foo::foo()", "declarations": [], diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 61a53f894..c1a8ae9d6 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -15,6 +15,7 @@ namespace ns { "id": 0, "usr": 11072669167287398027, "detailed_name": "ns", + "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], @@ -31,6 +32,7 @@ namespace ns { "id": 1, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -45,6 +47,7 @@ namespace ns { "id": 2, "usr": 14042997404480181958, "detailed_name": "ns::Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -63,6 +66,7 @@ namespace ns { "id": 0, "usr": 15768138241775955040, "detailed_name": "Foo ns::a", + "qual_name_offset": 9, "short_name": "a", "declarations": [], "spell": "5:12-5:13|0|2|2", @@ -75,6 +79,7 @@ namespace ns { "id": 1, "usr": 3182917058194750998, "detailed_name": "Foo ns::b", + "qual_name_offset": 10, "short_name": "b", "declarations": [], "spell": "6:13-6:14|0|2|2", diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 2b75f557e..840493fa0 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -51,6 +51,7 @@ void foo(float Value); "id": 0, "usr": 15019211479263750068, "detailed_name": "function", + "qual_name_offset": 0, "short_name": "function", "kind": 5, "declarations": ["2:7-2:15|-1|1|1", "5:7-5:15|-1|1|4"], @@ -67,6 +68,7 @@ void foo(float Value); "id": 1, "usr": 218068462278884837, "detailed_name": "function", + "qual_name_offset": 0, "short_name": "function", "kind": 5, "declarations": [], @@ -83,6 +85,7 @@ void foo(float Value); "id": 2, "usr": 9673599782548740467, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -99,6 +102,7 @@ void foo(float Value); "id": 3, "usr": 7143192229126273961, "detailed_name": "Args", + "qual_name_offset": 0, "short_name": "Args", "kind": 26, "declarations": [], @@ -115,6 +119,7 @@ void foo(float Value); "id": 4, "usr": 15695704394170757108, "detailed_name": "allocator", + "qual_name_offset": 0, "short_name": "allocator", "kind": 5, "declarations": ["9:28-9:37|-1|1|1", "11:39-11:48|-1|1|4"], @@ -129,6 +134,7 @@ void foo(float Value); "id": 5, "usr": 7440942986741176606, "detailed_name": "vector", + "qual_name_offset": 0, "short_name": "vector", "kind": 5, "declarations": ["17:7-17:13|-1|1|4", "26:7-26:13|-1|1|4"], @@ -145,6 +151,7 @@ void foo(float Value); "id": 6, "usr": 16155717907537731864, "detailed_name": "vector", + "qual_name_offset": 0, "short_name": "vector", "kind": 5, "declarations": [], @@ -161,6 +168,7 @@ void foo(float Value); "id": 7, "usr": 8880262253425334092, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -177,6 +185,7 @@ void foo(float Value); "id": 8, "usr": 5760043510674081814, "detailed_name": "Z1", + "qual_name_offset": 0, "short_name": "Z1", "kind": 23, "declarations": [], @@ -193,6 +202,7 @@ void foo(float Value); "id": 9, "usr": 10124869160135436852, "detailed_name": "Z2", + "qual_name_offset": 0, "short_name": "Z2", "kind": 23, "declarations": ["26:14-26:16|-1|1|4"], @@ -209,6 +219,7 @@ void foo(float Value); "id": 10, "usr": 1663022413889915338, "detailed_name": "vector", + "qual_name_offset": 0, "short_name": "vector", "kind": 5, "declarations": [], @@ -225,6 +236,7 @@ void foo(float Value); "id": 11, "usr": 9201299975592934124, "detailed_name": "Enum", + "qual_name_offset": 0, "short_name": "Enum", "kind": 10, "declarations": [], @@ -241,6 +253,7 @@ void foo(float Value); "id": 12, "usr": 14111105212951082474, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -257,6 +270,7 @@ void foo(float Value); "id": 13, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -272,6 +286,7 @@ void foo(float Value); "id": 0, "usr": 18107614608385228556, "detailed_name": "void vector::clear()", + "qual_name_offset": 5, "short_name": "clear", "kind": 6, "storage": 1, @@ -289,6 +304,7 @@ void foo(float Value); "id": 1, "usr": 6113470698424012876, "detailed_name": "void vector::clear()", + "qual_name_offset": 5, "short_name": "clear", "kind": 6, "storage": 1, @@ -306,6 +322,7 @@ void foo(float Value); "id": 2, "usr": 17498190318698490707, "detailed_name": "void foo(T Value)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -325,6 +342,7 @@ void foo(float Value); "id": 0, "usr": 2933643612409209903, "detailed_name": "function f", + "qual_name_offset": 21, "short_name": "f", "declarations": [], "spell": "7:21-7:22|-1|1|2", @@ -337,6 +355,7 @@ void foo(float Value); "id": 1, "usr": 5792869548777559988, "detailed_name": "vector vc", + "qual_name_offset": 13, "short_name": "vc", "declarations": [], "spell": "30:14-30:16|-1|1|2", @@ -349,6 +368,7 @@ void foo(float Value); "id": 2, "usr": 86949563628772958, "detailed_name": "vector vip", + "qual_name_offset": 14, "short_name": "vip", "declarations": [], "spell": "31:14-31:17|-1|1|2", @@ -361,6 +381,7 @@ void foo(float Value); "id": 3, "usr": 3566687051827176322, "detailed_name": "vector vz1", + "qual_name_offset": 11, "short_name": "vz1", "declarations": [], "spell": "32:12-32:15|-1|1|2", @@ -373,6 +394,7 @@ void foo(float Value); "id": 4, "usr": 15931696253641284761, "detailed_name": "vector vz2", + "qual_name_offset": 11, "short_name": "vz2", "declarations": [], "spell": "33:12-33:15|-1|1|2", @@ -385,6 +407,7 @@ void foo(float Value); "id": 5, "usr": 15477793821005285152, "detailed_name": "Enum::Enum0", + "qual_name_offset": 0, "short_name": "Enum0", "hover": "Enum::Enum0 = 0", "declarations": [], @@ -398,6 +421,7 @@ void foo(float Value); "id": 6, "usr": 4917621020431490070, "detailed_name": "Enum::Enum1", + "qual_name_offset": 0, "short_name": "Enum1", "hover": "Enum::Enum1 = 1", "declarations": [], @@ -411,6 +435,7 @@ void foo(float Value); "id": 7, "usr": 17826688417349629938, "detailed_name": "T Value", + "qual_name_offset": 2, "short_name": "Value", "declarations": [], "spell": "39:12-39:17|2|3|2", @@ -422,6 +447,7 @@ void foo(float Value); "id": 8, "usr": 13914496963221806870, "detailed_name": "const int kOnst", + "qual_name_offset": 10, "short_name": "kOnst", "hover": "const int kOnst = 7", "declarations": [], diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index e39308f9f..9f00bd05a 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -26,6 +26,7 @@ void Template::Foo() {} "id": 0, "usr": 17107291254533526269, "detailed_name": "Template", + "qual_name_offset": 0, "short_name": "Template", "kind": 5, "declarations": [], @@ -42,6 +43,7 @@ void Template::Foo() {} "id": 1, "usr": 17649312483543982122, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -57,6 +59,7 @@ void Template::Foo() {} "id": 0, "usr": 11994188353303124840, "detailed_name": "void Template::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 6, "storage": 1, diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 733db96f3..e4b9bdf56 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -17,6 +17,7 @@ int b = Foo::foo(); "id": 0, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -33,6 +34,7 @@ int b = Foo::foo(); "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -48,6 +50,7 @@ int b = Foo::foo(); "id": 0, "usr": 8340731781048851399, "detailed_name": "int Foo::foo()", + "qual_name_offset": 4, "short_name": "foo", "kind": 254, "storage": 3, @@ -65,6 +68,7 @@ int b = Foo::foo(); "id": 0, "usr": 16721564935990383768, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::foo()", "declarations": [], @@ -78,6 +82,7 @@ int b = Foo::foo(); "id": 1, "usr": 12028309045033782423, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::foo()", "declarations": [], diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 7ee252b42..04c36e50d 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -18,6 +18,7 @@ int b = Foo::foo(); "id": 0, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -34,6 +35,7 @@ int b = Foo::foo(); "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -49,6 +51,7 @@ int b = Foo::foo(); "id": 0, "usr": 9034026360701857235, "detailed_name": "int Foo::foo()", + "qual_name_offset": 4, "short_name": "foo", "kind": 254, "storage": 3, @@ -66,6 +69,7 @@ int b = Foo::foo(); "id": 0, "usr": 16721564935990383768, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::foo()", "declarations": [], @@ -79,6 +83,7 @@ int b = Foo::foo(); "id": 1, "usr": 12028309045033782423, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::foo()", "declarations": [], diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index c0b611ce8..063f755b8 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -36,6 +36,7 @@ VarDecl b "id": 0, "usr": 6697181287623958829, "detailed_name": "A", + "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], @@ -52,6 +53,7 @@ VarDecl b "id": 1, "usr": 13892793056005362145, "detailed_name": "B", + "qual_name_offset": 0, "short_name": "B", "kind": 10, "declarations": [], @@ -68,6 +70,7 @@ VarDecl b "id": 2, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -84,6 +87,7 @@ VarDecl b "id": 3, "usr": 13938528237873543349, "detailed_name": "Foo::Inner", + "qual_name_offset": 0, "short_name": "Inner", "kind": 23, "declarations": [], @@ -102,6 +106,7 @@ VarDecl b "id": 0, "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", + "qual_name_offset": 14, "short_name": "a", "declarations": [], "spell": "9:15-9:16|-1|1|2", @@ -114,6 +119,7 @@ VarDecl b "id": 1, "usr": 12028309045033782423, "detailed_name": "Foo::Inner b", + "qual_name_offset": 14, "short_name": "b", "declarations": [], "spell": "10:15-10:16|-1|1|2", diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index fa19a31db..f18538787 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -15,6 +15,7 @@ int b = Foo::var; "id": 0, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -31,6 +32,7 @@ int b = Foo::var; "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -47,6 +49,7 @@ int b = Foo::var; "id": 0, "usr": 13545144895171991916, "detailed_name": "const int Foo::var", + "qual_name_offset": 10, "short_name": "var", "hover": "const int Foo::var = 3", "declarations": ["3:24-3:27|0|2|1"], @@ -58,6 +61,7 @@ int b = Foo::var; "id": 1, "usr": 16721564935990383768, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::var", "declarations": [], @@ -71,6 +75,7 @@ int b = Foo::var; "id": 2, "usr": 12028309045033782423, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::var", "declarations": [], diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index 79bca7211..9a60681c8 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -18,6 +18,7 @@ int b = foo(); "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -33,6 +34,7 @@ int b = foo(); "id": 0, "usr": 326583651986177228, "detailed_name": "int foo()", + "qual_name_offset": 4, "short_name": "foo", "kind": 12, "storage": 3, @@ -49,6 +51,7 @@ int b = foo(); "id": 0, "usr": 16721564935990383768, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = foo()", "declarations": [], @@ -62,6 +65,7 @@ int b = foo(); "id": 1, "usr": 12028309045033782423, "detailed_name": "int b", + "qual_name_offset": 4, "short_name": "b", "hover": "int b = foo()", "declarations": [], diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 0cc76af94..8a53c1cc9 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -13,6 +13,7 @@ Foo b; "id": 0, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -31,6 +32,7 @@ Foo b; "id": 0, "usr": 16721564935990383768, "detailed_name": "Foo a", + "qual_name_offset": 9, "short_name": "a", "declarations": [], "spell": "4:10-4:11|-1|1|2", @@ -43,6 +45,7 @@ Foo b; "id": 1, "usr": 12028309045033782423, "detailed_name": "Foo b", + "qual_name_offset": 10, "short_name": "b", "declarations": [], "spell": "5:11-5:12|-1|1|2", diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 5d7464e93..02e01c73f 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -39,6 +39,7 @@ UnexposedDecl var "id": 0, "usr": 6697181287623958829, "detailed_name": "A", + "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], @@ -55,6 +56,7 @@ UnexposedDecl var "id": 1, "usr": 13892793056005362145, "detailed_name": "B", + "qual_name_offset": 0, "short_name": "B", "kind": 10, "declarations": [], @@ -71,6 +73,7 @@ UnexposedDecl var "id": 2, "usr": 11919899838872947844, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -87,6 +90,7 @@ UnexposedDecl var "id": 0, "usr": 8096973118640070624, "detailed_name": "T var", + "qual_name_offset": 2, "short_name": "var", "declarations": [], "spell": "5:3-5:6|-1|1|2", @@ -98,6 +102,7 @@ UnexposedDecl var "id": 1, "usr": 16721564935990383768, "detailed_name": "A a", + "qual_name_offset": 2, "short_name": "a", "hover": "A a = var", "declarations": [], @@ -111,6 +116,7 @@ UnexposedDecl var "id": 2, "usr": 12028309045033782423, "detailed_name": "B b", + "qual_name_offset": 2, "short_name": "b", "hover": "B b = var", "declarations": [], diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 8a975693c..32b4ea6f1 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -12,6 +12,7 @@ union vector3 { "id": 0, "usr": 17937907487590875128, "detailed_name": "vector3", + "qual_name_offset": 0, "short_name": "vector3", "kind": 23, "declarations": [], @@ -28,6 +29,7 @@ union vector3 { "id": 1, "usr": 1428566502523368801, "detailed_name": "vector3::(anon struct)", + "qual_name_offset": 0, "short_name": "(anon struct)", "kind": 23, "declarations": [], @@ -44,6 +46,7 @@ union vector3 { "id": 2, "usr": 21, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -60,6 +63,7 @@ union vector3 { "id": 0, "usr": 3348817847649945564, "detailed_name": "float vector3::(anon struct)::x", + "qual_name_offset": 6, "short_name": "x", "declarations": [], "spell": "2:18-2:19|1|2|2", @@ -72,6 +76,7 @@ union vector3 { "id": 1, "usr": 4821094820988543895, "detailed_name": "float vector3::(anon struct)::y", + "qual_name_offset": 6, "short_name": "y", "declarations": [], "spell": "2:21-2:22|1|2|2", @@ -84,6 +89,7 @@ union vector3 { "id": 2, "usr": 15292551660437765731, "detailed_name": "float vector3::(anon struct)::z", + "qual_name_offset": 6, "short_name": "z", "declarations": [], "spell": "2:24-2:25|1|2|2", @@ -96,6 +102,7 @@ union vector3 { "id": 3, "usr": 1963212417280098348, "detailed_name": "float [3] vector3::v", + "qual_name_offset": 10, "short_name": "v", "declarations": [], "spell": "3:9-3:10|0|2|2", diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index b11c9eee9..90a30b68d 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -10,6 +10,7 @@ static func g; "id": 0, "usr": 13838176792705659279, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -24,6 +25,7 @@ static func g; "id": 1, "usr": 10383876566159302459, "detailed_name": "func", + "qual_name_offset": 0, "short_name": "func", "kind": 252, "hover": "typedef int (func)(const int *a, const int *b)", @@ -43,6 +45,7 @@ static func g; "id": 0, "usr": 8105378401105136463, "detailed_name": "func g", + "qual_name_offset": 5, "short_name": "g", "kind": 12, "storage": 3, diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index e3e0c5014..519ddfdab 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -12,6 +12,7 @@ union Foo { "id": 0, "usr": 8501689086387244262, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -28,6 +29,7 @@ union Foo { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -42,6 +44,7 @@ union Foo { "id": 2, "usr": 3, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -58,6 +61,7 @@ union Foo { "id": 0, "usr": 9529311430721959843, "detailed_name": "int Foo::a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "2:7-2:8|0|2|2", @@ -70,6 +74,7 @@ union Foo { "id": 1, "usr": 8804696910588009104, "detailed_name": "bool Foo::b", + "qual_name_offset": 5, "short_name": "b", "declarations": [], "spell": "3:8-3:9|0|2|2", diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index bdc57e034..a91b4e370 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -20,6 +20,7 @@ void act(Foo*) { "id": 0, "usr": 8501689086387244262, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -36,6 +37,7 @@ void act(Foo*) { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -50,6 +52,7 @@ void act(Foo*) { "id": 2, "usr": 3, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -65,6 +68,7 @@ void act(Foo*) { "id": 0, "usr": 13982179977217945200, "detailed_name": "void act(Foo *)", + "qual_name_offset": 5, "short_name": "act", "kind": 12, "storage": 1, @@ -81,6 +85,7 @@ void act(Foo*) { "id": 0, "usr": 9529311430721959843, "detailed_name": "int Foo::a", + "qual_name_offset": 4, "short_name": "a", "hover": "int Foo::a : 5", "declarations": [], @@ -94,6 +99,7 @@ void act(Foo*) { "id": 1, "usr": 8804696910588009104, "detailed_name": "bool Foo::b", + "qual_name_offset": 5, "short_name": "b", "hover": "bool Foo::b : 3", "declarations": [], @@ -107,6 +113,7 @@ void act(Foo*) { "id": 2, "usr": 2933643612409209903, "detailed_name": "Foo f", + "qual_name_offset": 4, "short_name": "f", "declarations": [], "spell": "6:5-6:6|-1|1|2", diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 92cc92620..81aedbd40 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -17,6 +17,7 @@ Foo::Foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["4:3-4:6|-1|1|4", "7:6-7:9|-1|1|4"], @@ -34,6 +35,7 @@ Foo::Foo() { "id": 0, "usr": 468307235068920063, "detailed_name": "void called()", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -49,6 +51,7 @@ Foo::Foo() { "id": 1, "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 42adc3258..6514adae3 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -16,6 +16,7 @@ void caller() { "id": 0, "usr": 3787803219955606747, "detailed_name": "bool called(bool a, bool b)", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -32,6 +33,7 @@ void caller() { "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", + "qual_name_offset": 5, "short_name": "caller", "kind": 12, "storage": 1, @@ -48,6 +50,7 @@ void caller() { "id": 0, "usr": 1290746656694198202, "detailed_name": "MACRO_CALL", + "qual_name_offset": 0, "short_name": "MACRO_CALL", "hover": "#define MACRO_CALL(e) e", "declarations": [], diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 14e8e3069..1840fb154 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -21,6 +21,7 @@ void foo() { "id": 0, "usr": 468307235068920063, "detailed_name": "void called()", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -37,6 +38,7 @@ void foo() { "id": 1, "usr": 10177235824697315808, "detailed_name": "void caller()", + "qual_name_offset": 5, "short_name": "caller", "kind": 12, "storage": 1, @@ -52,6 +54,7 @@ void foo() { "id": 2, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index d22528e67..b2f55947c 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -17,6 +17,7 @@ Wrapper caller() { "id": 0, "usr": 13611487872560323389, "detailed_name": "Wrapper", + "qual_name_offset": 0, "short_name": "Wrapper", "kind": 23, "declarations": ["2:3-2:10|-1|1|4"], @@ -34,6 +35,7 @@ Wrapper caller() { "id": 0, "usr": 10544127002917214589, "detailed_name": "void Wrapper::Wrapper(int i)", + "qual_name_offset": 5, "short_name": "Wrapper", "kind": 9, "storage": 1, @@ -51,6 +53,7 @@ Wrapper caller() { "id": 1, "usr": 468307235068920063, "detailed_name": "int called()", + "qual_name_offset": 4, "short_name": "called", "kind": 12, "storage": 1, @@ -66,6 +69,7 @@ Wrapper caller() { "id": 2, "usr": 11404881820527069090, "detailed_name": "Wrapper caller()", + "qual_name_offset": 8, "short_name": "caller", "kind": 12, "storage": 1, diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 2f69d39c7..e87d6f34f 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -17,6 +17,7 @@ void user() { "id": 0, "usr": 12924914488846929470, "detailed_name": "void consume(void (*)())", + "qual_name_offset": 5, "short_name": "consume", "kind": 12, "storage": 1, @@ -32,6 +33,7 @@ void user() { "id": 1, "usr": 5264867802674151787, "detailed_name": "void used()", + "qual_name_offset": 5, "short_name": "used", "kind": 12, "storage": 1, @@ -47,6 +49,7 @@ void user() { "id": 2, "usr": 9376923949268137283, "detailed_name": "void user()", + "qual_name_offset": 5, "short_name": "user", "kind": 12, "storage": 1, @@ -63,6 +66,7 @@ void user() { "id": 0, "usr": 16088407831770615719, "detailed_name": "void (*)() x", + "qual_name_offset": 11, "short_name": "x", "declarations": [], "spell": "6:10-6:11|2|3|2", diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index b2d9fb460..52d5739cb 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -16,6 +16,7 @@ void user() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -33,6 +34,7 @@ void user() { "id": 0, "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", + "qual_name_offset": 5, "short_name": "Used", "kind": 6, "storage": 1, @@ -50,6 +52,7 @@ void user() { "id": 1, "usr": 9376923949268137283, "detailed_name": "void user()", + "qual_name_offset": 5, "short_name": "user", "kind": 12, "storage": 1, @@ -66,6 +69,7 @@ void user() { "id": 0, "usr": 4636142131003982569, "detailed_name": "void (Foo::*)() x", + "qual_name_offset": 16, "short_name": "x", "declarations": [], "spell": "6:8-6:9|1|3|2", diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 574108532..2181c4f48 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -13,6 +13,7 @@ void caller() { "id": 0, "usr": 468307235068920063, "detailed_name": "void called()", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -28,6 +29,7 @@ void caller() { "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", + "qual_name_offset": 5, "short_name": "caller", "kind": 12, "storage": 1, diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 01ef98f95..d18cc3277 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -16,6 +16,7 @@ void user() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -33,6 +34,7 @@ void user() { "id": 0, "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", + "qual_name_offset": 5, "short_name": "Used", "kind": 6, "storage": 1, @@ -50,6 +52,7 @@ void user() { "id": 1, "usr": 9376923949268137283, "detailed_name": "void user()", + "qual_name_offset": 5, "short_name": "user", "kind": 12, "storage": 1, @@ -66,6 +69,7 @@ void user() { "id": 0, "usr": 14045150712868309451, "detailed_name": "Foo *f", + "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index c3f1b85cc..eb0821335 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -15,6 +15,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -31,6 +32,7 @@ class Foo { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -46,6 +48,7 @@ class Foo { "id": 0, "usr": 9630503130605430498, "detailed_name": "int helper()", + "qual_name_offset": 4, "short_name": "helper", "kind": 12, "storage": 3, @@ -62,6 +65,7 @@ class Foo { "id": 0, "usr": 4220150017963593039, "detailed_name": "int Foo::x", + "qual_name_offset": 4, "short_name": "x", "hover": "int Foo::x = helper()", "declarations": [], diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index caec7c49c..8ee0bcde7 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -13,6 +13,7 @@ void usage() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -29,6 +30,7 @@ void usage() { "id": 1, "usr": 6767773193109753523, "detailed_name": "void usage()", + "qual_name_offset": 5, "short_name": "usage", "kind": 12, "storage": 1, diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index c9c988c12..1d595bdfd 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -15,6 +15,7 @@ void usage() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -32,6 +33,7 @@ void usage() { "id": 0, "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, @@ -49,6 +51,7 @@ void usage() { "id": 1, "usr": 6767773193109753523, "detailed_name": "void usage()", + "qual_name_offset": 5, "short_name": "usage", "kind": 12, "storage": 1, @@ -65,6 +68,7 @@ void usage() { "id": 0, "usr": 16229832321010999607, "detailed_name": "Foo *f", + "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index ddfe668a5..610873991 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -15,6 +15,7 @@ void foo() { "id": 0, "usr": 13420564603121289209, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], @@ -32,6 +33,7 @@ void foo() { "id": 0, "usr": 10585861037135727329, "detailed_name": "void accept(T)", + "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, @@ -48,6 +50,7 @@ void foo() { "id": 1, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 57b128e76..973043fb8 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -19,6 +19,7 @@ unique_ptr* return_type() { "id": 0, "usr": 3286534761799572592, "detailed_name": "unique_ptr", + "qual_name_offset": 0, "short_name": "unique_ptr", "kind": 5, "declarations": [], @@ -35,6 +36,7 @@ unique_ptr* return_type() { "id": 1, "usr": 4750332761459066907, "detailed_name": "S", + "qual_name_offset": 0, "short_name": "S", "kind": 23, "declarations": [], @@ -52,6 +54,7 @@ unique_ptr* return_type() { "id": 0, "usr": 16359708726068806331, "detailed_name": "unique_ptr *return_type()", + "qual_name_offset": 15, "short_name": "return_type", "kind": 12, "storage": 1, @@ -68,6 +71,7 @@ unique_ptr* return_type() { "id": 0, "usr": 12857919739649552168, "detailed_name": "unique_ptr f0", + "qual_name_offset": 17, "short_name": "f0", "declarations": [], "spell": "6:25-6:27|-1|1|2", @@ -80,6 +84,7 @@ unique_ptr* return_type() { "id": 1, "usr": 18075066956054788088, "detailed_name": "unique_ptr f1", + "qual_name_offset": 14, "short_name": "f1", "declarations": [], "spell": "7:22-7:24|-1|1|2", @@ -92,6 +97,7 @@ unique_ptr* return_type() { "id": 2, "usr": 3364438781074774169, "detailed_name": "unique_ptr *local", + "qual_name_offset": 15, "short_name": "local", "declarations": [], "spell": "10:18-10:23|0|3|2", diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index d200b0254..e740286d5 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -87,6 +87,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 0, "usr": 14209198335088845323, "detailed_name": "unique_ptr", + "qual_name_offset": 0, "short_name": "unique_ptr", "kind": 5, "declarations": ["2:7-2:17|-1|1|1"], @@ -101,6 +102,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 1, "usr": 4310164820010458371, "detailed_name": "S1", + "qual_name_offset": 0, "short_name": "S1", "kind": 23, "declarations": ["4:8-4:10|-1|1|1"], @@ -115,6 +117,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 2, "usr": 12728490517004312484, "detailed_name": "S2", + "qual_name_offset": 0, "short_name": "S2", "kind": 23, "declarations": ["5:8-5:10|-1|1|1"], @@ -129,6 +132,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 3, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -146,6 +150,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 0, "usr": 1246637699196435450, "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", + "qual_name_offset": 36, "short_name": "as_return_type", "kind": 12, "storage": 1, @@ -161,6 +166,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 1, "usr": 13067214284561914253, "detailed_name": "void no_return_type(int)", + "qual_name_offset": 5, "short_name": "no_return_type", "kind": 12, "storage": 1, @@ -176,6 +182,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 2, "usr": 18320186404467436976, "detailed_name": "void empty()", + "qual_name_offset": 5, "short_name": "empty", "kind": 12, "storage": 1, @@ -191,6 +198,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 3, "usr": 17922201480358737771, "detailed_name": "unique_ptr *Foo::foo()", + "qual_name_offset": 20, "short_name": "foo", "kind": 6, "storage": 1, @@ -211,6 +219,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 0, "usr": 2933643612409209903, "detailed_name": "unique_ptr, S2> f", + "qual_name_offset": 35, "short_name": "f", "declarations": ["15:43-15:44|-1|1|1"], "type": 0, @@ -221,6 +230,7 @@ unique_ptr* Foo::foo() { return nullptr; } "id": 1, "usr": 500112618220246, "detailed_name": "unique_ptr, S2> *local", + "qual_name_offset": 36, "short_name": "local", "declarations": [], "spell": "54:39-54:44|2|3|2", diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 20ee51d34..3401f59a3 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -14,6 +14,7 @@ static unique_ptr foo; "id": 0, "usr": 3286534761799572592, "detailed_name": "unique_ptr", + "qual_name_offset": 0, "short_name": "unique_ptr", "kind": 5, "declarations": [], @@ -30,6 +31,7 @@ static unique_ptr foo; "id": 1, "usr": 4750332761459066907, "detailed_name": "S", + "qual_name_offset": 0, "short_name": "S", "kind": 23, "declarations": ["4:8-4:9|-1|1|1"], @@ -46,6 +48,7 @@ static unique_ptr foo; "id": 0, "usr": 3398408600781120939, "detailed_name": "unique_ptr foo", + "qual_name_offset": 14, "short_name": "foo", "declarations": [], "spell": "6:22-6:25|-1|1|2", diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index a89d10647..5bb504200 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -10,6 +10,7 @@ extern T t; "id": 0, "usr": 5673439900521455039, "detailed_name": "T", + "qual_name_offset": 0, "short_name": "T", "kind": 23, "declarations": [], @@ -28,6 +29,7 @@ extern T t; "id": 0, "usr": 1346710425945444872, "detailed_name": "T t", + "qual_name_offset": 2, "short_name": "t", "declarations": ["3:10-3:11|-1|1|1"], "type": 0, diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 5876efe63..195f5afa6 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -15,6 +15,7 @@ struct Foo { "id": 0, "usr": 13749354388332789217, "detailed_name": "ForwardType", + "qual_name_offset": 0, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|-1|1|1"], @@ -29,6 +30,7 @@ struct Foo { "id": 1, "usr": 8508299082070213750, "detailed_name": "ImplementedType", + "qual_name_offset": 0, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -45,6 +47,7 @@ struct Foo { "id": 2, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -63,6 +66,7 @@ struct Foo { "id": 0, "usr": 14314859014962085433, "detailed_name": "ForwardType *Foo::a", + "qual_name_offset": 13, "short_name": "a", "declarations": [], "spell": "5:16-5:17|2|2|2", @@ -75,6 +79,7 @@ struct Foo { "id": 1, "usr": 14727441168849658842, "detailed_name": "ImplementedType Foo::b", + "qual_name_offset": 16, "short_name": "b", "declarations": [], "spell": "6:19-6:20|2|2|2", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 733155945..b501a77b0 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -15,6 +15,7 @@ void Foo() { "id": 0, "usr": 13749354388332789217, "detailed_name": "ForwardType", + "qual_name_offset": 0, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|-1|1|1"], @@ -29,6 +30,7 @@ void Foo() { "id": 1, "usr": 8508299082070213750, "detailed_name": "ImplementedType", + "qual_name_offset": 0, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -46,6 +48,7 @@ void Foo() { "id": 0, "usr": 4654328188330986029, "detailed_name": "void Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 12, "storage": 1, @@ -62,6 +65,7 @@ void Foo() { "id": 0, "usr": 16374832544037266261, "detailed_name": "ForwardType *a", + "qual_name_offset": 13, "short_name": "a", "declarations": [], "spell": "5:16-5:17|0|3|2", @@ -74,6 +78,7 @@ void Foo() { "id": 1, "usr": 2580122838476012357, "detailed_name": "ImplementedType b", + "qual_name_offset": 16, "short_name": "b", "declarations": [], "spell": "6:19-6:20|0|3|2", diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index b6155f873..60fccd12f 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -12,6 +12,7 @@ void foo(ForwardType* f, ImplementedType a) {} "id": 0, "usr": 13749354388332789217, "detailed_name": "ForwardType", + "qual_name_offset": 0, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|-1|1|1"], @@ -26,6 +27,7 @@ void foo(ForwardType* f, ImplementedType a) {} "id": 1, "usr": 8508299082070213750, "detailed_name": "ImplementedType", + "qual_name_offset": 0, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -43,6 +45,7 @@ void foo(ForwardType* f, ImplementedType a) {} "id": 0, "usr": 1699390678058422036, "detailed_name": "void foo(ForwardType *f, ImplementedType a)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -59,6 +62,7 @@ void foo(ForwardType* f, ImplementedType a) {} "id": 0, "usr": 13058491096576226774, "detailed_name": "ForwardType *f", + "qual_name_offset": 13, "short_name": "f", "declarations": [], "spell": "4:23-4:24|0|3|2", @@ -71,6 +75,7 @@ void foo(ForwardType* f, ImplementedType a) {} "id": 1, "usr": 11055777568039014776, "detailed_name": "ImplementedType a", + "qual_name_offset": 16, "short_name": "a", "declarations": [], "spell": "4:42-4:43|0|3|2", diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 2cbc4522c..05b6c4d44 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -17,6 +17,7 @@ void foo(Foo* f, Foo*) {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|-1|1|1"], @@ -32,6 +33,7 @@ void foo(Foo* f, Foo*) {} "id": 0, "usr": 8908726657907936744, "detailed_name": "void foo(Foo *f, Foo *)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -51,6 +53,7 @@ void foo(Foo* f, Foo*) {} "id": 0, "usr": 13823260660189154978, "detailed_name": "Foo *f", + "qual_name_offset": 5, "short_name": "f", "declarations": [], "spell": "4:15-4:16|0|3|2", diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index 2af6a1927..b588c4f7d 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -9,6 +9,7 @@ void foo(ForwardType*) {} "id": 0, "usr": 13749354388332789217, "detailed_name": "ForwardType", + "qual_name_offset": 0, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|-1|1|1"], @@ -24,6 +25,7 @@ void foo(ForwardType*) {} "id": 0, "usr": 15327735280790448926, "detailed_name": "void foo(ForwardType *)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 0219d89f5..799906b3f 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -15,6 +15,7 @@ void foo(Type& a0, const Type& a1) { "id": 0, "usr": 13487927231218873822, "detailed_name": "Type", + "qual_name_offset": 0, "short_name": "Type", "kind": 23, "declarations": [], @@ -32,6 +33,7 @@ void foo(Type& a0, const Type& a1) { "id": 0, "usr": 16858540520096802573, "detailed_name": "void foo(Type &a0, const Type &a1)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -48,6 +50,7 @@ void foo(Type& a0, const Type& a1) { "id": 0, "usr": 7997456978847868736, "detailed_name": "Type &a0", + "qual_name_offset": 6, "short_name": "a0", "declarations": [], "spell": "3:16-3:18|0|3|2", @@ -60,6 +63,7 @@ void foo(Type& a0, const Type& a1) { "id": 1, "usr": 17228576662112939520, "detailed_name": "const Type &a1", + "qual_name_offset": 12, "short_name": "a1", "declarations": [], "spell": "3:32-3:34|0|3|2", @@ -72,6 +76,7 @@ void foo(Type& a0, const Type& a1) { "id": 2, "usr": 15429032129697337561, "detailed_name": "Type a2", + "qual_name_offset": 5, "short_name": "a2", "declarations": [], "spell": "4:8-4:10|0|3|2", @@ -84,6 +89,7 @@ void foo(Type& a0, const Type& a1) { "id": 3, "usr": 6081981442495435784, "detailed_name": "Type *a3", + "qual_name_offset": 6, "short_name": "a3", "declarations": [], "spell": "5:9-5:11|0|3|2", @@ -96,6 +102,7 @@ void foo(Type& a0, const Type& a1) { "id": 4, "usr": 5004072032239834773, "detailed_name": "const Type *a4", + "qual_name_offset": 12, "short_name": "a4", "declarations": [], "spell": "6:15-6:17|0|3|2", @@ -108,6 +115,7 @@ void foo(Type& a0, const Type& a1) { "id": 5, "usr": 14939253431683105646, "detailed_name": "const Type *const a5", + "qual_name_offset": 18, "short_name": "a5", "hover": "const Type *const a5 = nullptr", "declarations": [], diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index 0e570fee3..53b6926a1 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -9,6 +9,7 @@ static Type t; "id": 0, "usr": 13487927231218873822, "detailed_name": "Type", + "qual_name_offset": 0, "short_name": "Type", "kind": 23, "declarations": [], @@ -27,6 +28,7 @@ static Type t; "id": 0, "usr": 6601831367240627080, "detailed_name": "Type t", + "qual_name_offset": 5, "short_name": "t", "declarations": [], "spell": "2:13-2:14|-1|1|2", diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index cdd5c0906..dfbc8836a 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -26,6 +26,7 @@ static Type* bar() { return nullptr; } "id": 0, "usr": 13487927231218873822, "detailed_name": "Type", + "qual_name_offset": 0, "short_name": "Type", "kind": 23, "declarations": ["1:8-1:12|-1|1|1"], @@ -40,6 +41,7 @@ static Type* bar() { return nullptr; } "id": 1, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -57,6 +59,7 @@ static Type* bar() { return nullptr; } "id": 0, "usr": 4259594751088586730, "detailed_name": "Type *foo()", + "qual_name_offset": 6, "short_name": "foo", "kind": 12, "storage": 1, @@ -78,6 +81,7 @@ static Type* bar() { return nullptr; } "id": 1, "usr": 13402221340333431092, "detailed_name": "Type *Foo::Get(int)", + "qual_name_offset": 6, "short_name": "Get", "kind": 6, "storage": 1, @@ -97,6 +101,7 @@ static Type* bar() { return nullptr; } "id": 2, "usr": 4240751906910175539, "detailed_name": "void Foo::Empty()", + "qual_name_offset": 5, "short_name": "Empty", "kind": 6, "storage": 1, @@ -116,6 +121,7 @@ static Type* bar() { return nullptr; } "id": 3, "usr": 7746867874366499515, "detailed_name": "const Type &external()", + "qual_name_offset": 12, "short_name": "external", "kind": 12, "storage": 2, @@ -132,6 +138,7 @@ static Type* bar() { return nullptr; } "id": 4, "usr": 18408440185620243373, "detailed_name": "Type *bar()", + "qual_name_offset": 6, "short_name": "bar", "kind": 12, "storage": 3, diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index a732a4f6b..6b243e4a5 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -18,6 +18,7 @@ void accept3(Foo3*) {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|-1|1|1"], @@ -32,6 +33,7 @@ void accept3(Foo3*) {} "id": 1, "usr": 1544499294580512394, "detailed_name": "Foo1", + "qual_name_offset": 0, "short_name": "Foo1", "kind": 252, "hover": "using Foo1 = Foo*", @@ -50,6 +52,7 @@ void accept3(Foo3*) {} "id": 2, "usr": 15466821155413653804, "detailed_name": "Foo2", + "qual_name_offset": 0, "short_name": "Foo2", "kind": 252, "hover": "typedef Foo Foo2", @@ -68,6 +71,7 @@ void accept3(Foo3*) {} "id": 3, "usr": 17897026942631673064, "detailed_name": "Foo3", + "qual_name_offset": 0, "short_name": "Foo3", "kind": 252, "hover": "using Foo3 = Foo1", @@ -86,6 +90,7 @@ void accept3(Foo3*) {} "id": 4, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -100,6 +105,7 @@ void accept3(Foo3*) {} "id": 5, "usr": 2638219001294786365, "detailed_name": "Foo4", + "qual_name_offset": 0, "short_name": "Foo4", "kind": 252, "hover": "using Foo4 = int", @@ -119,6 +125,7 @@ void accept3(Foo3*) {} "id": 0, "usr": 9119341505144503905, "detailed_name": "void accept(Foo *)", + "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, @@ -134,6 +141,7 @@ void accept3(Foo3*) {} "id": 1, "usr": 558620830317390922, "detailed_name": "void accept1(Foo1 *)", + "qual_name_offset": 5, "short_name": "accept1", "kind": 12, "storage": 1, @@ -149,6 +157,7 @@ void accept3(Foo3*) {} "id": 2, "usr": 10523262907746124479, "detailed_name": "void accept2(Foo2 *)", + "qual_name_offset": 5, "short_name": "accept2", "kind": 12, "storage": 1, @@ -164,6 +173,7 @@ void accept3(Foo3*) {} "id": 3, "usr": 14986366321326974406, "detailed_name": "void accept3(Foo3 *)", + "qual_name_offset": 5, "short_name": "accept3", "kind": 12, "storage": 1, diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index fb536eaba..a9f31ef07 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -13,6 +13,7 @@ typedef Foo Foo2; "id": 0, "usr": 10528472276654770367, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": ["2:8-2:11|-1|1|1"], @@ -27,6 +28,7 @@ typedef Foo Foo2; "id": 1, "usr": 1544499294580512394, "detailed_name": "Foo1", + "qual_name_offset": 0, "short_name": "Foo1", "kind": 252, "hover": "using Foo1 = Foo", @@ -45,6 +47,7 @@ typedef Foo Foo2; "id": 2, "usr": 15933698173231330933, "detailed_name": "Foo2", + "qual_name_offset": 0, "short_name": "Foo2", "kind": 252, "hover": "typedef Foo Foo2", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index e38d14d64..f948a0f7e 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -18,6 +18,7 @@ extern Foo foo; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -35,6 +36,7 @@ extern Foo foo; "id": 0, "usr": 9488177941273031343, "detailed_name": "Foo *Foo::make()", + "qual_name_offset": 5, "short_name": "make", "kind": 6, "storage": 1, @@ -55,6 +57,7 @@ extern Foo foo; "id": 0, "usr": 16380484338511689669, "detailed_name": "Foo f", + "qual_name_offset": 4, "short_name": "f", "declarations": [], "spell": "6:7-6:8|0|3|2", @@ -67,6 +70,7 @@ extern Foo foo; "id": 1, "usr": 14455976355866885943, "detailed_name": "Foo foo", + "qual_name_offset": 4, "short_name": "foo", "declarations": ["10:12-10:15|-1|1|1"], "type": 0, diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 556bacc4c..23988cc38 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -23,6 +23,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -39,6 +40,7 @@ void foo() { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -54,6 +56,7 @@ void foo() { "id": 0, "usr": 18319417758892371313, "detailed_name": "void called(int a)", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -70,6 +73,7 @@ void foo() { "id": 1, "usr": 11404602816585117695, "detailed_name": "int gen()", + "qual_name_offset": 4, "short_name": "gen", "kind": 12, "storage": 1, @@ -86,6 +90,7 @@ void foo() { "id": 2, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -102,6 +107,7 @@ void foo() { "id": 0, "usr": 11489549839875479478, "detailed_name": "int Foo::static_var", + "qual_name_offset": 4, "short_name": "static_var", "hover": "int Foo::static_var = 0", "declarations": ["6:14-6:24|0|2|1"], @@ -115,6 +121,7 @@ void foo() { "id": 1, "usr": 9648311402855509901, "detailed_name": "int Foo::field_var", + "qual_name_offset": 4, "short_name": "field_var", "declarations": [], "spell": "7:7-7:16|0|2|2", @@ -127,6 +134,7 @@ void foo() { "id": 2, "usr": 8039186520399841081, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "hover": "int a = 5", "declarations": [], diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index b5336d116..4aaa7875d 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -16,6 +16,7 @@ void foo() { "id": 0, "usr": 18319417758892371313, "detailed_name": "void called(int a)", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -32,6 +33,7 @@ void foo() { "id": 1, "usr": 11404602816585117695, "detailed_name": "int gen()", + "qual_name_offset": 4, "short_name": "gen", "kind": 12, "storage": 1, @@ -47,6 +49,7 @@ void foo() { "id": 2, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index de98e5fca..e2d4f2fad 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -17,6 +17,7 @@ void caller() { "id": 0, "usr": 468307235068920063, "detailed_name": "void called()", + "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, @@ -32,6 +33,7 @@ void caller() { "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", + "qual_name_offset": 5, "short_name": "caller", "kind": 12, "storage": 1, @@ -48,6 +50,7 @@ void caller() { "id": 0, "usr": 9121974011454213596, "detailed_name": "void (*)() x", + "qual_name_offset": 11, "short_name": "x", "declarations": [], "spell": "4:8-4:9|1|3|2", diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 21bbdfd93..d69730a63 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -26,6 +26,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -42,6 +43,7 @@ void foo() { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -57,6 +59,7 @@ void foo() { "id": 0, "usr": 17175780305784503374, "detailed_name": "void accept(int)", + "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, @@ -73,6 +76,7 @@ void foo() { "id": 1, "usr": 12086644540399881766, "detailed_name": "void accept(int *)", + "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, @@ -89,6 +93,7 @@ void foo() { "id": 2, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -105,6 +110,7 @@ void foo() { "id": 0, "usr": 4220150017963593039, "detailed_name": "int Foo::x", + "qual_name_offset": 4, "short_name": "x", "declarations": [], "spell": "3:7-3:8|0|2|2", @@ -117,6 +123,7 @@ void foo() { "id": 1, "usr": 3873837747174060388, "detailed_name": "int Foo::y", + "qual_name_offset": 4, "short_name": "y", "declarations": [], "spell": "4:7-4:8|0|2|2", @@ -129,6 +136,7 @@ void foo() { "id": 2, "usr": 14669930844300034456, "detailed_name": "Foo f", + "qual_name_offset": 4, "short_name": "f", "declarations": [], "spell": "11:7-11:8|2|3|2", diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 1ad13233f..981bb21ac 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -17,6 +17,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], @@ -33,6 +34,7 @@ void foo() { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -48,6 +50,7 @@ void foo() { "id": 0, "usr": 17175780305784503374, "detailed_name": "void accept(int)", + "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, @@ -64,6 +67,7 @@ void foo() { "id": 1, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -80,6 +84,7 @@ void foo() { "id": 0, "usr": 8599782646965457351, "detailed_name": "int Foo::x", + "qual_name_offset": 4, "short_name": "x", "declarations": ["2:14-2:15|0|2|1"], "type": 1, diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index ecf609308..e6400caa9 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -16,6 +16,7 @@ const VarType Holder::static_var; "id": 0, "usr": 5792006888140599735, "detailed_name": "VarType", + "qual_name_offset": 0, "short_name": "VarType", "kind": 10, "declarations": [], @@ -32,6 +33,7 @@ const VarType Holder::static_var; "id": 1, "usr": 10028537921178202800, "detailed_name": "Holder", + "qual_name_offset": 0, "short_name": "Holder", "kind": 23, "declarations": [], @@ -50,6 +52,7 @@ const VarType Holder::static_var; "id": 0, "usr": 7057400933868440116, "detailed_name": "const VarType Holder::static_var", + "qual_name_offset": 14, "short_name": "static_var", "hover": "const VarType Holder::static_var = (VarType)0x0", "declarations": ["4:28-4:38|1|2|1"], diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 412c85518..441c73ac5 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -12,6 +12,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -27,6 +28,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -43,6 +45,7 @@ void foo() { "id": 0, "usr": 16721564935990383768, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": ["1:12-1:13|-1|1|1"], "type": 0, diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 26341c493..f25318707 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -10,6 +10,7 @@ void foo(int a) { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -25,6 +26,7 @@ void foo(int a) { "id": 0, "usr": 11998306017310352355, "detailed_name": "void foo(int a)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -41,6 +43,7 @@ void foo(int a) { "id": 0, "usr": 10063793875496522529, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "1:14-1:15|0|3|2", diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 09fd489c6..009367ea9 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -11,6 +11,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -26,6 +27,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -42,6 +44,7 @@ void foo() { "id": 0, "usr": 14014650769929566957, "detailed_name": "int x", + "qual_name_offset": 4, "short_name": "x", "declarations": [], "spell": "2:7-2:8|0|3|2", diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index f1767412d..e63910aa7 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -16,6 +16,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -31,6 +32,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -47,6 +49,7 @@ void foo() { "id": 0, "usr": 13311055950748663970, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "2:7-2:8|0|3|2", @@ -59,6 +62,7 @@ void foo() { "id": 1, "usr": 14036425367303419504, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "5:9-5:10|0|3|2", diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 591f7b1da..b33d417ce 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -16,6 +16,7 @@ void foo(int a) { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -31,6 +32,7 @@ void foo(int a) { "id": 0, "usr": 11998306017310352355, "detailed_name": "void foo(int a)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -47,6 +49,7 @@ void foo(int a) { "id": 0, "usr": 11608231465452906059, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "1:14-1:15|0|3|2", @@ -59,6 +62,7 @@ void foo(int a) { "id": 1, "usr": 6997229590862003559, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "4:9-4:10|0|3|2", diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index ab456631f..b6fb8bc99 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -13,6 +13,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -28,6 +29,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -44,6 +46,7 @@ void foo() { "id": 0, "usr": 11823161916242867318, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "1:12-1:13|-1|1|2", diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index cf676c635..43e10c017 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -10,6 +10,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -28,6 +29,7 @@ class Foo { "id": 0, "usr": 13799811842374292251, "detailed_name": "Foo *Foo::member", + "qual_name_offset": 5, "short_name": "member", "declarations": [], "spell": "2:8-2:14|0|2|2", diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 6b5d12081..8af93e6c3 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -12,6 +12,7 @@ Foo* Foo::member = nullptr; "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -30,6 +31,7 @@ Foo* Foo::member = nullptr; "id": 0, "usr": 5844987037615239736, "detailed_name": "Foo *Foo::member", + "qual_name_offset": 5, "short_name": "member", "hover": "Foo *Foo::member = nullptr", "declarations": ["2:15-2:21|0|2|1"], diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index a7ea0afae..069ded36b 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -10,6 +10,7 @@ class Foo { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -26,6 +27,7 @@ class Foo { "id": 1, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -42,6 +44,7 @@ class Foo { "id": 0, "usr": 5844987037615239736, "detailed_name": "int Foo::member", + "qual_name_offset": 4, "short_name": "member", "declarations": ["2:14-2:20|0|2|1"], "type": 1, diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 8bd1166f4..801a22038 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -13,6 +13,7 @@ void f() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], @@ -30,6 +31,7 @@ void f() { "id": 0, "usr": 880549676430489861, "detailed_name": "void f()", + "qual_name_offset": 5, "short_name": "f", "kind": 12, "storage": 1, @@ -46,6 +48,7 @@ void f() { "id": 0, "usr": 10601729374837386290, "detailed_name": "Foo *x", + "qual_name_offset": 5, "short_name": "x", "declarations": [], "spell": "3:8-3:9|0|3|2", @@ -58,6 +61,7 @@ void f() { "id": 1, "usr": 18422884837902130475, "detailed_name": "Foo *y", + "qual_name_offset": 5, "short_name": "y", "declarations": [], "spell": "4:9-4:10|0|3|2", diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 4c3951ca1..16e4995d0 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -13,6 +13,7 @@ void foo() { "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|-1|1|1"], @@ -28,6 +29,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -44,6 +46,7 @@ void foo() { "id": 0, "usr": 13198746475679542317, "detailed_name": "Foo *a", + "qual_name_offset": 5, "short_name": "a", "declarations": [], "spell": "4:8-4:9|0|3|2", diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 0108c73be..cfd28001e 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -11,6 +11,7 @@ void foo(Foo* p0, Foo* p1) {} "id": 0, "usr": 15041163540773201510, "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|-1|1|1"], @@ -26,6 +27,7 @@ void foo(Foo* p0, Foo* p1) {} "id": 0, "usr": 8908726657907936744, "detailed_name": "void foo(Foo *p0, Foo *p1)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -42,6 +44,7 @@ void foo(Foo* p0, Foo* p1) {} "id": 0, "usr": 8730439006497971620, "detailed_name": "Foo *p0", + "qual_name_offset": 5, "short_name": "p0", "declarations": [], "spell": "3:15-3:17|0|3|2", @@ -54,6 +57,7 @@ void foo(Foo* p0, Foo* p1) {} "id": 1, "usr": 2525014371090380500, "detailed_name": "Foo *p1", + "qual_name_offset": 5, "short_name": "p1", "declarations": [], "spell": "3:24-3:26|0|3|2", diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index aa3fd2a70..8d4f88131 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -9,6 +9,7 @@ void foo(int, int) {} "id": 0, "usr": 2747674671862363334, "detailed_name": "void foo(int, int)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 1d16f481e..53fa645e5 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -16,6 +16,7 @@ void foo() { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -31,6 +32,7 @@ void foo() { "id": 0, "usr": 4259594751088586730, "detailed_name": "void foo()", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -47,6 +49,7 @@ void foo() { "id": 0, "usr": 1894874819807168345, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "2:7-2:8|0|3|2", @@ -59,6 +62,7 @@ void foo() { "id": 1, "usr": 4508045017817092115, "detailed_name": "int a", + "qual_name_offset": 4, "short_name": "a", "declarations": [], "spell": "5:9-5:10|0|3|2", diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index ee7b225ef..cab3e40d9 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -10,6 +10,7 @@ void foo(int p) { "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -25,6 +26,7 @@ void foo(int p) { "id": 0, "usr": 11998306017310352355, "detailed_name": "void foo(int p)", + "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, @@ -41,6 +43,7 @@ void foo(int p) { "id": 0, "usr": 5875271969926422921, "detailed_name": "int p", + "qual_name_offset": 4, "short_name": "p", "declarations": [], "spell": "1:14-1:15|0|3|2", @@ -53,6 +56,7 @@ void foo(int p) { "id": 1, "usr": 11404600766177939811, "detailed_name": "int p", + "qual_name_offset": 4, "short_name": "p", "hover": "int p = 0", "declarations": [], diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index 5d061ff7d..d40c35b80 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -8,6 +8,7 @@ static int global = 0; "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -24,6 +25,7 @@ static int global = 0; "id": 0, "usr": 6834525061342585382, "detailed_name": "int global", + "qual_name_offset": 4, "short_name": "global", "hover": "int global = 0", "declarations": [], diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index f70c21bc9..2aaaedcd5 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -8,6 +8,7 @@ extern int global; "id": 0, "usr": 17, "detailed_name": "", + "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], @@ -24,6 +25,7 @@ extern int global; "id": 0, "usr": 9937941849651546906, "detailed_name": "int global", + "qual_name_offset": 4, "short_name": "global", "declarations": ["1:12-1:18|-1|1|1"], "type": 0, diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 1101a9834..f61dd2c1f 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -15,6 +15,7 @@ void Foo() { "id": 0, "usr": 4750332761459066907, "detailed_name": "S", + "qual_name_offset": 0, "short_name": "S", "kind": 23, "declarations": [], @@ -31,6 +32,7 @@ void Foo() { "id": 1, "usr": 7434820806199665424, "detailed_name": "F", + "qual_name_offset": 0, "short_name": "F", "kind": 252, "hover": "using F = S", @@ -50,6 +52,7 @@ void Foo() { "id": 0, "usr": 4654328188330986029, "detailed_name": "void Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 12, "storage": 1, @@ -66,6 +69,7 @@ void Foo() { "id": 0, "usr": 6975456769752895964, "detailed_name": "F a", + "qual_name_offset": 2, "short_name": "a", "declarations": [], "spell": "4:5-4:6|0|3|2", diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index fac4d7401..1167416d2 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -309,7 +309,9 @@ struct IndexParam { clang_PrintingPolicy_dispose(print_policy_more); } - std::string PrettyPrintCursor(CXCursor cursor, bool initializer = true) { + std::tuple PrettyPrintCursor( + CXCursor cursor, + std::string_view short_name) { if (!print_policy) { print_policy = clang_getCursorPrintingPolicy(cursor); clang_PrintingPolicy_setProperty(print_policy, @@ -324,8 +326,31 @@ struct IndexParam { clang_PrintingPolicy_setProperty(print_policy_more, CXPrintingPolicy_TerseOutput, 1); } - return ToString(clang_getCursorPrettyPrinted( - cursor, initializer ? print_policy_more : print_policy)); + std::string name = + ToString(clang_getCursorPrettyPrinted(cursor, print_policy_more)); + for (std::string::size_type i = 0;;) { + if ((i = name.find("(anonymous ", i)) == std::string::npos) + break; + i++; + if (name.size() > 10 + 9 && name.compare(10, 9, "namespace")) + name.replace(i, 10 + 9, "anon ns"); + else + name.replace(i, 10, "anon"); + } + auto i = name.find(short_name); + assert(i != std::string::npos); + int16_t short_name_offset = i, short_name_size = short_name.size(); + for (int paren = 0; i; i--) { + // Skip parentheses in "(anon struct)::name" + if (name[i - 1] == ')') + paren++; + else if (name[i - 1] == '(') + paren--; + else if (!(paren > 0 || isalnum(name[i - 1]) || + name[i - 1] == '_' || name[i - 1] == ':')) + break; + } + return {name, i, short_name_offset, short_name_size}; } #endif }; @@ -360,13 +385,8 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { // Report skipped source range list. CXSourceRangeList* skipped = clang_getSkippedRanges(param->tu->cx_tu, file); for (unsigned i = 0; i < skipped->count; ++i) { - Range range = ResolveCXSourceRange(skipped->ranges[i]); -#if CINDEX_VERSION < 45 // Before clang 6.0.0 - // clang_getSkippedRanges reports start one token after the '#', move it - // back so it starts at the '#' - range.start.column -= 1; -#endif - db->skipped_by_preprocessor.push_back(range); + db->skipped_by_preprocessor.push_back( + ResolveCXSourceRange(skipped->ranges[i])); } clang_disposeSourceRangeList(skipped); } @@ -497,6 +517,8 @@ const char* GetAnonName(CXCursorKind kind) { return "(anon class)"; case CXCursor_EnumDecl: return "(anon enum)"; + case CXCursor_Namespace: + return "(anon ns)"; case CXCursor_StructDecl: return "(anon struct)"; case CXCursor_UnionDecl: @@ -521,9 +543,12 @@ void SetTypeName(IndexType* type, // Investigate why clang_getCursorPrettyPrinted gives `struct A {}` `namespace // ns {}` which are not qualified. // type->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor); - std::tie(type->def.detailed_name, type->def.short_name_offset) = + int short_name_offset, short_name_size; + std::tie(type->def.detailed_name, short_name_offset, short_name_size) = param->ns.QualifiedName(container ? container : &parent, name); - type->def.short_name_size = strlen(name); + type->def.qual_name_offset = 0; + type->def.short_name_offset = short_name_offset; + type->def.short_name_size = short_name_size; } // Finds the cursor associated with the declaration type of |cursor|. This @@ -586,13 +611,14 @@ void SetVarDetail(IndexVar* var, def.storage = GetStorageClass(clang_Cursor_getStorageClass(cursor.cx_cursor)); // TODO how to make PrettyPrint'ed variable name qualified? - std::string qualified_name = #if 0 && CINDEX_HAVE_PRETTY cursor.get_kind() != CXCursor_EnumConstantDecl ? param->PrettyPrintCursor(cursor.cx_cursor) : #endif - param->ns.QualifiedName(semanticContainer, short_name).first; + std::string qualified_name; + std::tie(qualified_name, def.short_name_offset, def.short_name_size) = + param->ns.QualifiedName(semanticContainer, short_name); if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) { CXType enum_type = clang_getCanonicalType( @@ -610,7 +636,10 @@ void SetVarDetail(IndexVar* var, #if 0 && CINDEX_HAVE_PRETTY //def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false); #else - ConcatTypeAndName(type_name, qualified_name); + int offset = type_name.size(); + offset += ConcatTypeAndName(type_name, qualified_name); + def.qual_name_offset = offset; + def.short_name_offset += offset; def.detailed_name = type_name; // Append the textual initializer, bit field, constructor to |hover|. // Omit |hover| for these types: @@ -947,7 +976,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, if (param->toplevel_type) { IndexType* ref_type = db->Resolve(*param->toplevel_type); std::string name = cursor.get_referenced().get_spell_name(); - if (name == ref_type->def.ShortName()) { + if (name == ref_type->def.Name(false)) { AddUseSpell(db, ref_type->uses, cursor); param->toplevel_type = std::nullopt; return; @@ -1236,6 +1265,7 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, if (cursor.get_kind() == CXCursor_MacroDefinition) { CXSourceRange cx_extent = clang_getCursorExtent(cursor.cx_cursor); var_def->def.detailed_name = cursor.get_display_name(); + var_def->def.qual_name_offset = 0; var_def->def.short_name_offset = 0; var_def->def.short_name_size = int16_t(strlen(var_def->def.detailed_name.c_str())); @@ -1407,11 +1437,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, } // namespace -std::pair NamespaceHelper::QualifiedName( +std::tuple NamespaceHelper::QualifiedName( const CXIdxContainerInfo* container, std::string_view unqualified_name) { if (!container) - return {std::string(unqualified_name), 0}; + return {std::string(unqualified_name), 0, 0}; // Anonymous namespaces are not processed by indexDeclaration. We trace // nested namespaces bottom-up through clang_getCursorSemanticParent until // one that we know its qualified name. Then do another trace top-down and @@ -1441,9 +1471,9 @@ std::pair NamespaceHelper::QualifiedName( qualifier += "::"; container_cursor_to_qualified_name[namespaces[i]] = qualifier; } - int pos = qualifier.size(); + int16_t pos = qualifier.size(); qualifier.append(unqualified_name); - return {qualifier, pos}; + return {qualifier, pos, int16_t(unqualified_name.size())}; } void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { @@ -1669,14 +1699,14 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // insert the qualified name before the first '('. // FIXME GetFunctionSignature should set index #if CINDEX_HAVE_PRETTY - func->def.detailed_name = param->PrettyPrintCursor(decl->cursor); + std::tie(func->def.detailed_name, func->def.qual_name_offset, + func->def.short_name_offset, func->def.short_name_size) = + param->PrettyPrintCursor(decl->cursor, decl->entityInfo->name); #else - func->def.detailed_name = GetFunctionSignature(db, ¶m->ns, decl); + std::tie(func->def.detailed_name, func->def.qual_name_offset, + func->def.short_name_offset, func->def.short_name_size) = + GetFunctionSignature(db, ¶m->ns, decl); #endif - auto idx = func->def.detailed_name.find(decl->entityInfo->name); - assert(idx != std::string::npos); - func->def.short_name_offset = idx; - func->def.short_name_size = strlen(decl->entityInfo->name); // CXCursor_OverloadedDeclRef in templates are not processed by // OnIndexReference, thus we use TemplateVisitor to collect function @@ -1843,7 +1873,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // cursor if (origin->def.detailed_name.empty()) { SetTypeName(origin, origin_cursor, nullptr, - &type->def.ShortName()[0], param); + &type->def.Name(false)[0], param); origin->def.kind = type->def.kind; } // TODO The name may be assigned in |ResolveToDeclarationType| but @@ -2046,7 +2076,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR)); IndexFunc* called = db->Resolve(called_id); - std::string_view short_name = called->def.ShortName(); + std::string_view short_name = called->def.Name(false); // libclang doesn't provide a nice api to check if the given function // call is implicit. ref->kind should probably work (it's either direct // or implicit), but libclang only supports implicit for objective-c. @@ -2296,11 +2326,15 @@ std::vector> ParseWithTu( return result; } -void ConcatTypeAndName(std::string& type, const std::string& name) { +bool ConcatTypeAndName(std::string& type, const std::string& name) { + bool ret = false; if (type.size() && - (type.back() != ' ' && type.back() != '*' && type.back() != '&')) + (type.back() != ' ' && type.back() != '*' && type.back() != '&')) { type.push_back(' '); + ret = true; + } type.append(name); + return ret; } void IndexInit() { diff --git a/src/indexer.h b/src/indexer.h index 8a6decea7..a57febe1f 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -140,8 +140,22 @@ struct IndexFamily { using Range = ::Range; }; +template +struct NameMixin { + std::string_view Name(bool qualified) const { + auto self = static_cast(this); + return qualified ? std::string_view( + self->detailed_name.c_str() + self->qual_name_offset, + self->short_name_offset - self->qual_name_offset + + self->short_name_size) + : std::string_view(self->detailed_name.c_str() + + self->short_name_offset, + self->short_name_size); + } +}; + template -struct TypeDefDefinitionData { +struct TypeDef : NameMixin> { // General metadata. std::string detailed_name; NtString hover; @@ -172,31 +186,26 @@ struct TypeDefDefinitionData { // type comes from a using or typedef statement). Maybe alias_of; + int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; - bool operator==(const TypeDefDefinitionData& o) const { + bool operator==(const TypeDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && extent == o.extent && alias_of == o.alias_of && bases == o.bases && types == o.types && funcs == o.funcs && vars == o.vars && kind == o.kind && hover == o.hover && comments == o.comments; } - bool operator!=(const TypeDefDefinitionData& o) const { + bool operator!=(const TypeDef& o) const { return !(*this == o); } - - std::string_view ShortName() const { - return std::string_view(detailed_name.c_str() + short_name_offset, - short_name_size); - } - // Used by ccls_inheritance_hierarchy.cc:Expand generic lambda - std::string_view DetailedName(bool) const { return detailed_name; } }; template -void Reflect(TVisitor& visitor, TypeDefDefinitionData& value) { +void Reflect(TVisitor& visitor, TypeDef& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); + REFLECT_MEMBER(qual_name_offset); REFLECT_MEMBER(short_name_offset); REFLECT_MEMBER(short_name_size); REFLECT_MEMBER(kind); @@ -214,7 +223,7 @@ void Reflect(TVisitor& visitor, TypeDefDefinitionData& value) { } struct IndexType { - using Def = TypeDefDefinitionData; + using Def = TypeDef; Usr usr; IndexTypeId id; @@ -240,7 +249,7 @@ struct IndexType { MAKE_HASHABLE(IndexType, t.id); template -struct FuncDefDefinitionData { +struct FuncDef : NameMixin> { // General metadata. std::string detailed_name; NtString hover; @@ -260,38 +269,29 @@ struct FuncDefDefinitionData { typename F::FileId file; // Type which declares this one (ie, it is a method) Maybe declaring_type; + int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; StorageClass storage = StorageClass::Invalid; - bool operator==(const FuncDefDefinitionData& o) const { + bool operator==(const FuncDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && extent == o.extent && declaring_type == o.declaring_type && bases == o.bases && vars == o.vars && callees == o.callees && kind == o.kind && storage == o.storage && hover == o.hover && comments == o.comments; } - bool operator!=(const FuncDefDefinitionData& o) const { + bool operator!=(const FuncDef& o) const { return !(*this == o); } - - std::string_view ShortName() const { - return std::string_view(detailed_name.c_str() + short_name_offset, - short_name_size); - } - std::string_view DetailedName(bool params) const { - if (params) - return detailed_name; - return std::string_view(detailed_name) - .substr(0, short_name_offset + short_name_size); - } }; template -void Reflect(TVisitor& visitor, FuncDefDefinitionData& value) { +void Reflect(TVisitor& visitor, FuncDef& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); + REFLECT_MEMBER(qual_name_offset); REFLECT_MEMBER(short_name_offset); REFLECT_MEMBER(short_name_size); REFLECT_MEMBER(kind); @@ -308,8 +308,8 @@ void Reflect(TVisitor& visitor, FuncDefDefinitionData& value) { REFLECT_MEMBER_END(); } -struct IndexFunc { - using Def = FuncDefDefinitionData; +struct IndexFunc : NameMixin { + using Def = FuncDef; Usr usr; IndexFuncId id; @@ -345,7 +345,7 @@ MAKE_HASHABLE(IndexFunc, t.id); MAKE_REFLECT_STRUCT(IndexFunc::Declaration, spell, param_spellings); template -struct VarDefDefinitionData { +struct VarDef : NameMixin> { // General metadata. std::string detailed_name; NtString hover; @@ -360,6 +360,7 @@ struct VarDefDefinitionData { Maybe type; // Function/type which declares this one. + int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; @@ -370,41 +371,21 @@ struct VarDefDefinitionData { bool is_local() const { return kind == lsSymbolKind::Variable; } - bool operator==(const VarDefDefinitionData& o) const { + bool operator==(const VarDef& 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; } - bool operator!=(const VarDefDefinitionData& o) const { return !(*this == o); } - - std::string_view ShortName() const { - return std::string_view(detailed_name.c_str() + short_name_offset, - short_name_size); - } - std::string DetailedName(bool qualified) const { - if (qualified) - return detailed_name; - int i = short_name_offset; - for (int paren = 0; i; i--) { - // Skip parentheses in "(anon struct)::name" - if (detailed_name[i - 1] == ')') - paren++; - else if (detailed_name[i - 1] == '(') - paren--; - else if (!(paren > 0 || isalnum(detailed_name[i - 1]) || - detailed_name[i - 1] == '_' || detailed_name[i - 1] == ':')) - break; - } - return detailed_name.substr(0, i) + detailed_name.substr(short_name_offset); - } + bool operator!=(const VarDef& o) const { return !(*this == o); } }; template -void Reflect(TVisitor& visitor, VarDefDefinitionData& value) { +void Reflect(TVisitor& visitor, VarDef& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); - REFLECT_MEMBER(short_name_size); + REFLECT_MEMBER(qual_name_offset); REFLECT_MEMBER(short_name_offset); + REFLECT_MEMBER(short_name_size); REFLECT_MEMBER(hover); REFLECT_MEMBER(comments); REFLECT_MEMBER(spell); @@ -417,7 +398,7 @@ void Reflect(TVisitor& visitor, VarDefDefinitionData& value) { } struct IndexVar { - using Def = VarDefDefinitionData; + using Def = VarDef; Usr usr; IndexVarId id; @@ -509,8 +490,9 @@ struct NamespaceHelper { std::unordered_map container_cursor_to_qualified_name; - std::pair QualifiedName(const CXIdxContainerInfo* container, - std::string_view unqualified_name); + std::tuple QualifiedName( + const CXIdxContainerInfo* container, + std::string_view unqualified_name); }; // |import_file| is the cc file which is what gets passed to clang. @@ -534,7 +516,7 @@ std::vector> ParseWithTu( const std::vector& args, const std::vector& file_contents); -void ConcatTypeAndName(std::string& type, const std::string& name); +bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); diff --git a/src/message_handler.cc b/src/message_handler.cc index cdc2d98a2..78b32eec1 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -222,9 +222,8 @@ void EmitSemanticHighlighting(QueryDatabase* db, } // Don't highlight overloadable operators or implicit lambda -> // std::function constructor. - std::string_view short_name = def->ShortName(); - if (short_name.compare(0, 8, "operator") == 0 || - short_name.compare(0, 27, "functionName(false); + if (short_name.compare(0, 8, "operator") == 0) continue; // applies to for loop if (def->spell) parent_kind = GetSymbolKind(db, *def->spell); diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 04e117f87..50a83ae66 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -37,7 +37,7 @@ struct In_CclsCallHierarchy : public RequestInMessage { // Base: include base functions; All: include both base and derived // functions. CallType callType = CallType::All; - bool detailedName = false; + bool qualified = true; int levels = 1; }; Params params; @@ -49,7 +49,7 @@ MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, id, callee, callType, - detailedName, + qualified, levels); MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsCallHierarchy); @@ -81,7 +81,7 @@ bool Expand(MessageHandler* m, Out_CclsCallHierarchy::Entry* entry, bool callee, CallType call_type, - bool detailed_name, + bool qualified, int levels) { const QueryFunc& func = m->db->funcs[entry->id.id]; const QueryFunc::Def* def = func.AnyDef(); @@ -96,7 +96,7 @@ bool Expand(MessageHandler* m, if (auto loc = GetLsLocation(m->db, m->working_files, use)) entry1.location = *loc; entry1.callType = call_type; - if (Expand(m, &entry1, callee, call_type, detailed_name, levels - 1)) + if (Expand(m, &entry1, callee, call_type, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); } }; @@ -117,10 +117,7 @@ bool Expand(MessageHandler* m, std::unordered_set seen; seen.insert(func.usr); std::vector stack; - if (detailed_name) - entry->name = def->detailed_name; - else - entry->name = def->ShortName(); + entry->name = def->Name(qualified); handle_uses(func, CallType::Direct); // Callers/callees of base functions. @@ -166,7 +163,7 @@ struct Handler_CclsCallHierarchy std::optional BuildInitial(QueryFuncId root_id, bool callee, CallType call_type, - bool detailed_name, + bool qualified, int levels) { const auto* def = db->funcs[root_id.id].AnyDef(); if (!def) @@ -180,7 +177,7 @@ struct Handler_CclsCallHierarchy GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - Expand(this, &entry, callee, call_type, detailed_name, levels); + Expand(this, &entry, callee, call_type, qualified, levels); return entry; } @@ -194,8 +191,8 @@ struct Handler_CclsCallHierarchy entry.id = *params.id; entry.callType = CallType::Direct; if (entry.id.id < db->funcs.size()) - Expand(this, &entry, params.callee, params.callType, - params.detailedName, params.levels); + Expand(this, &entry, params.callee, params.callType, params.qualified, + params.levels); out.result = std::move(entry); } else { QueryFile* file; @@ -209,7 +206,7 @@ struct Handler_CclsCallHierarchy if (sym.kind == SymbolKind::Func) { out.result = BuildInitial(QueryFuncId(sym.id), params.callee, params.callType, - params.detailedName, params.levels); + params.qualified, params.levels); break; } } diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 29b9ad5ef..52ab1ba17 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -18,7 +18,7 @@ struct In_CclsInheritanceHierarchy : public RequestInMessage { // true: derived classes/functions; false: base classes/functions bool derived = false; - bool detailedName = false; + bool qualified = true; int levels = 1; }; Params params; @@ -30,7 +30,7 @@ MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, id, kind, derived, - detailedName, + qualified, levels); MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); @@ -63,14 +63,14 @@ MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy, jsonrpc, id, result); bool Expand(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry* entry, bool derived, - bool detailed_name, + bool qualified, int levels); template bool ExpandHelper(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry* entry, bool derived, - bool detailed_name, + bool qualified, int levels, Q& entity) { const auto* def = entity.AnyDef(); @@ -78,10 +78,7 @@ bool ExpandHelper(MessageHandler* m, entry->numChildren = 0; return false; } - if (detailed_name) - entry->name = def->DetailedName(false); - else - entry->name = def->ShortName(); + entry->name = def->Name(qualified); if (def->spell) { if (std::optional loc = GetLsLocation(m->db, m->working_files, *def->spell)) @@ -93,7 +90,7 @@ bool ExpandHelper(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = id; entry1.kind = entry->kind; - if (Expand(m, &entry1, derived, detailed_name, levels - 1)) + if (Expand(m, &entry1, derived, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); } entry->numChildren = int(entry->children.size()); @@ -105,7 +102,7 @@ bool ExpandHelper(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = id; entry1.kind = entry->kind; - if (Expand(m, &entry1, derived, detailed_name, levels - 1)) + if (Expand(m, &entry1, derived, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); } entry->numChildren = int(entry->children.size()); @@ -118,13 +115,13 @@ bool ExpandHelper(MessageHandler* m, bool Expand(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry* entry, bool derived, - bool detailed_name, + bool qualified, int levels) { if (entry->kind == SymbolKind::Func) - return ExpandHelper(m, entry, derived, detailed_name, levels, + return ExpandHelper(m, entry, derived, qualified, levels, m->db->funcs[entry->id.id]); else - return ExpandHelper(m, entry, derived, detailed_name, levels, + return ExpandHelper(m, entry, derived, qualified, levels, m->db->types[entry->id.id]); } @@ -133,11 +130,11 @@ struct Handler_CclsInheritanceHierarchy MethodType GetMethodType() const override { return kMethodType; } std::optional - BuildInitial(SymbolRef sym, bool derived, bool detailed_name, int levels) { + BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) { Out_CclsInheritanceHierarchy::Entry entry; entry.id = sym.id; entry.kind = sym.kind; - Expand(this, &entry, derived, detailed_name, levels); + Expand(this, &entry, derived, qualified, levels); return entry; } @@ -153,7 +150,7 @@ struct Handler_CclsInheritanceHierarchy if (((entry.kind == SymbolKind::Func && entry.id.id < db->funcs.size()) || (entry.kind == SymbolKind::Type && entry.id.id < db->types.size())) && - Expand(this, &entry, params.derived, params.detailedName, + Expand(this, &entry, params.derived, params.qualified, params.levels)) out.result = std::move(entry); } else { @@ -167,7 +164,7 @@ struct Handler_CclsInheritanceHierarchy for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { - out.result = BuildInitial(sym, params.derived, params.detailedName, + out.result = BuildInitial(sym, params.derived, params.qualified, params.levels); break; } diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 619b51535..a29912932 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -16,7 +16,7 @@ struct In_CclsMemberHierarchy : public RequestInMessage { Maybe id; - bool detailedName = false; + bool qualified = false; int levels = 1; }; Params params; @@ -26,7 +26,7 @@ MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, - detailedName, + qualified, levels); MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); @@ -58,23 +58,24 @@ MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy, jsonrpc, id, result); bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, - bool detailed_name, + bool qualified, int levels); // Add a field to |entry| which is a Func/Type. void DoField(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, const QueryVar& var, - bool detailed_name, + bool qualified, int levels) { const QueryVar::Def* def1 = var.AnyDef(); if (!def1) return; Out_CclsMemberHierarchy::Entry entry1; - if (detailed_name) - entry1.fieldName = def1->DetailedName(false); + if (qualified) + entry1.fieldName = def1->detailed_name; else - entry1.fieldName = std::string(def1->ShortName()); + entry1.fieldName = def1->detailed_name.substr(0, def1->qual_name_offset) + + std::string(def1->Name(false)); if (def1->spell) { if (std::optional loc = GetLsLocation(m->db, m->working_files, *def1->spell)) @@ -82,7 +83,7 @@ void DoField(MessageHandler* m, } if (def1->type) { entry1.id = *def1->type; - if (Expand(m, &entry1, detailed_name, levels)) + if (Expand(m, &entry1, qualified, levels)) entry->children.push_back(std::move(entry1)); } else { entry1.id = QueryTypeId(); @@ -93,21 +94,18 @@ void DoField(MessageHandler* m, // Expand a type node by adding members recursively to it. bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, - bool detailed_name, + bool qualified, int levels) { const QueryType& type = m->db->types[entry->id.id]; const QueryType::Def* def = type.AnyDef(); - // builtin types have no declaration and empty |detailed_name|. + // builtin types have no declaration and empty |qualified|. if (CXType_FirstBuiltin <= type.usr && type.usr <= CXType_LastBuiltin) { entry->name = ClangBuiltinTypeName(CXTypeKind(type.usr)); return true; } if (!def) return false; - if (detailed_name) - entry->name = def->detailed_name; - else - entry->name = def->ShortName(); + entry->name = def->Name(qualified); std::unordered_set seen; if (levels > 0) { std::vector stack; @@ -139,17 +137,17 @@ bool Expand(MessageHandler* m, GetLsLocation(m->db, m->working_files, *def->spell)) entry1.location = *loc; } - if (def1 && detailed_name) + if (def1 && qualified) entry1.fieldName = def1->detailed_name; - if (Expand(m, &entry1, detailed_name, levels - 1)) { + if (Expand(m, &entry1, qualified, levels - 1)) { // For builtin types |name| is set. - if (detailed_name && entry1.fieldName.empty()) + if (entry1.fieldName.empty()) entry1.fieldName = std::string(entry1.name); entry->children.push_back(std::move(entry1)); } } else { EachDefinedEntity(m->db->vars, def->vars, [&](QueryVar& var) { - DoField(m, entry, var, detailed_name, levels - 1); + DoField(m, entry, var, qualified, levels - 1); }); } } @@ -165,7 +163,7 @@ struct Handler_CclsMemberHierarchy MethodType GetMethodType() const override { return kMethodType; } std::optional BuildInitial(QueryFuncId root_id, - bool detailed_name, + bool qualified, int levels) { const auto* def = db->funcs[root_id.id].AnyDef(); if (!def) @@ -173,23 +171,20 @@ struct Handler_CclsMemberHierarchy Out_CclsMemberHierarchy::Entry entry; // Not type, |id| is invalid. - if (detailed_name) - entry.name = def->DetailedName(false); - else - entry.name = std::string(def->ShortName()); + entry.name = std::string(def->Name(qualified)); if (def->spell) { if (std::optional loc = GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } EachDefinedEntity(db->vars, def->vars, [&](QueryVar& var) { - DoField(this, &entry, var, detailed_name, levels - 1); + DoField(this, &entry, var, qualified, levels - 1); }); return entry; } std::optional BuildInitial(QueryTypeId root_id, - bool detailed_name, + bool qualified, int levels) { const auto* def = db->types[root_id.id].AnyDef(); if (!def) @@ -202,7 +197,7 @@ struct Handler_CclsMemberHierarchy GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - Expand(this, &entry, detailed_name, levels); + Expand(this, &entry, qualified, levels); return entry; } @@ -216,7 +211,7 @@ struct Handler_CclsMemberHierarchy entry.id = *request->params.id; // entry.name is empty as it is known by the client. if (entry.id.id < db->types.size() && - Expand(this, &entry, params.detailedName, params.levels)) + Expand(this, &entry, params.qualified, params.levels)) out.result = std::move(entry); } else { QueryFile* file; @@ -229,18 +224,18 @@ struct Handler_CclsMemberHierarchy FindSymbolsAtLocation(working_file, file, params.position)) { switch (sym.kind) { case SymbolKind::Func: - out.result = BuildInitial(QueryFuncId(sym.id), params.detailedName, + out.result = BuildInitial(QueryFuncId(sym.id), params.qualified, params.levels); break; case SymbolKind::Type: - out.result = BuildInitial(QueryTypeId(sym.id), params.detailedName, + out.result = BuildInitial(QueryTypeId(sym.id), params.qualified, params.levels); break; case SymbolKind::Var: { const QueryVar::Def* def = db->GetVar(sym).AnyDef(); if (def && def->type) out.result = BuildInitial(QueryTypeId(*def->type), - params.detailedName, params.levels); + params.qualified, params.levels); break; } default: diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 15216aceb..35fec5bde 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -142,20 +142,20 @@ struct Handler_TextDocumentDefinition if (db->symbols[i].kind == SymbolKind::Invalid) continue; - std::string_view name = short_query.size() < query.size() - ? db->GetSymbolDetailedName(i) - : db->GetSymbolShortName(i); - auto pos = name.rfind(short_query); - if (pos == std::string::npos) + std::string_view short_name = db->GetSymbolName(i, false), + name = short_query.size() < query.size() + ? db->GetSymbolName(i, true) + : short_name; + if (short_name != short_query) continue; if (Maybe use = GetDefinitionSpell(db, db->symbols[i])) { std::tuple score{ - int(name.size() - short_query.size()), -pos, + int(name.size() - short_query.size()), 0, use->file != file_id, std::abs(use->range.start.line - position.line)}; // Update the score with qualified name if the qualified name // occurs in |name|. - pos = name.rfind(query); + auto pos = name.rfind(query); if (pos != std::string::npos) { std::get<0>(score) = int(name.size() - query.size()); std::get<1>(score) = -pos; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 06140b507..e556ba93a 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -84,7 +84,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { // Find exact substring matches. for (int i = 0; i < db->symbols.size(); ++i) { - std::string_view detailed_name = db->GetSymbolDetailedName(i); + std::string_view detailed_name = db->GetSymbolName(i, true); if (detailed_name.find(query) != std::string::npos) { // Do not show the same entry twice. if (!inserted_results.insert(std::string(detailed_name)).second) @@ -108,7 +108,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { query_without_space += c; for (int i = 0; i < (int)db->symbols.size(); ++i) { - std::string_view detailed_name = db->GetSymbolDetailedName(i); + std::string_view detailed_name = db->GetSymbolName(i, true); if (CaseFoldingSubsequenceMatch(query_without_space, detailed_name) .first) { // Do not show the same entry twice. @@ -129,12 +129,12 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { // Sort results with a fuzzy matching algorithm. int longest = 0; for (int i : result_indices) - longest = std::max(longest, int(db->GetSymbolDetailedName(i).size())); + longest = std::max(longest, int(db->GetSymbolName(i, true).size())); FuzzyMatcher fuzzy(query); std::vector> permutation(result_indices.size()); for (int i = 0; i < int(result_indices.size()); i++) { permutation[i] = { - fuzzy.Match(db->GetSymbolDetailedName(result_indices[i])), i}; + fuzzy.Match(db->GetSymbolName(result_indices[i], true)), i}; } std::sort(permutation.begin(), permutation.end(), std::greater>()); diff --git a/src/query.cc b/src/query.cc index 389971b30..e504619b7 100644 --- a/src/query.cc +++ b/src/query.cc @@ -35,6 +35,7 @@ std::optional ToQuery(const IdMap& id_map, QueryType::Def result; result.detailed_name = type.detailed_name; + result.qual_name_offset = type.qual_name_offset; result.short_name_offset = type.short_name_offset; result.short_name_size = type.short_name_size; result.kind = type.kind; @@ -60,6 +61,7 @@ std::optional ToQuery(const IdMap& id_map, QueryFunc::Def result; result.detailed_name = func.detailed_name; + result.qual_name_offset = func.qual_name_offset; result.short_name_offset = func.short_name_offset; result.short_name_size = func.short_name_size; result.kind = func.kind; @@ -84,6 +86,7 @@ std::optional ToQuery(const IdMap& id_map, const IndexVar::Def& v QueryVar::Def result; result.detailed_name = var.detailed_name; + result.qual_name_offset = var.qual_name_offset; result.short_name_offset = var.short_name_offset; result.short_name_size = var.short_name_size; if (!var.hover.empty()) @@ -900,8 +903,8 @@ void QueryDatabase::UpdateSymbols(Maybe>* symbol_idx, } } -// For Func, the returned name does not include parameters. -std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const { +std::string_view QueryDatabase::GetSymbolName(RawId symbol_idx, + bool qualified) const { RawId idx = symbols[symbol_idx].id.id; switch (symbols[symbol_idx].kind) { default: @@ -912,40 +915,15 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const { break; case SymbolKind::Func: if (const auto* def = funcs[idx].AnyDef()) - return def->DetailedName(false); + return def->Name(qualified); break; case SymbolKind::Type: if (const auto* def = types[idx].AnyDef()) - return def->detailed_name; + return def->Name(qualified); break; case SymbolKind::Var: if (const auto* def = vars[idx].AnyDef()) - return def->detailed_name; - break; - } - return ""; -} - -std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const { - RawId idx = symbols[symbol_idx].id.id; - switch (symbols[symbol_idx].kind) { - default: - break; - case SymbolKind::File: - if (files[idx].def) - return files[idx].def->path; - break; - case SymbolKind::Func: - if (const auto* def = funcs[idx].AnyDef()) - return def->ShortName(); - break; - case SymbolKind::Type: - if (const auto* def = types[idx].AnyDef()) - return def->ShortName(); - break; - case SymbolKind::Var: - if (const auto* def = vars[idx].AnyDef()) - return def->ShortName(); + return def->Name(qualified); break; } return ""; diff --git a/src/query.h b/src/query.h index 0ff4f3ef2..7a15c239d 100644 --- a/src/query.h +++ b/src/query.h @@ -152,7 +152,7 @@ struct QueryEntity { const Def* AnyDef() const { return const_cast(this)->AnyDef(); } }; -struct QueryType : QueryEntity> { +struct QueryType : QueryEntity> { using DerivedUpdate = MergeableUpdate; using InstancesUpdate = MergeableUpdate; @@ -167,7 +167,7 @@ struct QueryType : QueryEntity> { explicit QueryType(const Usr& usr) : usr(usr) {} }; -struct QueryFunc : QueryEntity> { +struct QueryFunc : QueryEntity> { using DerivedUpdate = MergeableUpdate; Usr usr; @@ -180,7 +180,7 @@ struct QueryFunc : QueryEntity> { explicit QueryFunc(const Usr& usr) : usr(usr) {} }; -struct QueryVar : QueryEntity> { +struct QueryVar : QueryEntity> { Usr usr; Maybe> symbol_idx; std::forward_list def; @@ -288,8 +288,7 @@ struct QueryDatabase { void UpdateSymbols(Maybe>* symbol_idx, SymbolKind kind, Id idx); - std::string_view GetSymbolDetailedName(RawId symbol_idx) const; - std::string_view GetSymbolShortName(RawId symbol_idx) const; + std::string_view GetSymbolName(RawId symbol_idx, bool qualified) const; // Query the indexing structure to look up symbol id for given Usr. Maybe GetQueryFileIdFromPath(const std::string& path); diff --git a/src/query_utils.cc b/src/query_utils.cc index e30b6d43f..a016fedc2 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -302,7 +302,7 @@ std::optional GetSymbolInfo(QueryDatabase* db, lsSymbolInformation info; EachEntityDef(db, sym, [&](const auto& def) { if (use_short_name) - info.name = def.ShortName(); + info.name = def.Name(true); else info.name = def.detailed_name; info.kind = def.kind; diff --git a/src/serializer.cc b/src/serializer.cc index 3e8bd3b9a..391a5999a 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -210,6 +210,7 @@ void Reflect(TVisitor& visitor, IndexType& value) { REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); REFLECT_MEMBER2("kind", value.def.kind); ReflectHoverAndComments(visitor, value.def); @@ -233,6 +234,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("storage", value.def.storage); @@ -255,6 +257,7 @@ void Reflect(TVisitor& visitor, IndexVar& value) { REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); ReflectHoverAndComments(visitor, value.def); REFLECT_MEMBER2("declarations", value.declarations); diff --git a/src/test.cc b/src/test.cc index 2453ed03d..f94e447e5 100644 --- a/src/test.cc +++ b/src/test.cc @@ -89,8 +89,10 @@ void ParseTestExpectation( active_output_contents = ""; in_output = true; - } else if (in_output) + } else if (in_output) { active_output_contents += line_with_ending; + active_output_contents.push_back('\n'); + } } if (in_output) diff --git a/src/type_printer.cc b/src/type_printer.cc index 4557dada9..06346d470 100644 --- a/src/type_printer.cc +++ b/src/type_printer.cc @@ -34,11 +34,14 @@ int GetNameInsertingPosition(const std::string& type_desc, } // namespace // Build a detailed function signature, including argument names. -std::string GetFunctionSignature(IndexFile* db, - NamespaceHelper* ns, - const CXIdxDeclInfo* decl) { +std::tuple GetFunctionSignature( + IndexFile* db, + NamespaceHelper* ns, + const CXIdxDeclInfo* decl) { int num_args = clang_Cursor_getNumArguments(decl->cursor); - std::pair function_name = + int16_t qual_name_offset, short_name_offset, short_name_size; + std::string func_name; + std::tie(func_name, short_name_offset, short_name_size) = ns->QualifiedName(decl->semanticContainer, decl->entityInfo->name); std::vector> args; @@ -52,15 +55,15 @@ std::string GetFunctionSignature(IndexFile* db, } std::string type_desc = ClangCursor(decl->cursor).get_type_description(); - int function_name_offset = GetNameInsertingPosition( + qual_name_offset = GetNameInsertingPosition( type_desc, ::ToString(clang_getTypeSpelling( clang_getCursorResultType(decl->cursor)))); - if (type_desc[function_name_offset] == '(') { + if (type_desc[qual_name_offset] == '(') { // Find positions to insert argument names. // Argument name are before ',' or closing ')'. num_args = 0; - for (int balance = 0, i = function_name_offset; + for (int balance = 0, i = qual_name_offset; i < int(type_desc.size()) && num_args < int(args.size()); i++) { if (type_desc[i] == '(' || type_desc[i] == '[') balance++; @@ -74,9 +77,10 @@ std::string GetFunctionSignature(IndexFile* db, } // Second pass: insert argument names before each comma and closing paren. - int i = function_name_offset; + int i = qual_name_offset; + short_name_offset += qual_name_offset; std::string type_desc_with_names(type_desc.begin(), type_desc.begin() + i); - type_desc_with_names.append(function_name.first); + type_desc_with_names.append(func_name); for (auto& arg : args) { if (arg.first < 0) { LOG_S(ERROR) @@ -98,9 +102,12 @@ std::string GetFunctionSignature(IndexFile* db, type_desc = std::move(type_desc_with_names); } else { // type_desc is either a typedef, or some complicated type we cannot handle. - // Append the function_name in this case. - ConcatTypeAndName(type_desc, function_name.first); + // Append the func_name in this case. + int offset = type_desc.size(); + offset += ConcatTypeAndName(type_desc, func_name); + qual_name_offset = offset; + short_name_offset += offset; } - return type_desc; + return {type_desc, qual_name_offset, short_name_offset, short_name_size}; } diff --git a/src/type_printer.h b/src/type_printer.h index 2e724c693..87b39ca51 100644 --- a/src/type_printer.h +++ b/src/type_printer.h @@ -2,6 +2,7 @@ #include "indexer.h" -std::string GetFunctionSignature(IndexFile* db, - NamespaceHelper* ns, - const CXIdxDeclInfo* decl); +std::tuple GetFunctionSignature( + IndexFile* db, + NamespaceHelper* ns, + const CXIdxDeclInfo* decl); From 98a4ef52886bb530f5962d18d7f5de810b47f8ad Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 6 Apr 2018 00:26:53 -0700 Subject: [PATCH 066/378] Import cmake improvement by Daan De Meyer --- CMakeLists.txt | 88 +++++++++++++------- cmake/DownloadAndExtract7zip.cmake | 55 ++++++------ cmake/DownloadAndExtractClang.cmake | 124 ++++++++++++++++++++++++++++ cmake/DownloadAndExtractLLVM.cmake | 112 ------------------------- cmake/FindClang.cmake | 33 +++++--- 5 files changed, 231 insertions(+), 181 deletions(-) create mode 100644 cmake/DownloadAndExtractClang.cmake delete mode 100644 cmake/DownloadAndExtractLLVM.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f95f61715..52e26ebc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,14 @@ project(ccls LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) -include(DownloadAndExtractLLVM) -set(CLANG_VERSION 6.0.0 CACHE STRING "Downloaded Clang version (6.0.0)") -option(SYSTEM_CLANG "Use system Clang instead of downloading Clang" OFF) +# Required libclang version +set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version") +set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} + CACHE STRING "Downloaded libclang location") +option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \ + downloading libclang" OFF) option(ASAN "Compile with address sanitizers" OFF) -option(CLANG_CXX "Build with Clang C++ api required by some ccls \ -features (warning: not available in LLVM Windows downloads)" OFF) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") @@ -63,13 +64,6 @@ else() $<$:-fno-limit-debug-info>) endif() - if(CLANG_CXX) - # -Wno-comment: include/clang/Format/Format.h error: multi-line comment - # -fno-rtti: # Without -fno-rtti, some Clang C++ functions may report - # `undefined references to typeinfo` - target_compile_options(ccls PRIVATE -Wno-comment -fno-rtti) - endif() - if(ASAN) target_compile_options(ccls PRIVATE -fsanitize=address,undefined) # target_link_libraries also takes linker flags @@ -77,18 +71,23 @@ else() endif() endif() -### Download Clang if required +### Download libclang if required -if(NOT SYSTEM_CLANG) - download_and_extract_llvm(${CLANG_VERSION}) +if(NOT SYSTEM_LIBCLANG) + message(STATUS "Using downloaded libclang") + + include(DownloadAndExtractClang) + download_and_extract_clang(${LIBCLANG_VERSION} ${LIBCLANG_DOWNLOAD_LOCATION}) # Used by FindClang set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) +else() + message(STATUS "Using system libclang") endif() ### Libraries # See cmake/FindClang.cmake -find_package(Clang REQUIRED) +find_package(Clang ${CLANG_VERSION} REQUIRED) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support @@ -96,7 +95,9 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) -if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + target_link_libraries(ccls PRIVATE -lc++experimental) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) else() target_link_libraries(ccls PRIVATE -lstdc++fs) endif() @@ -117,12 +118,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) target_link_libraries(ccls PRIVATE Psapi) endif() -if(CLANG_CXX) - # Clang C++ api uses ncurses - find_package(Curses REQUIRED) - target_link_libraries(ccls PRIVATE ${CURSES_LIBRARIES}) -endif() - ### Definitions target_compile_definitions(ccls PRIVATE @@ -131,10 +126,6 @@ target_compile_definitions(ccls PRIVATE LOGURU_THREADNAME_WIDTH=13 DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}") -if(CLANG_CXX) - target_compile_definitions(ccls PRIVATE USE_CLANG_CXX=1 LOGURU_RTTI=0) -endif() - ### Includes target_include_directories(ccls PRIVATE @@ -150,9 +141,8 @@ target_include_directories(ccls PRIVATE install(TARGETS ccls RUNTIME DESTINATION bin) -# We don't need to install libclang on Windows if we are using downloaded LLVM -# since libclang is distributed as a static library on Windows -if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) +# TODO: install libclang.dll on Windows as well +if(NOT SYSTEM_LIBCLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) set_property(TARGET ccls APPEND PROPERTY @@ -167,6 +157,44 @@ if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib) endif() +# Allow running from build Windows by copying libclang.dll to build directory +if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) + add_custom_command(TARGET ccls + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${DOWNLOADED_CLANG_DIR}/bin/libclang.dll + $ + COMMENT "Copying libclang.dll to build directory ...") +endif() + +### Tools + +# We use glob here since source files are already manually added with +# target_sources further down +file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h + src/messages/*.h src/messages/*.cc) + +if(Clang_FORMAT AND ${Clang_VERSION} STREQUAL 6.0.0) + add_custom_target(format + COMMAND ${Clang_FORMAT} -i ${SOURCES} + # .clang-format is located in the ccls root project dir + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Running clang-format ...") +else() + # Set error message depending on which condition was false + if (NOT Clang_FORMAT) + set(Clang_FORMAT_ERROR "Error: clang-format executable not found") + elseif(NOT ${Clang_VERSION} STREQUAL 6.0.0) + set(Clang_FORMAT_ERROR "Error: clang-format version does not match \ +6.0.0. Due to differences in clang-format output between versions we only \ +support clang-format 6.0.0") + endif() + + add_custom_target(format + COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold + ${Clang_FORMAT_ERROR}) +endif() + ### Sources target_sources(ccls PRIVATE third_party/siphash.cc) diff --git a/cmake/DownloadAndExtract7zip.cmake b/cmake/DownloadAndExtract7zip.cmake index f3257e6b0..72bc879d5 100644 --- a/cmake/DownloadAndExtract7zip.cmake +++ b/cmake/DownloadAndExtract7zip.cmake @@ -1,51 +1,52 @@ # Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/. # # Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR -# -# Downloads 7-Zip to extract LLVM if it isn't available in the PATH -function(download_and_extract_7zip) +function(download_and_extract_7zip 7ZIP_DOWNLOAD_LOCATION) set(7ZIP_VERSION 1801) set(7ZIP_EXT .msi) set(7ZIP_NAME 7z${7ZIP_VERSION}-x64) set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT}) -set(7ZIP_FILE ${CMAKE_BINARY_DIR}/${7ZIP_FULL_NAME}) -set(7ZIP_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${7ZIP_NAME}) +set(7ZIP_FILE ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_FULL_NAME}) +set(7ZIP_EXTRACT_DIR ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_NAME}) set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME}) -# msiexec requires Windows path separators (\) -file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE) -file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) - -if(NOT EXISTS ${7ZIP_FILE}) - message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...") - file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE}) +# Exit if 7-Zip is already downloaded and extracted +find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH + PATHS ${7ZIP_EXTRACT_DIR}/Files/7-Zip) +if(7ZIP_EXECUTABLE) + message(STATUS "7-Zip already downloaded") + return() endif() -if(NOT EXISTS ${7ZIP_EXTRACT_DIR}) +message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...") +file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE}) - find_program(MSIEXEC_EXECUTABLE msiexec) - if(NOT MSIEXEC_EXECUTABLE) - message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \ +find_program(MSIEXEC_EXECUTABLE msiexec) +if(NOT MSIEXEC_EXECUTABLE) + message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \ installer). Install 7-Zip yourself and make sure it is available in the path") - endif() +endif() - message(STATUS "Extracting downloaded 7-Zip ...") +message(STATUS "Extracting downloaded 7-Zip ...") - # msiexec with /a option allows extraction of msi installers without requiring - # admin privileges. We use this to extract the 7-Zip installer without - # requiring any actions from the user - execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn - TARGETDIR=${7ZIP_EXTRACT_DIR} - OUTPUT_QUIET) -endif() +# msiexec requires Windows path separators (\) +file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE) +file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) + +# msiexec with /a option allows extraction of msi installers without requiring +# admin privileges. We use this to extract the 7-Zip installer without +# requiring any actions from the user +execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn + TARGETDIR=${7ZIP_EXTRACT_DIR} + WORKING_DIRECTORY ${7ZIP_DOWNLOAD_LOCATION} + OUTPUT_QUIET) # Convert back to CMake separators (/) before returning file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) -# Actual directory is nested inside the extract directory. We return the nested -# directory instead of the extract directory +# Actual 7-Zip directory is nested inside the extract directory. set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE) endfunction() \ No newline at end of file diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake new file mode 100644 index 000000000..ee5feaa71 --- /dev/null +++ b/cmake/DownloadAndExtractClang.cmake @@ -0,0 +1,124 @@ +# Downloads and extracts the Clang archive for the current system from +# https://releases.llvm.org +# +# Returns the extracted Clang archive directory in DOWNLOADED_CLANG_DIR +# +# Downloads 7-Zip to extract Clang if it isn't available in the PATH +function(download_and_extract_clang CLANG_VERSION CLANG_DOWNLOAD_LOCATION) + +set(CLANG_ARCHIVE_EXT .tar.xz) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + + set(CLANG_ARCHIVE_NAME + clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) + + set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64) + set(CLANG_ARCHIVE_EXT .exe) + +elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) + + if(${CLANG_VERSION} STREQUAL 6.0.0) + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) + else() + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) + endif() + +endif() + +set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) +set(CLANG_ARCHIVE_FILE ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_FULL_NAME}) +set(CLANG_ARCHIVE_EXTRACT_DIR ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_NAME}) +set(CLANG_ARCHIVE_URL + https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME}) +set(CLANG_ARCHIVE_HASH_FILE + ${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256) + +# Exit if Clang is already downloaded and extracted +set(CLANG_ROOT ${CLANG_ARCHIVE_EXTRACT_DIR}) +find_package(Clang ${CLANG_VERSION} QUIET) +if(Clang_FOUND) + message(STATUS "Clang already downloaded") + set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) + return() +endif() + +if(NOT CLANG_ARCHIVE_NAME) + message(FATAL_ERROR "No Clang archive url specified for current platform \ +(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.") +endif() + +if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE}) + message(FATAL_ERROR "No SHA256 hash available for the current platform \ +(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \ +file an issue to get it added.") +endif() + +# Download Clang archive +message(STATUS "Downloading Clang ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...") +file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE} + STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT) + +# Abort if download failed +list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE) +if(${ERROR_CODE}) + list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING) + message(FATAL_ERROR ${ERROR_STRING}) +endif() + +# Retrieve expected hash from file and strip newline +file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH) +string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH) +# Calculate actual hash +file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH) +# Abort if hashes do not match +if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH}) + message(FATAL_ERROR "SHA256 hash of downloaded Clang does not match \ +expected hash. Remove the build directory and try running CMake again. If this \ +keeps happening, file an issue to report the problem.") +endif() + +if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) + # Download and extract 7-zip if not found in PATH + find_program(7ZIP_EXECUTABLE 7z) + if(NOT 7ZIP_EXECUTABLE) + message(STATUS "7-Zip not found in PATH") + + include(DownloadAndExtract7zip) + download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION}) + find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH + PATHS ${DOWNLOADED_7ZIP_DIR}) + else() + message(STATUS "7-Zip found in PATH") + endif() + + message(STATUS "Extracting downloaded Clang with 7-Zip ...") + + # Avoid running the Clang installer by extracting the exe with 7-Zip + execute_process(COMMAND ${7ZIP_EXECUTABLE} x + -o${CLANG_ARCHIVE_EXTRACT_DIR} + -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} + WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} + OUTPUT_QUIET) + +elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz) + message(STATUS "Extracting downloaded Clang with CMake built-in tar ...") + + # CMake has builtin support for tar via the -E flag + execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} + # Specify working directory to allow running cmake from + # everywhere + # (example: cmake -H"$HOME/ccls" -B"$home/ccls/build") + WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} + OUTPUT_QUIET) +endif() + +set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) + +endfunction() diff --git a/cmake/DownloadAndExtractLLVM.cmake b/cmake/DownloadAndExtractLLVM.cmake deleted file mode 100644 index 4a122e355..000000000 --- a/cmake/DownloadAndExtractLLVM.cmake +++ /dev/null @@ -1,112 +0,0 @@ -# Downloads and extracts the LLVM archive for the current system from -# https://releases.llvm.org -# -# Returns the extracted LLVM archive directory in DOWNLOADED_CLANG_DIR -# -# Downloads 7-Zip to extract LLVM if it isn't available in the PATH -function(download_and_extract_llvm CLANG_VERSION) - -include(DownloadAndExtract7zip) - -set(CLANG_ARCHIVE_EXT .tar.xz) - -if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - - set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) - - set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64) - set(CLANG_ARCHIVE_EXT .exe) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - - if(${CLANG_VERSION} STREQUAL 6.0.0) - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) - else() - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) - endif() -endif() - -if(NOT CLANG_ARCHIVE_NAME) - message(FATAL_ERROR "No LLVM archive url specified for current platform \ -(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.") -endif() - -set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) -set(CLANG_ARCHIVE_FILE ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_FULL_NAME}) -set(CLANG_ARCHIVE_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_NAME}) -set(CLANG_ARCHIVE_URL - https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME}) -set(CLANG_ARCHIVE_HASH_FILE - ${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256) - -if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE}) - message(FATAL_ERROR "No SHA256 hash available for the current platform \ -(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \ -file an issue to get it added.") -endif() - -file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH) -# Strip newline -string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH) - -if(NOT EXISTS ${CLANG_ARCHIVE_FILE}) - message(STATUS "Downloading LLVM ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...") - file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE} - STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT) - - list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE) - if(${ERROR_CODE}) - list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING) - message(FATAL_ERROR ${ERROR_STRING}) - endif() -endif() - -file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH) -if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH}) - message(FATAL_ERROR "SHA256 hash of downloaded LLVM does not match \ -expected hash. Remove the build directory and try running CMake again. If this \ -keeps happening, file an issue to report the problem.") -endif() - -if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR}) - if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) - find_program(7ZIP_EXECUTABLE 7z) - - if(NOT 7ZIP_EXECUTABLE) - message(STATUS "7-Zip not found in PATH") - download_and_extract_7zip() - find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH - PATHS ${DOWNLOADED_7ZIP_DIR}) - else() - message(STATUS "7-Zip found in PATH") - endif() - - message(STATUS "Extracting downloaded LLVM with 7-Zip ...") - - # Avoid running the LLVM installer by extracting the exe with 7-Zip - execute_process(COMMAND ${7ZIP_EXECUTABLE} x - -o${CLANG_ARCHIVE_EXTRACT_DIR} - -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} - OUTPUT_QUIET) - elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz) - message(STATUS "Extracting downloaded LLVM with CMake built-in tar ...") - # CMake has builtin support for tar via the -E flag - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} - # Extract to here to allow running cmake from everywhere - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - OUTPUT_QUIET) - endif() -endif() - -# CMake functions have no return values so we just lift our return variable to -# the parent scope -set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) - -endfunction() diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index c8e0d2473..f21fb57b8 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -2,12 +2,13 @@ # FindClang # --------- # -# Find Clang and LLVM libraries required by cquery +# Find Clang and LLVM libraries required by ccls # # Results are reported in the following variables:: # # Clang_FOUND - True if headers and requested libraries were found # Clang_EXECUTABLE - Clang executable +# Clang_FORMAT - Clang-format executable # Clang_RESOURCE_DIR - Clang resource directory # Clang_VERSION - Clang version as reported by Clang executable # @@ -32,8 +33,8 @@ macro(_Clang_find_library VAR NAME) # Windows needs lib prefix - if (CLANG_ROOT) - find_library(${VAR} NAMES ${NAME} lib${NAME} + if (CLANG_ROOT) + find_library(${VAR} NAMES ${NAME} lib${NAME} NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES lib) else() find_library(${VAR} NAMES ${NAME} lib${NAME}) @@ -42,7 +43,7 @@ endmacro() macro(_Clang_find_path VAR INCLUDE_FILE) if (CLANG_ROOT) - find_path(${VAR} ${INCLUDE_FILE} + find_path(${VAR} ${INCLUDE_FILE} NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES include) else() find_path(${VAR} ${INCLUDE_FILE}) @@ -51,7 +52,7 @@ endmacro() macro(_Clang_find_program VAR NAME) if (CLANG_ROOT) - find_program(${VAR} ${NAME} + find_program(${VAR} ${NAME} NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES bin) else() find_program(${VAR} ${NAME}) @@ -73,14 +74,14 @@ endmacro() ### Start -set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE +set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE Clang_RESOURCE_DIR Clang_VERSION) _Clang_find_library(Clang_LIBRARY clang) _Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) if(CLANG_CXX) - # The order is derived by topological sorting LINK_LIBS in + # The order is derived by topological sorting LINK_LIBS in # clang/lib/*/CMakeLists.txt _Clang_find_and_add_cxx_lib(clangFormat clang/Format/Format.h) _Clang_find_and_add_cxx_lib(clangToolingCore clang/Tooling/Core/Diagnostic.h) @@ -96,16 +97,24 @@ if(CLANG_CXX) _Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h) endif() +_Clang_find_program(Clang_FORMAT clang-format) _Clang_find_program(Clang_EXECUTABLE clang) if(Clang_EXECUTABLE) # Find Clang resource directory with Clang executable - execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir + execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir + RESULT_VARIABLE _Clang_FIND_RESOURCE_DIR_RESULT OUTPUT_VARIABLE Clang_RESOURCE_DIR + ERROR_VARIABLE _Clang_FIND_RESOURCE_DIR_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE) + if(_Clang_FIND_RESOURCE_DIR_RESULT) + message(FATAL_ERROR "Error retrieving Clang resource directory with Clang \ +executable. Output:\n ${_Clang_FIND_RESOURCE_DIR_ERROR}") + endif() + # Find Clang version set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - execute_process(COMMAND ${Clang_EXECUTABLE} --version + execute_process(COMMAND ${Clang_EXECUTABLE} --version OUTPUT_VARIABLE Clang_VERSION) string(REGEX MATCH ${_Clang_VERSION_REGEX} Clang_VERSION ${Clang_VERSION}) endif() @@ -122,8 +131,8 @@ if(Clang_FOUND AND NOT TARGET Clang::Clang) set(_Clang_INCLUDE_DIRS ${Clang_INCLUDE_DIR} ${_Clang_CXX_INCLUDE_DIRS}) add_library(Clang::Clang INTERFACE IMPORTED) - set_property(TARGET Clang::Clang PROPERTY + set_property(TARGET Clang::Clang PROPERTY INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES}) - set_property(TARGET Clang::Clang PROPERTY - INTERFACE_INCLUDE_DIRECTORIES ${_Clang_INCLUDE_DIRS}) + set_property(TARGET Clang::Clang PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${_Clang_INCLUDE_DIRS}) endif() From 992b3cce167558bc38d6fdcb15da4ed519d724eb Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Apr 2018 10:43:56 -0700 Subject: [PATCH 067/378] Use clang_File_tryGetRealPathName --- README.md | 2 +- ci/before_deploy.sh | 8 ++++---- src/clang_utils.cc | 9 +++++++-- src/command_line.cc | 4 ++-- src/project.cc | 4 ++-- src/utils.cc | 3 ++- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5d9737d29..d64955512 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ a C/C++/Objective-C language server. * code completion (with both signature help and snippets) * finding [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc) - * [call (caller/callee) hierarchy](src/messages/cquery_call_hierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/cquery_inheritance_hierarchy.cc), [member hierarchy](src/messages/cquery_member_hierarchy.cc) + * [call (caller/callee) hierarchy](src/messages/ccls_call_hierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance_hierarchy.cc), [member hierarchy](src/messages/ccls_member_hierarchy.cc) * [symbol rename](src/messages/text_document_rename.cc) * [document symbols](src/messages/text_document_document_symbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) * [hover information](src/messages/text_document_hover.cc) diff --git a/ci/before_deploy.sh b/ci/before_deploy.sh index 25fa14e05..e954d7f5c 100755 --- a/ci/before_deploy.sh +++ b/ci/before_deploy.sh @@ -7,15 +7,15 @@ case $(uname -s) in Darwin) libclang=(lib/clang+llvm-*/lib/libclang.dylib) strip_option="-x" - name=cquery-$version-x86_64-apple-darwin ;; + name=ccls-$version-x86_64-apple-darwin ;; FreeBSD) libclang=(lib/clang+llvm-*/lib/libclang.so.?) strip_option="-s" - name=cquery-$version-x86_64-unknown-freebsd10 ;; + name=ccls-$version-x86_64-unknown-freebsd10 ;; Linux) libclang=(lib/clang+llvm-*/lib/libclang.so.?) strip_option="-s" - name=cquery-$version-x86_64-unknown-linux-gnu ;; + name=ccls-$version-x86_64-unknown-linux-gnu ;; *) echo Unsupported >&2 exit 1 ;; @@ -26,7 +26,7 @@ mkdir "$pkg/$name" rsync -rtLR bin "./${libclang[-1]}" ./lib/clang+llvm-*/lib/clang/*/include "$pkg/$name" cd "$pkg" -strip "$strip_option" "$name/bin/cquery" "$name/${libclang[-1]}" +strip "$strip_option" "$name/bin/ccls" "$name/${libclang[-1]}" case $(uname -s) in Darwin) # https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/tar.1.html diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 4a62db7df..2a79b847e 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -106,8 +106,13 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, } std::string FileName(CXFile file) { - CXString cx_name = clang_getFileName(file); - std::string ret = NormalizePath(ToString(cx_name)); + std::string ret; + // clang > 6 +#if CINDEX_VERSION >= 48 + ret = ToString(clang_File_tryGetRealPathName(file)); +#endif + if (ret.empty()) + ret = ToString(clang_getFileName(file)); // Resolve /usr/include/c++/7.3.0 symlink. if (!StartsWith(ret, g_config->projectRoot)) ret = fs::canonical(ret); diff --git a/src/command_line.cc b/src/command_line.cc index 3604aca31..2cbc311e2 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -77,7 +77,7 @@ bool ShouldDisplayMethodTiming(MethodType type) { void PrintHelp() { std::cout - << R"help(ccls is a low-latency C/C++/Objective-C language server. + << R"help(ccls is a C/C++/Objective-C language server. Mode: --test-unit Run unit tests. @@ -91,7 +91,7 @@ void PrintHelp() { Other command line options: --init Override client provided initialization options - https://github.com/cquery-project/cquery/wiki/Initialization-options + https://github.com/MaskRay/ccls/wiki/Initialization-options --log-file Logging file for diagnostics --log-file-append Like --log-file, but appending --log-all-to-stderr Write all log messages to STDERR. diff --git a/src/project.cc b/src/project.cc index 9370c3acd..74790c756 100644 --- a/src/project.cc +++ b/src/project.cc @@ -80,8 +80,8 @@ std::vector kNormalizePathArgs = {"--sysroot="}; // Arguments whose path arguments should be injected into include dir lookup // for #include completion. -std::vector kQuoteIncludeArgs = {"-iquote"}; -std::vector kAngleIncludeArgs = {"-I", "/I", "-isystem"}; +std::vector kQuoteIncludeArgs = {"-iquote", "-I", "/I"}; +std::vector kAngleIncludeArgs = {"-isystem", "-I", "/I"}; bool ShouldAddToQuoteIncludes(const std::string& arg) { return StartsWithAny(arg, kQuoteIncludeArgs); diff --git a/src/utils.cc b/src/utils.cc index 593cf0a81..b993c8ef6 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -248,7 +249,7 @@ std::string TextReplacer::Apply(const std::string& content) { void WriteToFile(const std::string& filename, const std::string& content) { FILE* f = fopen(filename.c_str(), "wb"); if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) { - LOG_S(ERROR) << "Cannot write to " << filename; + LOG_S(ERROR) << "Failed to write to " << filename << ' ' << strerror(errno); return; } fclose(f); From 6e68e9edbdfa34ebfe56abe94e34d48c52b34dd0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Apr 2018 17:10:54 -0700 Subject: [PATCH 068/378] Simplify --- CMakeLists.txt | 1 + index_tests/constructors/constructor.cc | 4 +- index_tests/constructors/destructor.cc | 2 +- .../constructors/implicit_constructor.cc | 4 +- index_tests/constructors/make_functions.cc | 12 +- .../func_associated_function_params.cc | 4 +- .../class_inherit_templated_parent.cc | 4 +- index_tests/lambdas/lambda.cc | 10 +- index_tests/macros/foo.cc | 2 +- index_tests/namespaces/anonymous_function.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 4 +- index_tests/namespaces/namespace_reference.cc | 2 +- .../outline/static_function_in_type.cc | 2 +- index_tests/preprocessor/include_guard.cc | 2 +- .../implicit_variable_instantiation.cc | 2 +- index_tests/templates/specialization.cc | 10 +- .../template_var_usage_folded_into_one.cc | 2 +- index_tests/usage/func_usage_addr_func.cc | 2 +- index_tests/usage/func_usage_addr_method.cc | 2 +- index_tests/usage/func_usage_call_method.cc | 2 +- .../usage/func_usage_forward_decl_method.cc | 2 +- .../usage/type_usage_as_template_parameter.cc | 2 +- ...ype_usage_as_template_parameter_complex.cc | 2 +- index_tests/usage/type_usage_declare_local.cc | 4 +- index_tests/usage/type_usage_declare_param.cc | 4 +- .../type_usage_declare_param_prototype.cc | 2 +- .../usage/type_usage_declare_qualifiers.cc | 12 +- index_tests/usage/type_usage_various.cc | 2 +- index_tests/usage/usage_inside_of_call.cc | 2 +- index_tests/usage/var_usage_call_function.cc | 2 +- index_tests/usage/var_usage_class_member.cc | 2 +- index_tests/usage/var_usage_local.cc | 2 +- index_tests/usage/var_usage_shadowed_local.cc | 4 +- .../usage/var_usage_shadowed_parameter.cc | 2 +- index_tests/vars/deduce_auto_type.cc | 4 +- index_tests/vars/function_local.cc | 2 +- index_tests/vars/function_param.cc | 4 +- index_tests/vars/function_shadow_local.cc | 4 +- index_tests/vars/function_shadow_param.cc | 2 +- .../vars/type_instance_on_using_type.cc | 2 +- src/clang_complete.cc | 10 +- src/clang_indexer.cc | 2 +- src/clang_utils.cc | 8 +- src/command_line.cc | 30 +- src/filesystem.cc | 43 +++ src/filesystem.hh | 7 + src/include_complete.cc | 6 +- src/lex_utils.cc | 8 +- src/lsp.cc | 37 --- src/lsp.h | 42 ++- src/message_handler.cc | 4 +- src/messages/initialize.cc | 11 +- src/platform.h | 2 +- src/platform_posix.cc | 2 +- src/platform_win.cc | 3 +- src/project.cc | 52 +-- src/query_utils.cc | 14 +- src/serializer.cc | 20 +- src/serializer.h | 9 - src/serializers/json.h | 1 - src/serializers/msgpack.h | 1 - src/test.cc | 312 ++++++++++-------- src/utils.cc | 129 -------- src/utils.h | 34 -- src/working_files.cc | 10 + 65 files changed, 403 insertions(+), 531 deletions(-) create mode 100644 src/filesystem.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 52e26ebc5..97d131607 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,6 +211,7 @@ target_sources(ccls PRIVATE src/diagnostics_engine.cc src/file_consumer.cc src/file_contents.cc + src/filesystem.cc src/fuzzy_match.cc src/iindexer.cc src/import_manager.cc diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index b36665ad1..8e26369d0 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -67,7 +67,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 10983126130596230582, + "usr": 18410644574635149442, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", @@ -80,7 +80,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 17165811951126099095, + "usr": 11468802633764653592, "detailed_name": "Foo *f2", "qual_name_offset": 5, "short_name": "f2", diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 59c464090..d750286fb 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -89,7 +89,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 1893354193220338759, + "usr": 9954632887635271906, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index bd7b719e7..06c475c95 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -66,7 +66,7 @@ void Make() { }], "vars": [{ "id": 0, - "usr": 449111627548814328, + "usr": 17348451315735351657, "detailed_name": "Type foo0", "qual_name_offset": 5, "short_name": "foo0", @@ -79,7 +79,7 @@ void Make() { "storage": 1 }, { "id": 1, - "usr": 17097499197730163115, + "usr": 3757978174345638825, "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index a2c3a4bec..9150cc488 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -143,7 +143,7 @@ OUTPUT: make_functions.cc "skipped_by_preprocessor": [], "types": [{ "id": 0, - "usr": 9281343527065946499, + "usr": 7902098450755788854, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -160,7 +160,7 @@ OUTPUT: make_functions.cc "uses": ["4:1-4:2|-1|1|4"] }, { "id": 1, - "usr": 10771590811355716928, + "usr": 12533159752419999454, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -177,7 +177,7 @@ OUTPUT: make_functions.cc "uses": ["4:15-4:19|-1|1|4"] }, { "id": 2, - "usr": 11897454629873246477, + "usr": 18441628706991062891, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -194,7 +194,7 @@ OUTPUT: make_functions.cc "uses": ["9:1-9:2|-1|1|4"] }, { "id": 3, - "usr": 3337128087216004141, + "usr": 9441341235704820385, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -347,7 +347,7 @@ OUTPUT: make_functions.cc }], "vars": [{ "id": 0, - "usr": 8463700030555379526, + "usr": 15288691366352169805, "detailed_name": "Args &&... args", "qual_name_offset": 11, "short_name": "args", @@ -359,7 +359,7 @@ OUTPUT: make_functions.cc "storage": 1 }, { "id": 1, - "usr": 3908732770590594660, + "usr": 12338908251430965107, "detailed_name": "Args... args", "qual_name_offset": 8, "short_name": "args", diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index ee705c0d2..02287ca86 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -53,7 +53,7 @@ int foo(int a, int b) { return 0; } }], "vars": [{ "id": 0, - "usr": 14555488990109936920, + "usr": 10480417713467708012, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -66,7 +66,7 @@ int foo(int a, int b) { return 0; } "storage": 1 }, { "id": 1, - "usr": 10963664335057337329, + "usr": 18099600680625658464, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 3056a4ffa..f106d3c9f 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -102,7 +102,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "uses": ["13:56-13:64|-1|1|4"] }, { "id": 5, - "usr": 7916588271848318236, + "usr": 780719166805015998, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -138,7 +138,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [{ "id": 0, - "usr": 12990052348105569112, + "usr": 3880651725784125791, "detailed_name": "unsigned int T", "qual_name_offset": 13, "short_name": "T", diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 5ed38fa39..c06408f32 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -33,7 +33,7 @@ void foo() { "uses": [] }, { "id": 1, - "usr": 14635009347499519042, + "usr": 1287417953265234030, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -65,7 +65,7 @@ void foo() { "callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"] }, { "id": 1, - "usr": 17926497908620168464, + "usr": 1328781044864682611, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -80,7 +80,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 12666114896600231317, + "usr": 17270098654620601683, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", @@ -93,7 +93,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 2981279427664991319, + "usr": 16806544259835773270, "detailed_name": "lambda dosomething", "qual_name_offset": 7, "short_name": "dosomething", @@ -106,7 +106,7 @@ void foo() { "storage": 1 }, { "id": 2, - "usr": 12879188959314906706, + "usr": 2034725908368218782, "detailed_name": "int y", "qual_name_offset": 4, "short_name": "y", diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index f03b19de5..4fb7a6e71 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -92,7 +92,7 @@ int x = A; "storage": 0 }, { "id": 2, - "usr": 2056319845419860263, + "usr": 14946041066794678724, "detailed_name": "DISALLOW", "qual_name_offset": 0, "short_name": "DISALLOW", diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 701ab8555..878cb81a2 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -26,7 +26,7 @@ void foo(); "funcs": [{ "id": 0, "usr": 5010253035933134245, - "detailed_name": "void (anon)::foo()", + "detailed_name": "void (anon ns)::foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 12, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 2c8280f5e..15cf5c652 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -150,7 +150,7 @@ void func() { "storage": 1 }, { "id": 1, - "usr": 6030927277961448585, + "usr": 107714981785063096, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -164,7 +164,7 @@ void func() { "storage": 1 }, { "id": 2, - "usr": 7657277353101371136, + "usr": 1200087780658383286, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index cf559e1c7..5636a6f43 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -111,7 +111,7 @@ void Runner() { "storage": 1 }, { "id": 1, - "usr": 3649375698083002347, + "usr": 7976909968919750794, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 9d05094f5..7782eea6b 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -187,7 +187,7 @@ OUTPUT: static_function_in_type.cc }], "vars": [{ "id": 0, - "usr": 13569879755236306838, + "usr": 9285345059965948351, "detailed_name": "ns::Manager *m", "qual_name_offset": 13, "short_name": "m", diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 592fab713..33a82ca34 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -12,7 +12,7 @@ "funcs": [], "vars": [{ "id": 0, - "usr": 11674328179498211370, + "usr": 13076155634261037336, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 42a89405a..c268b2903 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -87,7 +87,7 @@ namespace ns { "uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"] }, { "id": 4, - "usr": 2205716167465743256, + "usr": 14511917000226829276, "detailed_name": "", "qual_name_offset": 0, "short_name": "", diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 840493fa0..0d667a2d6 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -83,7 +83,7 @@ void foo(float Value); "uses": ["7:1-7:9|-1|1|4"] }, { "id": 2, - "usr": 9673599782548740467, + "usr": 10862637711685426953, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -100,7 +100,7 @@ void foo(float Value); "uses": ["5:16-5:17|-1|1|4"] }, { "id": 3, - "usr": 7143192229126273961, + "usr": 756188769017350739, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -166,7 +166,7 @@ void foo(float Value); "uses": ["31:1-31:7|-1|1|4"] }, { "id": 7, - "usr": 8880262253425334092, + "usr": 3421332160420436276, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -251,7 +251,7 @@ void foo(float Value); "uses": [] }, { "id": 12, - "usr": 14111105212951082474, + "usr": 2461355892344618654, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -433,7 +433,7 @@ void foo(float Value); "storage": 0 }, { "id": 7, - "usr": 17826688417349629938, + "usr": 10307767688451422448, "detailed_name": "T Value", "qual_name_offset": 2, "short_name": "Value", diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 02e01c73f..fd4bd404c 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -71,7 +71,7 @@ UnexposedDecl var "uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"] }, { "id": 2, - "usr": 11919899838872947844, + "usr": 8864163146308556810, "detailed_name": "", "qual_name_offset": 0, "short_name": "", diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index e87d6f34f..8851f96e3 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -64,7 +64,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 16088407831770615719, + "usr": 13681544683892648258, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 52d5739cb..3babaf658 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -67,7 +67,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 4636142131003982569, + "usr": 8436636043513449412, "detailed_name": "void (Foo::*)() x", "qual_name_offset": 16, "short_name": "x", diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index d18cc3277..d2d33b007 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -67,7 +67,7 @@ void user() { }], "vars": [{ "id": 0, - "usr": 14045150712868309451, + "usr": 3014406561587537195, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 1d595bdfd..0c5b0bbbb 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -66,7 +66,7 @@ void usage() { }], "vars": [{ "id": 0, - "usr": 16229832321010999607, + "usr": 12410753116854389823, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 973043fb8..e7cdd887d 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -95,7 +95,7 @@ unique_ptr* return_type() { "storage": 3 }, { "id": 2, - "usr": 3364438781074774169, + "usr": 2462000803278878465, "detailed_name": "unique_ptr *local", "qual_name_offset": 15, "short_name": "local", diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index e740286d5..f5614cc8e 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -228,7 +228,7 @@ unique_ptr* Foo::foo() { return nullptr; } "storage": 2 }, { "id": 1, - "usr": 500112618220246, + "usr": 11547294959889394856, "detailed_name": "unique_ptr, S2> *local", "qual_name_offset": 36, "short_name": "local", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index b501a77b0..2822020db 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -63,7 +63,7 @@ void Foo() { }], "vars": [{ "id": 0, - "usr": 16374832544037266261, + "usr": 11033478034711123650, "detailed_name": "ForwardType *a", "qual_name_offset": 13, "short_name": "a", @@ -76,7 +76,7 @@ void Foo() { "storage": 1 }, { "id": 1, - "usr": 2580122838476012357, + "usr": 8949902309768550158, "detailed_name": "ImplementedType b", "qual_name_offset": 16, "short_name": "b", diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 60fccd12f..b12d9ec31 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -60,7 +60,7 @@ void foo(ForwardType* f, ImplementedType a) {} }], "vars": [{ "id": 0, - "usr": 13058491096576226774, + "usr": 2584795197111552890, "detailed_name": "ForwardType *f", "qual_name_offset": 13, "short_name": "f", @@ -73,7 +73,7 @@ void foo(ForwardType* f, ImplementedType a) {} "storage": 1 }, { "id": 1, - "usr": 11055777568039014776, + "usr": 5136230284979460117, "detailed_name": "ImplementedType a", "qual_name_offset": 16, "short_name": "a", diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 05b6c4d44..7b16a92fb 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -51,7 +51,7 @@ void foo(Foo* f, Foo*) {} }], "vars": [{ "id": 0, - "usr": 13823260660189154978, + "usr": 2161866804398917919, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 799906b3f..086219647 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -48,7 +48,7 @@ void foo(Type& a0, const Type& a1) { }], "vars": [{ "id": 0, - "usr": 7997456978847868736, + "usr": 16414210592877294238, "detailed_name": "Type &a0", "qual_name_offset": 6, "short_name": "a0", @@ -61,7 +61,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 1, - "usr": 17228576662112939520, + "usr": 11558141642862804306, "detailed_name": "const Type &a1", "qual_name_offset": 12, "short_name": "a1", @@ -74,7 +74,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 2, - "usr": 15429032129697337561, + "usr": 1536316608590232194, "detailed_name": "Type a2", "qual_name_offset": 5, "short_name": "a2", @@ -87,7 +87,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 3, - "usr": 6081981442495435784, + "usr": 316760354845869406, "detailed_name": "Type *a3", "qual_name_offset": 6, "short_name": "a3", @@ -100,7 +100,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 4, - "usr": 5004072032239834773, + "usr": 12321730890779907974, "detailed_name": "const Type *a4", "qual_name_offset": 12, "short_name": "a4", @@ -113,7 +113,7 @@ void foo(Type& a0, const Type& a1) { "storage": 1 }, { "id": 5, - "usr": 14939253431683105646, + "usr": 4771437488905761633, "detailed_name": "const Type *const a5", "qual_name_offset": 18, "short_name": "a5", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index f948a0f7e..a2ae182ef 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -55,7 +55,7 @@ extern Foo foo; }], "vars": [{ "id": 0, - "usr": 16380484338511689669, + "usr": 14873619387499024780, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 23988cc38..c005b4bfb 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -132,7 +132,7 @@ void foo() { "storage": 0 }, { "id": 2, - "usr": 8039186520399841081, + "usr": 13284113377394221067, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index e2d4f2fad..1c34a7f2d 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -48,7 +48,7 @@ void caller() { }], "vars": [{ "id": 0, - "usr": 9121974011454213596, + "usr": 3510529098767253033, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index d69730a63..003834a72 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -134,7 +134,7 @@ void foo() { "storage": 0 }, { "id": 2, - "usr": 14669930844300034456, + "usr": 16303259148898744165, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 009367ea9..64b460c65 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -42,7 +42,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 14014650769929566957, + "usr": 8534460107894911680, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index e63910aa7..4e6bbe489 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -47,7 +47,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 13311055950748663970, + "usr": 17941402366659878910, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -60,7 +60,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 14036425367303419504, + "usr": 11094102496276744608, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index b33d417ce..2d3194ef5 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -60,7 +60,7 @@ void foo(int a) { "storage": 1 }, { "id": 1, - "usr": 6997229590862003559, + "usr": 8011559936501990179, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 801a22038..cfe0d4fd1 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -46,7 +46,7 @@ void f() { }], "vars": [{ "id": 0, - "usr": 10601729374837386290, + "usr": 9275666070987716270, "detailed_name": "Foo *x", "qual_name_offset": 5, "short_name": "x", @@ -59,7 +59,7 @@ void f() { "storage": 1 }, { "id": 1, - "usr": 18422884837902130475, + "usr": 16202433437488621027, "detailed_name": "Foo *y", "qual_name_offset": 5, "short_name": "y", diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 16e4995d0..eef83fc49 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -44,7 +44,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 13198746475679542317, + "usr": 10782632605670042066, "detailed_name": "Foo *a", "qual_name_offset": 5, "short_name": "a", diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index cfd28001e..df37bff6b 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -42,7 +42,7 @@ void foo(Foo* p0, Foo* p1) {} }], "vars": [{ "id": 0, - "usr": 8730439006497971620, + "usr": 4580260577538694711, "detailed_name": "Foo *p0", "qual_name_offset": 5, "short_name": "p0", @@ -55,7 +55,7 @@ void foo(Foo* p0, Foo* p1) {} "storage": 1 }, { "id": 1, - "usr": 2525014371090380500, + "usr": 12071725611268840435, "detailed_name": "Foo *p1", "qual_name_offset": 5, "short_name": "p1", diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 53fa645e5..a27f81697 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -47,7 +47,7 @@ void foo() { }], "vars": [{ "id": 0, - "usr": 1894874819807168345, + "usr": 3440226937504376525, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -60,7 +60,7 @@ void foo() { "storage": 1 }, { "id": 1, - "usr": 4508045017817092115, + "usr": 14700715011944976607, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index cab3e40d9..b4fdf18a0 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -54,7 +54,7 @@ void foo(int p) { "storage": 1 }, { "id": 1, - "usr": 11404600766177939811, + "usr": 2147918703972955240, "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index f61dd2c1f..654030b40 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -67,7 +67,7 @@ void Foo() { }], "vars": [{ "id": 0, - "usr": 6975456769752895964, + "usr": 7730100248624586522, "detailed_name": "F a", "qual_name_offset": 2, "short_name": "a", diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 465df0422..05a89ed84 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -1,6 +1,7 @@ #include "clang_complete.h" #include "clang_utils.h" +#include "filesystem.hh" #include "platform.h" #include "timer.h" @@ -27,6 +28,11 @@ unsigned Flags() { ; } +std::string StripFileType(const std::string& path) { + fs::path p(path); + return p.parent_path() / p.stem(); +} + unsigned GetCompletionPriority(const CXCompletionString& str, CXCursorKind result_kind, const std::optional& typedText) { @@ -671,12 +677,12 @@ ClangCompleteManager::ClangCompleteManager(Project* project, preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { new std::thread([&]() { - SetCurrentThreadName("completequery"); + SetThreadName("completequery"); CompletionQueryMain(this); }); new std::thread([&]() { - SetCurrentThreadName("completeparse"); + SetThreadName("completeparse"); CompletionParseMain(this); }); } diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 1167416d2..b03ef730b 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -2304,7 +2304,7 @@ std::vector> ParseWithTu( if (ls_diagnostic.severity != lsDiagnosticSeverity::Error) continue; ls_diagnostic.range = - lsRange(lsPosition(line, 10), lsPosition(line, 10)); + lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; param.primary_file->diagnostics_.push_back(ls_diagnostic); break; } diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 2a79b847e..b9da4daf6 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -15,8 +15,8 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) { unsigned int end_line, end_column; clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr); - return lsRange(lsPosition(start_line - 1, start_column - 1) /*start*/, - lsPosition(end_line - 1, end_column) /*end*/); + return lsRange{lsPosition{int(start_line) - 1, int(start_column) - 1}, + lsPosition{int(end_line) - 1, int(end_column)}}; } } // namespace @@ -59,8 +59,8 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, // Build diagnostic. lsDiagnostic ls_diagnostic; - ls_diagnostic.range = lsRange(lsPosition(start_line - 1, start_column - 1), - lsPosition(end_line - 1, end_column - 1)); + ls_diagnostic.range = lsRange{{int(start_line) - 1, int(start_column) - 1}, + {int(end_line) - 1, int(end_column) - 1}}; ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic)); diff --git a/src/command_line.cc b/src/command_line.cc index 2cbc311e2..6eb155962 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -31,9 +31,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -76,8 +76,7 @@ bool ShouldDisplayMethodTiming(MethodType type) { } void PrintHelp() { - std::cout - << R"help(ccls is a C/C++/Objective-C language server. + printf("%s", R"help(ccls is a C/C++/Objective-C language server. Mode: --test-unit Run unit tests. @@ -101,7 +100,7 @@ Other command line options: out. See more on https://github.com/MaskRay/ccls/wiki -)help"; +)help"); } } // namespace @@ -214,7 +213,7 @@ void RunQueryDbThread(const std::string& bin_name, } // Run query db main loop. - SetCurrentThreadName("querydb"); + SetThreadName("querydb"); while (true) { bool did_work = QueryDbMainLoop( &db, querydb_waiter, &project, &file_consumer_shared, @@ -244,11 +243,8 @@ void RunQueryDbThread(const std::string& bin_name, // // |ipc| is connected to a server. void LaunchStdinLoop(std::unordered_map* request_times) { - // If flushing cin requires flushing cout there could be deadlocks in some - // clients. - std::cin.tie(nullptr); - - StartThread("stdin", [request_times]() { + new std::thread([request_times]() { + SetThreadName("stdin"); auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; @@ -288,7 +284,8 @@ void LaunchStdinLoop(std::unordered_map* request_times) { void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { - StartThread("stdout", [=]() { + new std::thread([=]() { + SetThreadName("stdout"); auto* queue = QueueManager::instance(); while (true) { @@ -387,9 +384,8 @@ int main(int argc, char** argv) { rapidjson::Document reader; rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); if (!ok) { - std::cerr << "Failed to parse --init as JSON: " - << rapidjson::GetParseError_En(ok.Code()) << " (" - << ok.Offset() << ")\n"; + fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", + rapidjson::GetParseError_En(ok.Code()), ok.Offset()); return 1; } JsonReader json_reader{&reader}; @@ -397,9 +393,9 @@ int main(int argc, char** argv) { Config config; Reflect(json_reader, config); } catch (std::invalid_argument& e) { - std::cerr << "Fail to parse --init " - << static_cast(json_reader).GetPath() - << ", expected " << e.what() << "\n"; + fprintf(stderr, "Failed to parse --init %s, expected %s\n", + static_cast(json_reader).GetPath().c_str(), + e.what()); return 1; } } diff --git a/src/filesystem.cc b/src/filesystem.cc new file mode 100644 index 000000000..be32b081f --- /dev/null +++ b/src/filesystem.cc @@ -0,0 +1,43 @@ +#include "filesystem.hh" + +#include "utils.h" + +#include +#include + +static void GetFilesInFolderHelper( + std::string folder, + bool recursive, + std::string output_prefix, + const std::function& handler) { + std::queue> q; + q.emplace(fs::path(folder), fs::path(output_prefix)); + while (!q.empty()) { + for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { + auto path = it->path(); + std::string filename = path.filename(); + if (filename[0] != '.' || filename == ".ccls") { + fs::file_status status = it->symlink_status(); + if (fs::is_regular_file(status)) + handler(q.front().second / filename); + else if (fs::is_directory(status) || fs::is_symlink(status)) { + if (recursive) { + std::string child_dir = q.front().second / filename; + if (fs::is_directory(status)) + q.push(make_pair(path, child_dir)); + } + } + } + } + q.pop(); + } +} + +void GetFilesInFolder(std::string folder, + bool recursive, + bool add_folder_to_path, + const std::function& handler) { + EnsureEndsInSlash(folder); + GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "", + handler); +} diff --git a/src/filesystem.hh b/src/filesystem.hh index 0608bd714..dedce15e5 100644 --- a/src/filesystem.hh +++ b/src/filesystem.hh @@ -1,5 +1,12 @@ #pragma once #include +#include +#include namespace fs = std::experimental::filesystem; + +void GetFilesInFolder(std::string folder, + bool recursive, + bool add_folder_to_path, + const std::function& handler); diff --git a/src/include_complete.cc b/src/include_complete.cc index f9d55f92a..f44bedcc6 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -1,11 +1,14 @@ #include "include_complete.h" +#include "filesystem.hh" #include "match.h" #include "platform.h" #include "project.h" #include "standard_includes.h" #include "timer.h" +#include + namespace { struct CompletionCandidate { @@ -112,7 +115,8 @@ void IncludeComplete::Rescan() { g_config->completion.includeBlacklist); is_scanning = true; - StartThread("scan_includes", [this]() { + new std::thread([this]() { + SetThreadName("scan_includes"); Timer timer; InsertStlIncludes(); diff --git a/src/lex_utils.cc b/src/lex_utils.cc index deb6ece98..6045eb9da 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -69,21 +69,21 @@ std::pair CaseFoldingSubsequenceMatch(std::string_view search, TEST_SUITE("Offset") { TEST_CASE("past end") { std::string content = "foo"; - int offset = GetOffsetForPosition(lsPosition(10, 10), content); + int offset = GetOffsetForPosition(lsPosition{10, 10}, content); REQUIRE(offset <= content.size()); } TEST_CASE("in middle of content") { std::string content = "abcdefghijk"; for (int i = 0; i < content.size(); ++i) { - int offset = GetOffsetForPosition(lsPosition(0, i), content); + int offset = GetOffsetForPosition(lsPosition{0, i}, content); REQUIRE(i == offset); } } TEST_CASE("at end of content") { - REQUIRE(GetOffsetForPosition(lsPosition(0, 0), "") == 0); - REQUIRE(GetOffsetForPosition(lsPosition(0, 1), "a") == 1); + REQUIRE(GetOffsetForPosition(lsPosition{0, 0}, "") == 0); + REQUIRE(GetOffsetForPosition(lsPosition{0, 1}, "a") == 1); } } diff --git a/src/lsp.cc b/src/lsp.cc index 251a52d79..1c1c66735 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -269,46 +269,9 @@ std::string lsDocumentUri::GetPath() const { return ret; } -lsPosition::lsPosition() {} -lsPosition::lsPosition(int line, int character) - : line(line), character(character) {} - -bool lsPosition::operator==(const lsPosition& other) const { - return line == other.line && character == other.character; -} - -bool lsPosition::operator<(const lsPosition& other) const { - return line != other.line ? line < other.line : character < other.character; -} - std::string lsPosition::ToString() const { return std::to_string(line) + ":" + std::to_string(character); } -const lsPosition lsPosition::kZeroPosition = lsPosition(); - -lsRange::lsRange() {} -lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {} - -bool lsRange::operator==(const lsRange& o) const { - return start == o.start && end == o.end; -} - -bool lsRange::operator<(const lsRange& o) const { - return !(start == o.start) ? start < o.start : end < o.end; -} - -lsLocation::lsLocation() {} -lsLocation::lsLocation(lsDocumentUri uri, lsRange range) - : uri(uri), range(range) {} - -bool lsLocation::operator==(const lsLocation& o) const { - return uri == o.uri && range == o.range; -} - -bool lsLocation::operator<(const lsLocation& o) const { - return std::make_tuple(uri.raw_uri, range) < - std::make_tuple(o.uri.raw_uri, o.range); -} bool lsTextEdit::operator==(const lsTextEdit& that) { return range == that.range && newText == that.newText; diff --git a/src/lsp.h b/src/lsp.h index 32692db30..e3fc65559 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -121,44 +121,42 @@ void Reflect(TVisitor& visitor, lsDocumentUri& value) { } struct lsPosition { - lsPosition(); - lsPosition(int line, int character); - - bool operator==(const lsPosition& other) const; - bool operator<(const lsPosition& other) const; - - std::string ToString() const; - - // Note: these are 0-based. int line = 0; int character = 0; - static const lsPosition kZeroPosition; + bool operator==(const lsPosition& o) const { + return line == o.line && character == o.character; + } + bool operator<(const lsPosition& o) const { + return line != o.line ? line < o.line : character < o.character; + } + std::string ToString() const; }; MAKE_HASHABLE(lsPosition, t.line, t.character); MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { - lsRange(); - lsRange(lsPosition start, lsPosition end); - - bool operator==(const lsRange& other) const; - bool operator<(const lsRange& other) const; - lsPosition start; lsPosition end; + bool operator==(const lsRange& o) const { + return start == o.start && end == o.end; + } + bool operator<(const lsRange& o) const { + return !(start == o.start) ? start < o.start : end < o.end; + } }; MAKE_HASHABLE(lsRange, t.start, t.end); MAKE_REFLECT_STRUCT(lsRange, start, end); struct lsLocation { - lsLocation(); - lsLocation(lsDocumentUri uri, lsRange range); - - bool operator==(const lsLocation& other) const; - bool operator<(const lsLocation& o) const; - lsDocumentUri uri; lsRange range; + bool operator==(const lsLocation& o) const { + return uri == o.uri && range == o.range; + } + bool operator<(const lsLocation& o) const { + return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri + : range < o.range; + } }; MAKE_HASHABLE(lsLocation, t.uri, t.range); MAKE_REFLECT_STRUCT(lsLocation, uri, range); diff --git a/src/message_handler.cc b/src/message_handler.cc index 78b32eec1..7c0fd96e8 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -332,8 +332,8 @@ void EmitSemanticHighlighting(QueryDatabase* db, // Attribute range [events[i-1].pos, events[i].pos) to events[top-1].symbol // . if (top && !(events[i - 1].pos == events[i].pos)) - events[top - 1].symbol->ranges.emplace_back(events[i - 1].pos, - events[i].pos); + events[top - 1].symbol->ranges.push_back( + lsRange{events[i - 1].pos, events[i].pos}); if (events[i].id >= 0) events[top++] = events[i]; else diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 37440fa9f..d2aa51676 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -517,11 +517,12 @@ struct Handler_Initialize : BaseMessageHandler { std::max(int(std::thread::hardware_concurrency() * 0.8), 1); } LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; - for (int i = 0; i < g_config->index.threads; ++i) { - StartThread("indexer" + std::to_string(i), [=]() { - Indexer_Main(diag_engine, file_consumer_shared, - timestamp_manager, import_manager, - import_pipeline_status, project, working_files, waiter); + for (int i = 0; i < g_config->index.threads; i++) { + new std::thread([=]() { + SetThreadName("indexer" + std::to_string(i)); + Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, + import_manager, import_pipeline_status, project, + working_files, waiter); }); } diff --git a/src/platform.h b/src/platform.h index e29036068..b8a36bf36 100644 --- a/src/platform.h +++ b/src/platform.h @@ -12,7 +12,7 @@ void PlatformInit(); std::string GetExecutablePath(); std::string NormalizePath(const std::string& path); -void SetCurrentThreadName(const std::string& thread_name); +void SetThreadName(const std::string& thread_name); std::optional GetLastModificationTime(const std::string& absolute_path); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ea9da8cae..6af30d70b 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -155,7 +155,7 @@ std::string NormalizePath(const std::string& path) { return resolved ? *resolved : path; } -void SetCurrentThreadName(const std::string& thread_name) { +void SetThreadName(const std::string& thread_name) { loguru::set_thread_name(thread_name.c_str()); #if defined(__APPLE__) pthread_setname_np(thread_name.c_str()); diff --git a/src/platform_win.cc b/src/platform_win.cc index c6c4df3fa..f4c71a959 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -15,7 +15,6 @@ #include #include -#include #include void PlatformInit() { @@ -60,7 +59,7 @@ typedef struct tagTHREADNAME_INFO { DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; #pragma pack(pop) -void SetCurrentThreadName(const std::string& thread_name) { +void SetThreadName(const std::string& thread_name) { loguru::set_thread_name(thread_name.c_str()); THREADNAME_INFO info; diff --git a/src/project.cc b/src/project.cc index 74790c756..4ced67fba 100644 --- a/src/project.cc +++ b/src/project.cc @@ -21,6 +21,7 @@ #include #endif +#include #include #include #include @@ -47,7 +48,7 @@ struct ProjectConfig { std::unordered_set quote_dirs; std::unordered_set angle_dirs; std::vector extra_flags; - std::string project_dir; + fs::path project_dir; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -107,7 +108,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( const CompileCommandsEntry& entry) { Project::Entry result; result.filename = entry.file; - const std::string base_name = GetBaseName(entry.file); + const std::string base_name = fs::path(entry.file).filename(); // Expand %c %cpp %clang std::vector args; @@ -256,7 +257,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( std::vector ReadCompilerArgumentsFromFile( const std::string& path) { std::vector args; - for (std::string line : ReadFileLines(path)) { + std::ifstream fin(path); + for (std::string line; std::getline(fin, line);) { TrimInPlace(line); if (line.empty() || StartsWith(line, "#")) continue; @@ -268,7 +270,7 @@ std::vector ReadCompilerArgumentsFromFile( std::vector LoadFromDirectoryListing(ProjectConfig* config) { std::vector result; config->mode = ProjectMode::DotCcls; - LOG_IF_S(WARNING, !FileExists(config->project_dir + "/.ccls") && + LOG_IF_S(WARNING, !fs::exists(config->project_dir / ".ccls") && config->extra_flags.empty()) << "ccls has no clang arguments. Considering adding either a " "compile_commands.json or .ccls file. See the ccls README for " @@ -282,31 +284,31 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { [&folder_args, &files](const std::string& path) { if (SourceFileLanguage(path) != LanguageId::Unknown) { files.push_back(path); - } else if (GetBaseName(path) == ".ccls") { + } else if (fs::path(path).filename() == ".ccls") { LOG_S(INFO) << "Using .ccls arguments from " << path; - folder_args.emplace(GetDirName(path), - ReadCompilerArgumentsFromFile(path)); + folder_args.emplace( + fs::path(path).parent_path().string(), + ReadCompilerArgumentsFromFile(path)); } }); - const auto& project_dir_args = folder_args[config->project_dir]; + const std::string project_dir = config->project_dir.string(); + const auto& project_dir_args = folder_args[project_dir]; LOG_IF_S(INFO, !project_dir_args.empty()) << "Using .ccls arguments " << StringJoin(project_dir_args); - auto GetCompilerArgumentForFile = [&config, - &folder_args](const std::string& path) { - for (std::string cur = GetDirName(path);; cur = GetDirName(cur)) { + auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) { + while (!(cur = cur.parent_path()).empty()) { auto it = folder_args.find(cur); if (it != folder_args.end()) return it->second; std::string normalized = NormalizePath(cur); // Break if outside of the project root. - if (normalized.size() <= config->project_dir.size() || - normalized.compare(0, config->project_dir.size(), - config->project_dir) != 0) + if (normalized.size() <= project_dir.size() || + normalized.compare(0, project_dir.size(), project_dir) != 0) break; } - return folder_args[config->project_dir]; + return folder_args[project_dir]; }; for (const std::string& file : files) { @@ -327,7 +329,7 @@ std::vector LoadCompilationEntriesFromDirectory( ProjectConfig* project, const std::string& opt_compilation_db_dir) { // If there is a .ccls file always load using directory listing. - if (FileExists(project->project_dir + ".ccls")) + if (fs::exists(project->project_dir / ".ccls")) return LoadFromDirectoryListing(project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. @@ -335,7 +337,7 @@ std::vector LoadCompilationEntriesFromDirectory( if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir + comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir.string() : opt_compilation_db_dir; } else { project->mode = ProjectMode::ExternalCommand; @@ -522,11 +524,14 @@ Project::Entry Project::FindCompilationEntryForFile( // |best_entry| probably has its own path in the arguments. We need to remap // that path to the new filename. - std::string best_entry_base_name = GetBaseName(best_entry->filename); + fs::path best_entry_base_name = fs::path(best_entry->filename).filename(); for (std::string& arg : result.args) { - if (arg == best_entry->filename || - GetBaseName(arg) == best_entry_base_name) { - arg = filename; + try { + if (arg == best_entry->filename || + fs::path(arg).filename() == best_entry_base_name) { + arg = filename; + } + } catch (...) { } } } @@ -669,7 +674,7 @@ TEST_SUITE("Project") { "--foobar", "-Ia_relative1", "--foobar", - "-I", + "-isystem", "a_relative2", "--foobar", "-iquote/q_absolute1", @@ -691,7 +696,8 @@ TEST_SUITE("Project") { "/a_absolute1", "/a_absolute2", "/base/a_relative1", "/base/a_relative2"}; std::unordered_set quote_expected{ - "/q_absolute1", "/q_absolute2", "/base/q_relative1", + "/a_absolute1", "/a_absolute2", "/base/a_relative1", + "/q_absolute1", "/q_absolute2", "/base/q_relative1", "/base/q_relative2"}; REQUIRE(config.angle_dirs == angle_expected); REQUIRE(config.quote_dirs == quote_expected); diff --git a/src/query_utils.cc b/src/query_utils.cc index a016fedc2..bf61ba644 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -158,19 +158,19 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { std::optional GetLsPosition(WorkingFile* working_file, const Position& position) { if (!working_file) - return lsPosition(position.line, position.column); + return lsPosition{position.line, position.column}; int column = position.column; if (std::optional start = working_file->GetBufferPosFromIndexPos(position.line, &column, false)) - return lsPosition(*start, column); + return lsPosition{*start, column}; return std::nullopt; } std::optional GetLsRange(WorkingFile* working_file, const Range& location) { if (!working_file) { - return lsRange(lsPosition(location.start.line, location.start.column), - lsPosition(location.end.line, location.end.column)); + return lsRange{lsPosition{location.start.line, location.start.column}, + lsPosition{location.end.line, location.end.column}}; } int start_column = location.start.column, end_column = location.end.column; @@ -192,8 +192,8 @@ std::optional GetLsRange(WorkingFile* working_file, const Range& locati if (*start == *end && start_column > end_column) end_column = start_column; - return lsRange(lsPosition(*start, start_column), - lsPosition(*end, end_column)); + return lsRange{lsPosition{*start, start_column}, + lsPosition{*end, end_column}}; } lsDocumentUri GetLsDocumentUri(QueryDatabase* db, @@ -227,7 +227,7 @@ std::optional GetLsLocation(QueryDatabase* db, GetLsRange(working_files->GetFileByFilename(path), use.range); if (!range) return std::nullopt; - return lsLocation(uri, *range); + return lsLocation{uri, *range}; } std::optional GetLsLocationEx(QueryDatabase* db, diff --git a/src/serializer.cc b/src/serializer.cc index 391a5999a..978e2550e 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,11 +1,11 @@ #include "serializer.h" +#include "filesystem.hh" #include "serializers/json.h" #include "serializers/msgpack.h" #include "indexer.h" -#include #include #include @@ -153,7 +153,7 @@ void Reflect(Writer& visitor, IndexInclude& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); if (gTestOutputMode) { - std::string basename = GetBaseName(value.resolved_path); + std::string basename = fs::path(value.resolved_path).filename(); if (!StartsWith(value.resolved_path, "&")) basename = "&" + basename; REFLECT_MEMBER2("resolved_path", basename); @@ -279,7 +279,7 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) { assert(value.Resolve(it->second)->uses.size() == 0); } - DefaultReflectMemberStart(visitor); + visitor.StartObject(); return true; } template @@ -441,17 +441,3 @@ std::unique_ptr Deserialize( return file; } - -void SetTestOutputMode() { - gTestOutputMode = true; -} - -TEST_SUITE("Serializer utils") { - TEST_CASE("GetBaseName") { - REQUIRE(GetBaseName("foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("foo/foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("/foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("///foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("bar/") == "."); - } -} diff --git a/src/serializer.h b/src/serializer.h index b2b9b65cf..5807a5957 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -25,7 +25,6 @@ class Reader { virtual bool IsBool() = 0; virtual bool IsNull() = 0; - virtual bool IsArray() = 0; virtual bool IsInt() = 0; virtual bool IsInt64() = 0; virtual bool IsUint64() = 0; @@ -73,7 +72,6 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); -#define REFLECT_MEMBER_END1(value) ReflectMemberEnd(visitor, value); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) @@ -315,11 +313,6 @@ void Reflect(Writer& visitor, std::vector& values) { // ReflectMember -inline void DefaultReflectMemberStart(Writer& visitor) { - visitor.StartObject(); -} -inline void DefaultReflectMemberStart(Reader& visitor) {} - template bool ReflectMemberStart(Reader& visitor, T& value) { return false; @@ -356,5 +349,3 @@ std::unique_ptr Deserialize( const std::string& serialized_index_content, const std::string& file_content, std::optional expected_version); - -void SetTestOutputMode(); diff --git a/src/serializers/json.h b/src/serializers/json.h index 47e3b0355..aa9d5f0f4 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -15,7 +15,6 @@ class JsonReader : public Reader { bool IsBool() override { return m_->IsBool(); } bool IsNull() override { return m_->IsNull(); } - bool IsArray() override { return m_->IsArray(); } bool IsInt() override { return m_->IsInt(); } bool IsInt64() override { return m_->IsInt64(); } bool IsUint64() override { return m_->IsUint64(); } diff --git a/src/serializers/msgpack.h b/src/serializers/msgpack.h index f9b1666b5..83ea59836 100644 --- a/src/serializers/msgpack.h +++ b/src/serializers/msgpack.h @@ -23,7 +23,6 @@ class MessagePackReader : public Reader { bool IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; } bool IsNull() override { return oh_.get().is_nil(); } - bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; } bool IsInt() override { return oh_.get().type == msgpack::type::POSITIVE_INTEGER || oh_.get().type == msgpack::type::NEGATIVE_INTEGER; diff --git a/src/test.cc b/src/test.cc index f94e447e5..a80758159 100644 --- a/src/test.cc +++ b/src/test.cc @@ -1,5 +1,6 @@ #include "test.h" +#include "filesystem.hh" #include "indexer.h" #include "platform.h" #include "serializer.h" @@ -15,7 +16,6 @@ #include #include #include -#include // The 'diff' utility is available and we can use dprintf(3). #if _POSIX_C_SOURCE >= 200809L @@ -23,6 +23,8 @@ #include #endif +extern bool gTestOutputMode; + std::string ToString(const rapidjson::Document& document) { rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); @@ -35,6 +37,33 @@ std::string ToString(const rapidjson::Document& document) { return buffer.GetString(); } +struct TextReplacer { + struct Replacement { + std::string from; + std::string to; + }; + + std::vector replacements; + + std::string Apply(const std::string& content) { + std::string result = content; + + for (const Replacement& replacement : replacements) { + while (true) { + size_t idx = result.find(replacement.from); + if (idx == std::string::npos) + break; + + result.replace(result.begin() + idx, + result.begin() + idx + replacement.from.size(), + replacement.to); + } + } + + return result; + } +}; + void ParseTestExpectation( const std::string& filename, const std::vector& lines_with_endings, @@ -125,8 +154,7 @@ void DiffDocuments(std::string path, rapidjson::Document& actual) { std::string joined_actual_output = ToString(actual); std::string joined_expected_output = ToString(expected); - std::cout << "[FAILED] " << path << " (section " << path_section << ")" - << std::endl; + printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str()); #if _POSIX_C_SOURCE >= 200809L char expected_file[] = "/tmp/ccls.expected.XXXXXX"; @@ -156,13 +184,10 @@ void DiffDocuments(std::string path, std::vector expected_output = SplitString(joined_expected_output, "\n"); - std::cout << "Expected output for " << path << " (section " << path_section - << "):" << std::endl; - std::cout << joined_expected_output << std::endl; - std::cout << "Actual output for " << path << " (section " << path_section - << "):" << std::endl; - std::cout << joined_actual_output << std::endl; - std::cout << std::endl; + printf("Expected output for %s (section %s)\n:%s\n", path.c_str(), + path_section.c_str(), joined_expected_output.c_str()); + printf("Actual output for %s (section %s)\n:%s\n", path.c_str(), + path_section.c_str(), joined_actual_output.c_str()); } void VerifySerializeToFrom(IndexFile* file) { @@ -173,7 +198,7 @@ void VerifySerializeToFrom(IndexFile* file) { std::nullopt /*expected_version*/); std::string actual = result->ToString(); if (expected != actual) { - std::cerr << "Serialization failure" << std::endl; + fprintf(stderr, "Serialization failure\n"); assert(false); } } @@ -186,7 +211,7 @@ std::string FindExpectedOutputForFilename( return entry.second; } - std::cerr << "Couldn't find expected output for " << filename << std::endl; + fprintf(stderr, "Couldn't find expected output for %s\n", filename.c_str()); getchar(); getchar(); return "{}"; @@ -203,16 +228,17 @@ IndexFile* FindDbForPathEnding( } bool RunIndexTests(const std::string& filter_path, bool enable_update) { - SetTestOutputMode(); + gTestOutputMode = true; // Index tests change based on the version of clang used. - static constexpr const char* kRequiredClangVersion = + static const char kRequiredClangVersion[] = "clang version 6.0.0 (tags/RELEASE_600/final)"; if (GetClangVersion() != kRequiredClangVersion && GetClangVersion().find("trunk") == std::string::npos) { - std::cerr << "Index tests must be run using clang version \"" - << kRequiredClangVersion << "\" (ccls is running with \"" - << GetClangVersion() << "\")" << std::endl; + fprintf(stderr, + "Index tests must be run using clang version %s, ccls is running " + "with %s\n", + kRequiredClangVersion, GetClangVersion().c_str()); return false; } @@ -221,141 +247,141 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); ClangIndex index; - for (std::string path : GetFilesInFolder("index_tests", true /*recursive*/, - true /*add_folder_to_path*/)) { - bool is_fail_allowed = false; + GetFilesInFolder( + "index_tests", true /*recursive*/, true /*add_folder_to_path*/, + [&](const std::string& path) { + bool is_fail_allowed = false; - if (EndsWithAny(path, {".m", ".mm"})) { + if (EndsWithAny(path, {".m", ".mm"})) { #ifndef __APPLE__ - std::cout << "Skipping \"" << path << "\" since this platform does not " - << "support running Objective-C tests." << std::endl; - continue; + return; #endif - // objective-c tests are often not updated right away. do not bring down - // CI if they fail. - if (!enable_update) - is_fail_allowed = true; - } - - if (path.find(filter_path) == std::string::npos) - continue; - - if (!filter_path.empty()) - std::cout << "Running " << path << std::endl; - - // Parse expected output from the test, parse it into JSON document. - std::vector lines_with_endings = ReadFileLines(path); - TextReplacer text_replacer; - std::vector flags; - std::unordered_map all_expected_output; - ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, - &all_expected_output); - - // Build flags. - bool had_extra_flags = !flags.empty(); - if (!AnyStartsWith(flags, "-x")) - flags.push_back("-xc++"); - flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); - if (had_extra_flags) { - std::cout << "For " << path << std::endl; - std::cout << " flags: " << StringJoin(flags) << std::endl; - } - flags.push_back(path); - - // Run test. - g_config = std::make_unique(); - FileConsumerSharedState file_consumer_shared; - PerformanceImportFile perf; - auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, - false /*dump_ast*/); - - for (const auto& entry : all_expected_output) { - const std::string& expected_path = entry.first; - std::string expected_output = text_replacer.Apply(entry.second); - - // FIXME: promote to utils, find and remove duplicates (ie, - // ccls_call_tree.cc, maybe something in project.cc). - auto basename = [](const std::string& path) -> std::string { - size_t last_index = path.find_last_of('/'); - if (last_index == std::string::npos) - return path; - return path.substr(last_index + 1); - }; - - auto severity_to_string = [](const lsDiagnosticSeverity& severity) { - switch (severity) { - case lsDiagnosticSeverity::Error: - return "error "; - case lsDiagnosticSeverity::Warning: - return "warning "; - case lsDiagnosticSeverity::Information: - return "information "; - case lsDiagnosticSeverity::Hint: - return "hint "; - } - assert(false && "not reached"); - return ""; - }; - - // Get output from index operation. - IndexFile* db = FindDbForPathEnding(expected_path, dbs); - assert(db); - if (!db->diagnostics_.empty()) { - std::cout << "For " << path << std::endl; - for (const lsDiagnostic& diagnostic : db->diagnostics_) { - std::cout << " "; - if (diagnostic.severity) - std::cout << severity_to_string(*diagnostic.severity); - std::cout << basename(db->path) << ":" - << diagnostic.range.start.ToString() << "-" - << diagnostic.range.end.ToString() << ": " - << diagnostic.message << std::endl; + // objective-c tests are often not updated right away. do not bring + // down + // CI if they fail. + if (!enable_update) + is_fail_allowed = true; } - } - std::string actual_output = "{}"; - if (db) { - VerifySerializeToFrom(db); - actual_output = db->ToString(); - } - actual_output = text_replacer.Apply(actual_output); - - // Compare output via rapidjson::Document to ignore any formatting - // differences. - rapidjson::Document actual; - actual.Parse(actual_output.c_str()); - rapidjson::Document expected; - expected.Parse(expected_output.c_str()); - - if (actual == expected) { - // std::cout << "[PASSED] " << path << std::endl; - } else { - if (!is_fail_allowed) - success = false; - DiffDocuments(path, expected_path, expected, actual); - std::cout << std::endl; - std::cout << std::endl; - if (enable_update) { - std::cout - << "[Enter to continue - type u to update test, a to update all]"; - char c = 'u'; - if (!update_all) { - c = getchar(); - getchar(); - } - if (c == 'a') - update_all = true; + if (path.find(filter_path) == std::string::npos) + return; + + if (!filter_path.empty()) + printf("Running %s\n", path.c_str()); - if (update_all || c == 'u') { - // Note: we use |entry.second| instead of |expected_output| because - // |expected_output| has had text replacements applied. - UpdateTestExpectation(path, entry.second, ToString(actual) + "\n"); + // Parse expected output from the test, parse it into JSON document. + std::vector lines_with_endings; + { + std::ifstream fin(path); + for (std::string line; std::getline(fin, line);) + lines_with_endings.push_back(line); + } + TextReplacer text_replacer; + std::vector flags; + std::unordered_map all_expected_output; + ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, + &all_expected_output); + + // Build flags. + if (!AnyStartsWith(flags, "-x")) + flags.push_back("-xc++"); + flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); + flags.push_back(path); + + // Run test. + g_config = std::make_unique(); + FileConsumerSharedState file_consumer_shared; + PerformanceImportFile perf; + auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, + false /*dump_ast*/); + + for (const auto& entry : all_expected_output) { + const std::string& expected_path = entry.first; + std::string expected_output = text_replacer.Apply(entry.second); + + // FIXME: promote to utils, find and remove duplicates (ie, + // ccls_call_tree.cc, maybe something in project.cc). + auto basename = [](const std::string& path) -> std::string { + size_t last_index = path.find_last_of('/'); + if (last_index == std::string::npos) + return path; + return path.substr(last_index + 1); + }; + + // Get output from index operation. + IndexFile* db = FindDbForPathEnding(expected_path, dbs); + assert(db); + if (!db->diagnostics_.empty()) { + printf("For %s\n", path.c_str()); + for (const lsDiagnostic& diagnostic : db->diagnostics_) { + printf(" "); + if (diagnostic.severity) + switch (*diagnostic.severity) { + case lsDiagnosticSeverity::Error: + printf("error "); + break; + case lsDiagnosticSeverity::Warning: + printf("warning "); + break; + case lsDiagnosticSeverity::Information: + printf("information "); + break; + case lsDiagnosticSeverity::Hint: + printf("hint "); + break; + } + printf("%s:%s-%s:%s\n", basename(db->path).c_str(), + diagnostic.range.start.ToString().c_str(), + diagnostic.range.end.ToString().c_str(), + diagnostic.message.c_str()); + } + } + std::string actual_output = "{}"; + if (db) { + VerifySerializeToFrom(db); + actual_output = db->ToString(); + } + actual_output = text_replacer.Apply(actual_output); + + // Compare output via rapidjson::Document to ignore any formatting + // differences. + rapidjson::Document actual; + actual.Parse(actual_output.c_str()); + rapidjson::Document expected; + expected.Parse(expected_output.c_str()); + + if (actual == expected) { + // std::cout << "[PASSED] " << path << std::endl; + } else { + if (!is_fail_allowed) + success = false; + DiffDocuments(path, expected_path, expected, actual); + puts("\n"); + if (enable_update) { + printf( + "[Enter to continue - type u to update test, a to update " + "all]"); + char c = 'u'; + if (!update_all) { + c = getchar(); + getchar(); + } + + if (c == 'a') + update_all = true; + + if (update_all || c == 'u') { + // Note: we use |entry.second| instead of |expected_output| + // because + // |expected_output| has had text replacements applied. + UpdateTestExpectation(path, entry.second, + ToString(actual) + "\n"); + } + } } } - } - } - } + }); return success; } diff --git a/src/utils.cc b/src/utils.cc index b993c8ef6..eb8fb6a38 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,6 +1,5 @@ #include "utils.h" -#include "filesystem.hh" #include "platform.h" #include @@ -12,12 +11,7 @@ #include #include #include -#include #include -#include -#include -#include -#include #include using namespace std::placeholders; @@ -83,26 +77,6 @@ bool FindAnyPartial(const std::string& value, }); } -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 "/"; - return path.substr(0, last_slash); -} - -std::string GetBaseName(const std::string& path) { - return fs::path(path).filename(); -} - -std::string StripFileType(const std::string& path) { - fs::path p(path); - return p.parent_path() / p.stem(); -} - std::vector SplitString(const std::string& str, const std::string& delimiter) { // http://stackoverflow.com/a/13172514 @@ -132,54 +106,6 @@ std::string LowerPathIfInsensitive(const std::string& path) { #endif } -static void GetFilesInFolderHelper( - std::string folder, - bool recursive, - std::string output_prefix, - const std::function& handler) { - std::queue> q; - q.emplace(fs::path(folder), fs::path(output_prefix)); - while (!q.empty()) { - for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { - auto path = it->path(); - std::string filename = path.filename(); - if (filename[0] != '.' || filename == ".ccls") { - fs::file_status status = it->symlink_status(); - if (fs::is_regular_file(status)) - handler(q.front().second / filename); - else if (fs::is_directory(status) || fs::is_symlink(status)) { - if (recursive) { - std::string child_dir = q.front().second / filename; - if (fs::is_directory(status)) - q.push(make_pair(path, child_dir)); - } - } - } - } - q.pop(); - } -} - -std::vector GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path) { - EnsureEndsInSlash(folder); - std::vector result; - GetFilesInFolderHelper( - folder, recursive, add_folder_to_path ? folder : "", - [&result](const std::string& path) { result.push_back(path); }); - return result; -} - -void GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path, - const std::function& handler) { - EnsureEndsInSlash(folder); - GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "", - handler); -} - void EnsureEndsInSlash(std::string& path) { if (path.empty() || path[path.size() - 1] != '/') path += '/'; @@ -195,10 +121,6 @@ std::string EscapeFileName(std::string path) { return path; } -bool FileExists(const std::string& filename) { - return fs::exists(filename); -} - std::optional ReadContent(const std::string& filename) { LOG_S(INFO) << "Reading " << filename; char buf[4096]; @@ -211,41 +133,6 @@ std::optional ReadContent(const std::string& filename) { return ret; } -std::vector ReadFileLines(std::string filename) { - std::vector result; - std::ifstream fin(filename); - for (std::string line; std::getline(fin, line);) - result.push_back(line); - return result; -} - -std::vector ToLines(const std::string& content) { - std::vector result; - std::istringstream lines(content); - std::string line; - while (getline(lines, line)) - result.push_back(line); - return result; -} - -std::string TextReplacer::Apply(const std::string& content) { - std::string result = content; - - for (const Replacement& replacement : replacements) { - while (true) { - size_t idx = result.find(replacement.from); - if (idx == std::string::npos) - break; - - result.replace(result.begin() + idx, - result.begin() + idx + replacement.from.size(), - replacement.to); - } - } - - return result; -} - void WriteToFile(const std::string& filename, const std::string& content) { FILE* f = fopen(filename.c_str(), "wb"); if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) { @@ -278,19 +165,3 @@ std::string GetDefaultResourceDirectory() { return NormalizePath(result); } - -void StartThread(const std::string& thread_name, std::function entry) { - new std::thread([thread_name, entry]() { - SetCurrentThreadName(thread_name); - entry(); - }); -} - -TEST_SUITE("StripFileType") { - TEST_CASE("all") { - REQUIRE(StripFileType("") == ""); - REQUIRE(StripFileType("bar") == "bar"); - REQUIRE(StripFileType("bar.cc") == "bar"); - REQUIRE(StripFileType("foo/bar.cc") == "foo/bar"); - } -} diff --git a/src/utils.h b/src/utils.h index baba2774b..82755e71d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -23,13 +22,6 @@ bool StartsWithAny(std::string_view s, const std::vector& ps); bool EndsWithAny(std::string_view s, const std::vector& ss); bool FindAnyPartial(const std::string& value, const std::vector& values); -// 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); -// Returns |path| without the filetype, ie, "foo/bar.cc" => "foo/bar". -std::string StripFileType(const std::string& path); std::vector SplitString(const std::string& str, const std::string& delimiter); @@ -62,15 +54,6 @@ bool ContainsValue(const TCollection& collection, const TValue& value) { return collection.find(value) != collection.end(); } -// Finds all files in the given folder. This is recursive. -std::vector GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path); -void GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path, - const std::function& handler); - // Ensures that |path| ends in a slash. void EnsureEndsInSlash(std::string& path); @@ -78,22 +61,7 @@ void EnsureEndsInSlash(std::string& path); // e.g. foo/bar.c => foo_bar.c std::string EscapeFileName(std::string path); -// FIXME: Move ReadContent into ICacheManager? -bool FileExists(const std::string& filename); std::optional ReadContent(const std::string& filename); -std::vector ReadFileLines(std::string filename); -std::vector ToLines(const std::string& content); - -struct TextReplacer { - struct Replacement { - std::string from; - std::string to; - }; - - std::vector replacements; - - std::string Apply(const std::string& content); -}; void WriteToFile(const std::string& filename, const std::string& content); @@ -149,5 +117,3 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { } std::string GetDefaultResourceDirectory(); - -void StartThread(const std::string& thread_name, std::function entry); diff --git a/src/working_files.cc b/src/working_files.cc index 478a6ff59..cdc5e5ef1 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -9,6 +9,7 @@ #include #include #include +#include namespace { @@ -38,6 +39,15 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) { return result; } +std::vector ToLines(const std::string& content) { + std::vector result; + std::istringstream lines(content); + std::string line; + while (getline(lines, line)) + result.push_back(line); + return result; +} + // Computes the edit distance of strings [a,a+la) and [b,b+lb) with Eugene W. // Myers' O(ND) diff algorithm. // Costs: insertion=1, deletion=1, no substitution. From 8d19e0a4f11b44581da15acc6ad4c9ec857ffa2e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Apr 2018 21:24:21 -0700 Subject: [PATCH 069/378] Remove import_manager.cc --- CMakeLists.txt | 1 - src/clang_cursor.cc | 49 ++++++++---------------------------------- src/clang_cursor.h | 24 +++++++++++---------- src/import_manager.cc | 14 ------------ src/import_manager.h | 14 +----------- src/import_pipeline.cc | 12 ++++++----- 6 files changed, 30 insertions(+), 84 deletions(-) delete mode 100644 src/import_manager.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 97d131607..818eb71ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,7 +214,6 @@ target_sources(ccls PRIVATE src/filesystem.cc src/fuzzy_match.cc src/iindexer.cc - src/import_manager.cc src/import_pipeline.cc src/include_complete.cc src/method.cc diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index 35197f729..efb297c45 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -21,26 +21,18 @@ Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { Position((int16_t)end_line - 1, (int16_t)end_column - 1)); } -ClangType::ClangType() : cx_type() {} - -ClangType::ClangType(const CXType& other) : cx_type(other) {} - -bool ClangType::operator==(const ClangType& rhs) const { - return clang_equalTypes(cx_type, rhs.cx_type); -} - ClangCursor ClangType::get_declaration() const { return clang_getTypeDeclaration(cx_type); } std::string ClangType::get_usr() const { - return ClangCursor(clang_getTypeDeclaration(cx_type)).get_usr(); + return ClangCursor{clang_getTypeDeclaration(cx_type)}.get_usr(); } Usr ClangType::get_usr_hash() const { if (is_builtin()) return static_cast(cx_type.kind); - return ClangCursor(clang_getTypeDeclaration(cx_type)).get_usr_hash(); + return ClangCursor{clang_getTypeDeclaration(cx_type)}.get_usr_hash(); } ClangType ClangType::get_canonical() const { @@ -79,7 +71,7 @@ std::string ClangType::get_spell_name() const { } ClangType ClangType::get_return_type() const { - return ClangType(clang_getResultType(cx_type)); + return clang_getResultType(cx_type); } std::vector ClangType::get_arguments() const { @@ -104,31 +96,8 @@ std::vector ClangType::get_template_arguments() const { return types; } -static_assert(sizeof(ClangCursor) == sizeof(CXCursor), - "Cursor must be the same size as CXCursor"); - -ClangCursor::ClangCursor() : cx_cursor(clang_getNullCursor()) {} - -ClangCursor::ClangCursor(const CXCursor& other) : cx_cursor(other) {} - -ClangCursor::operator bool() const { - return !clang_Cursor_isNull(cx_cursor); -} - -bool ClangCursor::operator==(const ClangCursor& rhs) const { - return clang_equalCursors(cx_cursor, rhs.cx_cursor); -} - -bool ClangCursor::operator!=(const ClangCursor& rhs) const { - return !(*this == rhs); -} - -CXCursorKind ClangCursor::get_kind() const { - return cx_cursor.kind; -} - ClangType ClangCursor::get_type() const { - return ClangType(clang_getCursorType(cx_cursor)); + return {clang_getCursorType(cx_cursor)}; } std::string ClangCursor::get_spell_name() const { @@ -175,23 +144,23 @@ ClangCursor ClangCursor::template_specialization_to_template_definition() } ClangCursor ClangCursor::get_referenced() const { - return ClangCursor(clang_getCursorReferenced(cx_cursor)); + return {clang_getCursorReferenced(cx_cursor)}; } ClangCursor ClangCursor::get_canonical() const { - return ClangCursor(clang_getCanonicalCursor(cx_cursor)); + return {clang_getCanonicalCursor(cx_cursor)}; } ClangCursor ClangCursor::get_definition() const { - return ClangCursor(clang_getCursorDefinition(cx_cursor)); + return {clang_getCursorDefinition(cx_cursor)}; } ClangCursor ClangCursor::get_lexical_parent() const { - return ClangCursor(clang_getCursorLexicalParent(cx_cursor)); + return {clang_getCursorLexicalParent(cx_cursor)}; } ClangCursor ClangCursor::get_semantic_parent() const { - return ClangCursor(clang_getCursorSemanticParent(cx_cursor)); + return {clang_getCursorSemanticParent(cx_cursor)}; } std::vector ClangCursor::get_arguments() const { diff --git a/src/clang_cursor.h b/src/clang_cursor.h index 6084408dc..d0a1eed61 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -19,10 +19,8 @@ class ClangCursor; class ClangType { public: - ClangType(); - ClangType(const CXType& other); - - bool operator==(const ClangType& rhs) const; + ClangType() = default; + ClangType(const CXType& cx) : cx_type(cx) {} // Returns true if this is a fundamental type like int. bool is_builtin() const { @@ -50,14 +48,18 @@ class ClangType { class ClangCursor { public: - ClangCursor(); - ClangCursor(const CXCursor& other); - - explicit operator bool() const; - bool operator==(const ClangCursor& rhs) const; - bool operator!=(const ClangCursor& rhs) const; + ClangCursor() = default; + ClangCursor(CXCursor cx) : cx_cursor(cx) {} + bool operator==(const ClangCursor& o) const { + return clang_equalCursors(cx_cursor, o.cx_cursor); + } + bool operator!=(const ClangCursor& o) const { + return !(*this == o); + } - CXCursorKind get_kind() const; + CXCursorKind get_kind() const { + return cx_cursor.kind; + } ClangType get_type() const; std::string get_spell_name() const; Range get_spell(CXFile* cx_file = nullptr) const; diff --git a/src/import_manager.cc b/src/import_manager.cc deleted file mode 100644 index 11b13f296..000000000 --- a/src/import_manager.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "import_manager.h" - -bool ImportManager::TryMarkDependencyImported(const std::string& path) { - std::lock_guard lock(dependency_mutex_); - return dependency_imported_.insert(path).second; -} - -bool ImportManager::StartQueryDbImport(const std::string& path) { - return querydb_processing_.insert(path).second; -} - -void ImportManager::DoneQueryDbImport(const std::string& path) { - querydb_processing_.erase(path); -} diff --git a/src/import_manager.h b/src/import_manager.h index 57dc7ffe5..7740aec11 100644 --- a/src/import_manager.h +++ b/src/import_manager.h @@ -9,21 +9,9 @@ // // NOTE: This is not thread safe and should only be used on the querydb thread. struct ImportManager { - // Try to mark the given dependency as imported. A dependency can only ever be - // imported once. - bool TryMarkDependencyImported(const std::string& path); - - // Try to import the given file into querydb. We should only ever be - // importing a file into querydb once per file. Returns true if the file - // can be imported. - bool StartQueryDbImport(const std::string& path); - - // The file has been fully imported and can be imported again later on. - void DoneQueryDbImport(const std::string& path); - std::unordered_set querydb_processing_; // TODO: use std::shared_mutex so we can have multiple readers. std::mutex dependency_mutex_; std::unordered_set dependency_imported_; -}; \ No newline at end of file +}; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 334b0e72d..89bc4d389 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -167,9 +167,10 @@ ShouldParse FileNeedsParse( // If the file is a dependency but another file as already imported it, // don't bother. - if (!is_interactive && from && - !import_manager->TryMarkDependencyImported(path)) { - return ShouldParse::No; + if (!is_interactive && from) { + std::lock_guard lock(import_manager->dependency_mutex_); + if (!import_manager->dependency_imported_.insert(path).second) + return ShouldParse::No; } std::optional modification_timestamp = @@ -651,7 +652,8 @@ void QueryDb_DoIdMap(QueueManager* queue, // // Note, we must do this *after* we have checked for the previous index, // otherwise we will never actually generate the IdMap. - if (!import_manager->StartQueryDbImport(request->current->path)) { + if (!import_manager->querydb_processing_.insert(request->current->path) + .second) { LOG_S(INFO) << "Dropping index as it is already being imported for " << request->current->path; return; @@ -712,7 +714,7 @@ void QueryDb_OnIndexed(QueueManager* queue, // Mark the files as being done in querydb stage after we apply the index // update. - import_manager->DoneQueryDbImport(updated_file.value.path); + import_manager->querydb_processing_.erase(updated_file.value.path); } } From 75638b5387cf05adf0c5f4fd1c4e96d6a60cba1f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Apr 2018 23:32:35 -0700 Subject: [PATCH 070/378] Simplify Position & Range; prettify Maybe; remove file_contents.{h,cc} --- CMakeLists.txt | 1 - src/clang_cursor.cc | 4 +- src/clang_indexer.cc | 51 +++-- src/file_consumer.cc | 40 +++- src/file_consumer.h | 20 +- src/file_contents.cc | 29 --- src/file_contents.h | 23 -- src/indexer.h | 20 +- src/maybe.h | 8 +- src/messages/text_document_definition.cc | 3 +- src/method.cc | 10 - src/method.h | 10 +- src/position.cc | 133 +++-------- src/position.h | 45 ++-- src/query.cc | 270 ++--------------------- src/query_utils.cc | 8 +- src/serializer.h | 2 +- src/test.cc | 7 +- src/utils.h | 11 - 19 files changed, 175 insertions(+), 520 deletions(-) delete mode 100644 src/file_contents.cc delete mode 100644 src/file_contents.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 818eb71ca..0594e2bab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,7 +210,6 @@ target_sources(ccls PRIVATE src/config.cc src/diagnostics_engine.cc src/file_consumer.cc - src/file_contents.cc src/filesystem.cc src/fuzzy_match.cc src/iindexer.cc diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index efb297c45..369da7449 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -17,8 +17,8 @@ Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { unsigned int end_line, end_column; clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr); - return Range(Position((int16_t)start_line - 1, (int16_t)start_column - 1), - Position((int16_t)end_line - 1, (int16_t)end_column - 1)); + return Range{{int16_t(start_line - 1), (int16_t)(start_column - 1)}, + {int16_t(end_line - 1), int16_t(end_column - 1)}}; } ClangCursor ClangType::get_declaration() const { diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index b03ef730b..e335a7506 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -280,7 +281,7 @@ struct ConstructorCache { struct IndexParam { std::unordered_set seen_cx_files; std::vector seen_files; - FileContentsMap file_contents; + std::unordered_map file_contents; std::unordered_map file_modification_times; // Only use this when strictly needed (ie, primary translation unit is @@ -729,7 +730,10 @@ IndexTypeId IndexFile::ToTypeId(Usr usr) { return it->second; IndexTypeId id(types.size()); - types.push_back(IndexType(id, usr)); + IndexType type; + type.usr = usr; + type.id = id; + types.push_back(type); id_cache.usr_to_type_id[usr] = id; id_cache.type_id_to_usr[id] = usr; return id; @@ -740,7 +744,10 @@ IndexFuncId IndexFile::ToFuncId(Usr usr) { return it->second; IndexFuncId id(funcs.size()); - funcs.push_back(IndexFunc(id, usr)); + IndexFunc func; + func.usr = usr; + func.id = id; + funcs.push_back(std::move(func)); id_cache.usr_to_func_id[usr] = id; id_cache.func_id_to_usr[id] = usr; return id; @@ -751,7 +758,10 @@ IndexVarId IndexFile::ToVarId(Usr usr) { return it->second; IndexVarId id(vars.size()); - vars.push_back(IndexVar(id, usr)); + IndexVar var; + var.usr = usr; + var.id = id; + vars.push_back(std::move(var)); id_cache.usr_to_var_id[usr] = id; id_cache.var_id_to_usr[id] = usr; return id; @@ -783,8 +793,6 @@ std::string IndexFile::ToString() { return Serialize(SerializeFormat::Json, *this); } -IndexType::IndexType(IndexTypeId id, Usr usr) : usr(usr), id(id) {} - template void Uniquify(std::vector>& ids) { std::unordered_set> seen; @@ -796,11 +804,19 @@ void Uniquify(std::vector>& ids) { } void Uniquify(std::vector& uses) { - std::unordered_set seen; + union U { + Range range = {}; + uint64_t u64; + }; + static_assert(sizeof(Range) == 8); + std::unordered_set seen; size_t n = 0; - for (size_t i = 0; i < uses.size(); i++) - if (seen.insert(uses[i].range).second) + for (size_t i = 0; i < uses.size(); i++) { + U u; + u.range = uses[i].range; + if (seen.insert(u.u64).second) uses[n++] = uses[i]; + } uses.resize(n); } @@ -2343,10 +2359,6 @@ void IndexInit() { clang_toggleCrashRecovery(1); } -std::string GetClangVersion() { - return ToString(clang_getClangVersion()); -} - // |SymbolRef| is serialized this way. // |Use| also uses this though it has an extra field |file|, // which is not used by Index* so it does not need to be serialized. @@ -2354,7 +2366,7 @@ void Reflect(Reader& visitor, Reference& value) { if (visitor.Format() == SerializeFormat::Json) { std::string t = visitor.GetString(); char* s = const_cast(t.c_str()); - value.range = Range(s); + value.range = Range::FromString(s); s = strchr(s, '|'); value.id.id = RawId(strtol(s + 1, &s, 10)); value.kind = static_cast(strtol(s + 1, &s, 10)); @@ -2368,12 +2380,13 @@ void Reflect(Reader& visitor, Reference& value) { } 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::type>(value.id.id)); - s += '|' + std::to_string(int(value.kind)); - s += '|' + std::to_string(int(value.role)); + char buf[99]; + snprintf(buf, sizeof buf, "%s|%" PRId32 "|%d|%d", + value.range.ToString().c_str(), + static_cast::type>(value.id.id), + int(value.kind), int(value.role)); + std::string s(buf); Reflect(visitor, s); } else { Reflect(visitor, value.range); diff --git a/src/file_consumer.cc b/src/file_consumer.cc index c237c5b71..9d1d276a6 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -9,8 +9,9 @@ namespace { -std::optional GetFileContents(const std::string& path, - FileContentsMap* file_contents) { +std::optional GetFileContents( + const std::string& path, + std::unordered_map* file_contents) { auto it = file_contents->find(path); if (it == file_contents->end()) { std::optional content = ReadContent(path); @@ -28,6 +29,34 @@ bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) { a.data[2] == b.data[2]; } +FileContents::FileContents() : line_offsets_{0} {} + +FileContents::FileContents(const std::string& path, const std::string& content) + : path(path), content(content) { + line_offsets_.push_back(0); + for (size_t i = 0; i < content.size(); i++) { + if (content[i] == '\n') + line_offsets_.push_back(i + 1); + } +} + +std::optional FileContents::ToOffset(Position p) const { + if (0 <= p.line && size_t(p.line) < line_offsets_.size()) { + int ret = line_offsets_[p.line] + p.column; + if (size_t(ret) < content.size()) + return ret; + } + return std::nullopt; +} + +std::optional FileContents::ContentsInRange(Range range) const { + std::optional start_offset = ToOffset(range.start), + end_offset = ToOffset(range.end); + if (start_offset && end_offset && *start_offset < *end_offset) + return content.substr(*start_offset, *end_offset - *start_offset); + return std::nullopt; +} + bool FileConsumerSharedState::Mark(const std::string& file) { std::lock_guard lock(mutex); return used_files.insert(file).second; @@ -44,9 +73,10 @@ FileConsumer::FileConsumer(FileConsumerSharedState* shared_state, const std::string& parse_file) : shared_(shared_state), parse_file_(parse_file) {} -IndexFile* FileConsumer::TryConsumeFile(CXFile file, - bool* is_first_ownership, - FileContentsMap* file_contents_map) { +IndexFile* FileConsumer::TryConsumeFile( + CXFile file, + bool* is_first_ownership, + std::unordered_map* file_contents_map) { assert(is_first_ownership); CXFileUniqueID file_id; diff --git a/src/file_consumer.h b/src/file_consumer.h index 6ac94eddb..de7162c3c 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -1,6 +1,6 @@ #pragma once -#include "file_contents.h" +#include "position.h" #include "utils.h" #include @@ -9,6 +9,7 @@ #include #include #include +#include struct IndexFile; @@ -16,6 +17,19 @@ struct IndexFile; MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]); bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b); +struct FileContents { + FileContents(); + FileContents(const std::string& path, const std::string& content); + + std::optional ToOffset(Position p) const; + std::optional ContentsInRange(Range range) const; + + std::string path; + std::string content; + // {0, 1 + position of first newline, 1 + position of second newline, ...} + std::vector line_offsets_; +}; + struct FileConsumerSharedState { mutable std::unordered_set used_files; mutable std::mutex mutex; @@ -48,7 +62,7 @@ struct FileConsumer { // variable since it is large and we do not want to copy it. IndexFile* TryConsumeFile(CXFile file, bool* is_first_ownership, - FileContentsMap* file_contents); + std::unordered_map* file_contents); // Returns and passes ownership of all local state. std::vector> TakeLocalState(); @@ -59,4 +73,4 @@ struct FileConsumer { std::unordered_map> local_; FileConsumerSharedState* shared_; std::string parse_file_; -}; \ No newline at end of file +}; diff --git a/src/file_contents.cc b/src/file_contents.cc deleted file mode 100644 index 5a7bc0f44..000000000 --- a/src/file_contents.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include "file_contents.h" - -FileContents::FileContents() : line_offsets_{0} {} - -FileContents::FileContents(const std::string& path, const std::string& content) - : path(path), content(content) { - line_offsets_.push_back(0); - for (size_t i = 0; i < content.size(); i++) { - if (content[i] == '\n') - line_offsets_.push_back(i + 1); - } -} - -std::optional FileContents::ToOffset(Position p) const { - if (0 <= p.line && size_t(p.line) < line_offsets_.size()) { - int ret = line_offsets_[p.line] + p.column; - if (size_t(ret) < content.size()) - return ret; - } - return std::nullopt; -} - -std::optional FileContents::ContentsInRange(Range range) const { - std::optional start_offset = ToOffset(range.start), - end_offset = ToOffset(range.end); - if (start_offset && end_offset && *start_offset < *end_offset) - return content.substr(*start_offset, *end_offset - *start_offset); - return std::nullopt; -} diff --git a/src/file_contents.h b/src/file_contents.h deleted file mode 100644 index 21c484d40..000000000 --- a/src/file_contents.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "position.h" - -#include -#include -#include -#include - -struct FileContents { - FileContents(); - FileContents(const std::string& path, const std::string& content); - - std::optional ToOffset(Position p) const; - std::optional ContentsInRange(Range range) const; - - std::string path; - std::string content; - // {0, 1 + position of first newline, 1 + position of second newline, ...} - std::vector line_offsets_; -}; - -using FileContentsMap = std::unordered_map; diff --git a/src/indexer.h b/src/indexer.h index a57febe1f..05c8e6107 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -4,7 +4,6 @@ #include "clang_translation_unit.h" #include "clang_utils.h" #include "file_consumer.h" -#include "file_contents.h" #include "language.h" #include "lsp.h" #include "maybe.h" @@ -54,7 +53,7 @@ struct Id { // Needed for google::dense_hash_map. explicit operator RawId() const { return id; } - bool HasValueForMaybe_() const { return id != RawId(-1); } + bool Valid() const { return id != RawId(-1); } bool operator==(const Id& o) const { return id == o.id; } bool operator!=(const Id& o) const { return id != o.id; } @@ -101,7 +100,7 @@ struct Reference { SymbolKind kind; Role role; - bool HasValueForMaybe_() const { return range.HasValueForMaybe_(); } + bool Valid() const { return range.Valid(); } operator SymbolIdx() const { return {id, kind}; } std::tuple, SymbolKind, Role> ToTuple() const { return std::make_tuple(range, id, kind, role); @@ -126,8 +125,6 @@ struct Use : Reference { Use(Range range, Id id, SymbolKind kind, Role role, Id file) : Reference{range, id, kind, role}, file(file) {} }; -// Used by |HANDLE_MERGEABLE| so only |range| is needed. -MAKE_HASHABLE(Use, t.range); void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); @@ -241,9 +238,6 @@ struct IndexType { // NOTE: Do not insert directly! Use AddUsage instead. std::vector uses; - IndexType() {} // For serialization. - IndexType(IndexTypeId id, Usr usr); - bool operator<(const IndexType& other) const { return id < other.id; } }; MAKE_HASHABLE(IndexType, t.id); @@ -336,9 +330,6 @@ struct IndexFunc : NameMixin { // def.spell. std::vector uses; - IndexFunc() {} // For serialization. - IndexFunc(IndexFuncId id, Usr usr) : usr(usr), id(id) {} - bool operator<(const IndexFunc& other) const { return id < other.id; } }; MAKE_HASHABLE(IndexFunc, t.id); @@ -408,9 +399,6 @@ struct IndexVar { std::vector declarations; std::vector uses; - IndexVar() {} // For serialization. - IndexVar(IndexVarId id, Usr usr) : usr(usr), id(id) {} - bool operator<(const IndexVar& other) const { return id < other.id; } }; MAKE_HASHABLE(IndexVar, t.id); @@ -519,7 +507,3 @@ std::vector> ParseWithTu( bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); - -void ClangSanityCheck(); - -std::string GetClangVersion(); diff --git a/src/maybe.h b/src/maybe.h index c26c97084..328fc71ec 100644 --- a/src/maybe.h +++ b/src/maybe.h @@ -5,7 +5,7 @@ #include // Like std::optional, but the stored data is responsible for containing the empty -// state. T should define a function `bool T::HasValueForMaybe_()`. +// state. T should define a function `bool T::Valid()`. template class Maybe { T storage; @@ -28,10 +28,10 @@ class Maybe { const T& operator*() const { return storage; } T& operator*() { return storage; } - bool HasValue() const { return storage.HasValueForMaybe_(); } - explicit operator bool() const { return HasValue(); } + bool Valid() const { return storage.Valid(); } + explicit operator bool() const { return Valid(); } operator std::optional() const { - if (HasValue()) + if (Valid()) return storage; return std::nullopt; } diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 35fec5bde..f431e146c 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -105,7 +105,8 @@ struct Handler_TextDocumentDefinition if (uses.empty() && on_def) uses.push_back(*on_def); } - AddRange(&out.result, GetLsLocationExs(db, working_files, uses)); + auto locs = GetLsLocationExs(db, working_files, uses); + out.result.insert(out.result.end(), locs.begin(), locs.end()); if (!out.result.empty()) break; } diff --git a/src/method.cc b/src/method.cc index f1e38590c..99af41a37 100644 --- a/src/method.cc +++ b/src/method.cc @@ -5,13 +5,3 @@ MethodType kMethodType_Exit = "exit"; MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; MethodType kMethodType_CclsPublishInactiveRegions = "$ccls/publishInactiveRegions"; MethodType kMethodType_CclsPublishSemanticHighlighting = "$ccls/publishSemanticHighlighting"; - -InMessage::~InMessage() = default; - -lsRequestId RequestInMessage::GetRequestId() const { - return id; -} - -lsRequestId NotificationInMessage::GetRequestId() const { - return std::monostate(); -} \ No newline at end of file diff --git a/src/method.h b/src/method.h index 7931673e2..a336ed5be 100644 --- a/src/method.h +++ b/src/method.h @@ -15,7 +15,7 @@ extern MethodType kMethodType_CclsPublishSemanticHighlighting; using lsRequestId = std::variant; struct InMessage { - virtual ~InMessage(); + virtual ~InMessage() = default; virtual MethodType GetMethodType() const = 0; virtual lsRequestId GetRequestId() const = 0; @@ -24,10 +24,14 @@ struct InMessage { struct RequestInMessage : public InMessage { // number or string, actually no null lsRequestId id; - lsRequestId GetRequestId() const override; + lsRequestId GetRequestId() const override { + return id; + } }; // NotificationInMessage does not have |id|. struct NotificationInMessage : public InMessage { - lsRequestId GetRequestId() const override; + lsRequestId GetRequestId() const override { + return std::monostate(); + } }; diff --git a/src/position.cc b/src/position.cc index 37c94c6e9..abcab3120 100644 --- a/src/position.cc +++ b/src/position.cc @@ -1,74 +1,29 @@ #include "position.h" -#include - -Position::Position() : line(-1), column(-1) {} +#include "serializer.h" -Position::Position(int16_t line, int16_t column) : line(line), column(column) {} +#include +#include +#include -Position::Position(const char* encoded) { - char* p = const_cast(encoded); - line = int16_t(strtol(p, &p, 10)) - 1; +Position Position::FromString(const std::string& encoded) { + char* p = const_cast(encoded.c_str()); + int16_t line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); p++; - column = int16_t(strtol(p, &p, 10)) - 1; + int16_t column = int16_t(strtol(p, &p, 10)) - 1; + return {line, column}; } std::string Position::ToString() { - // Output looks like this: - // - // 1:2 - // - // 1 => line - // 2 => column - - std::string result; - result += std::to_string(line + 1); - result += ':'; - result += std::to_string(column + 1); - return result; -} - -std::string Position::ToPrettyString(const std::string& filename) { - // Output looks like this: - // - // 1:2:3 - // - // 1 => filename - // 2 => line - // 3 => column - - std::string result; - result += filename; - result += ':'; - result += std::to_string(line + 1); - result += ':'; - result += std::to_string(column + 1); - return result; -} - -bool Position::operator==(const Position& that) const { - return line == that.line && column == that.column; -} - -bool Position::operator!=(const Position& that) const { - return !(*this == that); -} - -bool Position::operator<(const Position& that) const { - if (line != that.line) - return line < that.line; - return column < that.column; + char buf[99]; + snprintf(buf, sizeof buf, "%d:%d", line + 1, column + 1); + return buf; } -Range::Range() {} - -Range::Range(Position position) : Range(position, position) {} - -Range::Range(Position start, Position end) : start(start), end(end) {} - -Range::Range(const char* encoded) { - char* p = const_cast(encoded); +Range Range::FromString(const std::string& encoded) { + Position start, end; + char* p = const_cast(encoded.c_str()); start.line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); p++; @@ -80,18 +35,14 @@ Range::Range(const char* encoded) { assert(*p == ':'); p++; end.column = int16_t(strtol(p, nullptr, 10)) - 1; + return {start, end}; } bool Range::Contains(int line, int column) const { - if (line == start.line && line == end.line) - return column >= start.column && column < end.column; - if (line == start.line) - return column >= start.column; - if (line == end.line) - return column < end.column; - if (line > start.line && line < end.line) - return true; - return false; + if (line > INT16_MAX) + return false; + Position p{int16_t(line), int16_t(std::min(column, INT16_MAX))}; + return !(p < start) && p < end; } Range Range::RemovePrefix(Position position) const { @@ -99,47 +50,16 @@ Range Range::RemovePrefix(Position position) const { } std::string Range::ToString() { - // Output looks like this: - // - // 1:2-3:4 - // - // 1 => start line - // 2 => start column - // 3 => end line - // 4 => end column - - std::string output; - - output += std::to_string(start.line + 1); - output += ':'; - output += std::to_string(start.column + 1); - output += '-'; - output += std::to_string(end.line + 1); - output += ':'; - output += std::to_string(end.column + 1); - - return output; -} - -bool Range::operator==(const Range& that) const { - return start == that.start && end == that.end; -} - -bool Range::operator!=(const Range& that) const { - return !(*this == that); -} - -bool Range::operator<(const Range& that) const { - if (start != that.start) - return start < that.start; - return end < that.end; + char buf[99]; + snprintf(buf, sizeof buf, "%d:%d-%d:%d", start.line + 1, start.column + 1, + end.line + 1, end.column + 1); + return buf; } // Position void Reflect(Reader& visitor, Position& value) { if (visitor.Format() == SerializeFormat::Json) { - std::string s = visitor.GetString(); - value = Position(s.c_str()); + value = Position::FromString(visitor.GetString()); } else { Reflect(visitor, value.line); Reflect(visitor, value.column); @@ -158,8 +78,7 @@ void Reflect(Writer& visitor, Position& value) { // Range void Reflect(Reader& visitor, Range& value) { if (visitor.Format() == SerializeFormat::Json) { - std::string s = visitor.GetString(); - value = Range(s.c_str()); + value = Range::FromString(visitor.GetString()); } else { Reflect(visitor, value.start.line); Reflect(visitor, value.start.column); diff --git a/src/position.h b/src/position.h index 8d238b555..748bb741e 100644 --- a/src/position.h +++ b/src/position.h @@ -1,57 +1,56 @@ #pragma once #include "maybe.h" -#include "serializer.h" #include "utils.h" #include #include struct Position { - int16_t line; - int16_t column; + int16_t line = -1; + int16_t column = -1; - Position(); - Position(int16_t line, int16_t column); - explicit Position(const char* encoded); + static Position FromString(const std::string& encoded); - bool HasValueForMaybe_() const { return line >= 0; } + bool Valid() const { return line >= 0; } std::string ToString(); - std::string ToPrettyString(const std::string& filename); // Compare two Positions and check if they are equal. Ignores the value of // |interesting|. - bool operator==(const Position& that) const; - bool operator!=(const Position& that) const; - bool operator<(const Position& that) const; + bool operator==(const Position& o) const { + return line == o.line && column == o.column; + } + bool operator<(const Position& o) const { + if (line != o.line) + return line < o.line; + return column < o.column; + } }; -static_assert( - sizeof(Position) == 4, - "Investigate, Position should be 32-bits for indexer size reasons"); MAKE_HASHABLE(Position, t.line, t.column); struct Range { Position start; Position end; - Range(); - explicit Range(Position position); - Range(Position start, Position end); - explicit Range(const char* encoded); + static Range FromString(const std::string& encoded); - bool HasValueForMaybe_() const { return start.HasValueForMaybe_(); } + bool Valid() const { return start.Valid(); } bool Contains(int line, int column) const; Range RemovePrefix(Position position) const; std::string ToString(); - bool operator==(const Range& that) const; - bool operator!=(const Range& that) const; - bool operator<(const Range& that) const; + bool operator==(const Range& o) const { + return start == o.start && end == o.end; + } + bool operator<(const Range& o) const { + return !(start == o.start) ? start < o.start : end < o.end; + } }; -MAKE_HASHABLE(Range, t.start, t.end); // Reflection +class Reader; +class Writer; void Reflect(Reader& visitor, Position& value); void Reflect(Writer& visitor, Position& value); void Reflect(Reader& visitor, Range& value); diff --git a/src/query.cc b/src/query.cc index e504619b7..8d28f2a01 100644 --- a/src/query.cc +++ b/src/query.cc @@ -11,14 +11,30 @@ #include #include #include +#include #include #include #include // TODO: Make all copy constructors explicit. +// Used by |HANDLE_MERGEABLE| so only |range| is needed. +MAKE_HASHABLE(Range, t.start, t.end); +MAKE_HASHABLE(Use, t.range); + namespace { +template +void AddRange(std::vector* dest, const std::vector& to_add) { + dest->insert(dest->end(), to_add.begin(), to_add.end()); +} + +template +void AddRange(std::vector* dest, std::vector&& to_add) { + dest->insert(dest->end(), std::make_move_iterator(to_add.begin()), + std::make_move_iterator(to_add.end())); +} + template void RemoveRange(std::vector* dest, const std::vector& to_remove) { std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); @@ -897,7 +913,7 @@ void QueryDatabase::ImportOrUpdate(std::vector&& updates) { void QueryDatabase::UpdateSymbols(Maybe>* symbol_idx, SymbolKind kind, Id idx) { - if (!symbol_idx->HasValue()) { + if (!symbol_idx->Valid()) { *symbol_idx = Id(symbols.size()); symbols.push_back(SymbolIdx{idx, kind}); } @@ -928,255 +944,3 @@ std::string_view QueryDatabase::GetSymbolName(RawId symbol_idx, } return ""; } - -TEST_SUITE("query") { - IndexUpdate GetDelta(IndexFile previous, IndexFile current) { - QueryDatabase db; - IdMap previous_map(&db, previous.id_cache); - IdMap current_map(&db, current.id_cache); - return IndexUpdate::CreateDelta(&previous_map, ¤t_map, &previous, - ¤t); - } - - TEST_CASE("remove defs") { - IndexFile previous("foo.cc", ""); - IndexFile current("foo.cc", ""); - - previous.Resolve(previous.ToTypeId(HashUsr("usr1")))->def.spell = - Use(Range(Position(1, 0)), {}, {}, {}, {}); - previous.Resolve(previous.ToFuncId(HashUsr("usr2")))->def.spell = - Use(Range(Position(2, 0)), {}, {}, {}, {}); - previous.Resolve(previous.ToVarId(HashUsr("usr3")))->def.spell = - Use(Range(Position(3, 0)), {}, {}, {}, {}); - - IndexUpdate update = GetDelta(previous, current); - - REQUIRE(update.types_removed == std::vector{HashUsr("usr1")}); - REQUIRE(update.funcs_removed.size() == 1); - REQUIRE(update.funcs_removed[0].usr == HashUsr("usr2")); - REQUIRE(update.vars_removed.size() == 1); - REQUIRE(update.vars_removed[0].usr == HashUsr("usr3")); - } - - TEST_CASE("do not remove ref-only defs") { - IndexFile previous("foo.cc", ""); - IndexFile current("foo.cc", ""); - - previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) - ->uses.push_back(Use{Range(Position(1, 0)), {}, {}, {}, {}}); - previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) - ->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {})); - previous.Resolve(previous.ToVarId(HashUsr("usr3"))) - ->uses.push_back(Use(Range(Position(3, 0)), {}, {}, {}, {})); - - IndexUpdate update = GetDelta(previous, current); - - REQUIRE(update.types_removed == std::vector{}); - REQUIRE(update.funcs_removed.empty()); - REQUIRE(update.vars_removed.empty()); - } - - TEST_CASE("func callers") { - IndexFile previous("foo.cc", ""); - IndexFile current("foo.cc", ""); - - IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); - IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - - pf->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {})); - cf->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {})); - - IndexUpdate update = GetDelta(previous, current); - - REQUIRE(update.funcs_removed.empty()); - 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_add.size() == 1); - REQUIRE(update.funcs_uses[0].to_add[0].range == Range(Position(2, 0))); - } - - TEST_CASE("type usages") { - IndexFile previous("foo.cc", ""); - IndexFile current("foo.cc", ""); - - IndexType* pt = previous.Resolve(previous.ToTypeId(HashUsr("usr"))); - IndexType* ct = current.Resolve(current.ToTypeId(HashUsr("usr"))); - - pt->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {})); - ct->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {})); - - IndexUpdate update = GetDelta(previous, current); - - REQUIRE(update.types_removed == std::vector{}); - REQUIRE(update.types_def_update.empty()); - REQUIRE(update.types_uses.size() == 1); - REQUIRE(update.types_uses[0].to_remove.size() == 1); - REQUIRE(update.types_uses[0].to_remove[0].range == Range(Position(1, 0))); - REQUIRE(update.types_uses[0].to_add.size() == 1); - REQUIRE(update.types_uses[0].to_add[0].range == Range(Position(2, 0))); - } - - TEST_CASE("apply delta") { - IndexFile previous("foo.cc", ""); - IndexFile current("foo.cc", ""); - - IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); - IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - pf->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {})); - pf->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {})); - cf->uses.push_back(Use(Range(Position(4, 0)), {}, {}, {}, {})); - cf->uses.push_back(Use(Range(Position(5, 0)), {}, {}, {}, {})); - - QueryDatabase db; - IdMap previous_map(&db, previous.id_cache); - IdMap current_map(&db, current.id_cache); - REQUIRE(db.funcs.size() == 1); - - IndexUpdate import_update = - IndexUpdate::CreateDelta(nullptr, &previous_map, nullptr, &previous); - IndexUpdate delta_update = IndexUpdate::CreateDelta( - &previous_map, ¤t_map, &previous, ¤t); - - db.ApplyIndexUpdate(&import_update); - REQUIRE(db.funcs[0].uses.size() == 2); - REQUIRE(db.funcs[0].uses[0].range == Range(Position(1, 0))); - REQUIRE(db.funcs[0].uses[1].range == Range(Position(2, 0))); - - db.ApplyIndexUpdate(&delta_update); - REQUIRE(db.funcs[0].uses.size() == 2); - REQUIRE(db.funcs[0].uses[0].range == Range(Position(4, 0))); - REQUIRE(db.funcs[0].uses[1].range == Range(Position(5, 0))); - } - - TEST_CASE("Remove variable with usage") { - auto load_index_from_json = [](const char* json) { - return Deserialize(SerializeFormat::Json, "foo.cc", json, "", - std::nullopt); - }; - - auto previous = load_index_from_json(R"RAW( -{ - "types": [ - { - "id": 0, - "usr": 17, - "detailed_name": "", - "short_name_offset": 0, - "short_name_size": 0, - "kind": 0, - "hover": "", - "comments": "", - "parents": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [ - 0 - ], - "uses": [] - } - ], - "funcs": [ - { - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "short_name_offset": 5, - "short_name_size": 3, - "kind": 12, - "storage": 1, - "hover": "", - "comments": "", - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-4:2|-1|1|0", - "base": [], - "derived": [], - "locals": [], - "uses": [], - "callees": [] - } - ], - "vars": [ - { - "id": 0, - "usr": 16837348799350457167, - "detailed_name": "int a", - "short_name_offset": 4, - "short_name_size": 1, - "hover": "", - "comments": "", - "declarations": [], - "spell": "2:7-2:8|0|3|2", - "extent": "2:3-2:8|0|3|2", - "type": 0, - "uses": [ - "3:3-3:4|0|3|4" - ], - "kind": 13, - "storage": 1 - } - ] -} - )RAW"); - - auto current = load_index_from_json(R"RAW( -{ - "types": [], - "funcs": [ - { - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "short_name_offset": 5, - "short_name_size": 3, - "kind": 12, - "storage": 1, - "hover": "", - "comments": "", - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "base": [], - "derived": [], - "locals": [], - "uses": [], - "callees": [] - } - ], - "vars": [] -} - )RAW"); - - // Validate previous/current were parsed. - REQUIRE(previous->vars.size() == 1); - REQUIRE(current->vars.size() == 0); - - QueryDatabase db; - - // Apply initial file. - { - IdMap previous_map(&db, previous->id_cache); - IndexUpdate import_update = IndexUpdate::CreateDelta( - nullptr, &previous_map, nullptr, previous.get()); - db.ApplyIndexUpdate(&import_update); - } - - REQUIRE(db.vars.size() == 1); - REQUIRE(db.vars[0].uses.size() == 1); - - // Apply change. - { - IdMap previous_map(&db, previous->id_cache); - IdMap current_map(&db, current->id_cache); - IndexUpdate delta_update = IndexUpdate::CreateDelta( - &previous_map, ¤t_map, previous.get(), current.get()); - db.ApplyIndexUpdate(&delta_update); - } - REQUIRE(db.vars.size() == 1); - REQUIRE(db.vars[0].uses.size() == 0); - } -} diff --git a/src/query_utils.cc b/src/query_utils.cc index bf61ba644..95d33b5a1 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -47,8 +47,8 @@ Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym) { Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym) { // Used to jump to file. if (sym.kind == SymbolKind::File) - return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind, - Role::None, QueryFileId(sym.id)); + return Use(Range{{0, 0}, {0, 0}}, sym.id, sym.kind, Role::None, + QueryFileId(sym.id)); Maybe ret; EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.extent); }); return ret; @@ -126,7 +126,7 @@ std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); - AddRange(&ret, func1.uses); + ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); } }); } @@ -147,7 +147,7 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); - AddRange(&ret, func1.uses); + ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); } }); } diff --git a/src/serializer.h b/src/serializer.h index 5807a5957..4ea92cc7b 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -231,7 +231,7 @@ void ReflectMember(Writer& visitor, const char* name, std::optional& value) { // The same as std::optional template void ReflectMember(Writer& visitor, const char* name, Maybe& value) { - if (value.HasValue() || visitor.Format() != SerializeFormat::Json) { + if (value.Valid() || visitor.Format() != SerializeFormat::Json) { visitor.Key(name); Reflect(visitor, value); } diff --git a/src/test.cc b/src/test.cc index a80758159..7155b0bd5 100644 --- a/src/test.cc +++ b/src/test.cc @@ -229,16 +229,17 @@ IndexFile* FindDbForPathEnding( bool RunIndexTests(const std::string& filter_path, bool enable_update) { gTestOutputMode = true; + std::string version = ToString(clang_getClangVersion()); // Index tests change based on the version of clang used. static const char kRequiredClangVersion[] = "clang version 6.0.0 (tags/RELEASE_600/final)"; - if (GetClangVersion() != kRequiredClangVersion && - GetClangVersion().find("trunk") == std::string::npos) { + if (version != kRequiredClangVersion && + version.find("trunk") == std::string::npos) { fprintf(stderr, "Index tests must be run using clang version %s, ccls is running " "with %s\n", - kRequiredClangVersion, GetClangVersion().c_str()); + kRequiredClangVersion, version.c_str()); return false; } diff --git a/src/utils.h b/src/utils.h index 82755e71d..6b117d051 100644 --- a/src/utils.h +++ b/src/utils.h @@ -65,17 +65,6 @@ std::optional ReadContent(const std::string& filename); void WriteToFile(const std::string& filename, const std::string& content); -template -void AddRange(std::vector* dest, const std::vector& to_add) { - dest->insert(dest->end(), to_add.begin(), to_add.end()); -} - -template -void AddRange(std::vector* dest, std::vector&& to_add) { - dest->insert(dest->end(), std::make_move_iterator(to_add.begin()), - std::make_move_iterator(to_add.end())); -} - // http://stackoverflow.com/a/38140932 // // struct SomeHashKey { From 2a06fb55dde99e7b1b7a59693e28294dd0a37cdf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Apr 2018 10:03:50 -0700 Subject: [PATCH 071/378] Better definition/references on #include lines --- src/lsp.h | 16 ------- src/messages/ccls_call_hierarchy.cc | 2 +- src/messages/ccls_inheritance_hierarchy.cc | 8 ++-- src/messages/ccls_member_hierarchy.cc | 6 +-- src/messages/text_document_definition.cc | 22 ++++------ src/messages/text_document_references.cc | 51 ++++++++++++---------- src/query_utils.cc | 19 ++++---- src/query_utils.h | 2 +- 8 files changed, 56 insertions(+), 70 deletions(-) diff --git a/src/lsp.h b/src/lsp.h index e3fc65559..2341e87e0 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -8,22 +8,6 @@ #include #include -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////// OUTGOING MESSAGES ///////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////// INCOMING MESSAGES ///////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - #define REGISTER_IN_MESSAGE(type) \ static MessageRegistryRegister type##message_handler_instance_; diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 50a83ae66..e9aebe4f0 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -182,7 +182,7 @@ struct Handler_CclsCallHierarchy } void Run(In_CclsCallHierarchy* request) override { - const auto& params = request->params; + auto& params = request->params; Out_CclsCallHierarchy out; out.id = request->id; diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 52ab1ba17..3ead318d3 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -139,7 +139,7 @@ struct Handler_CclsInheritanceHierarchy } void Run(In_CclsInheritanceHierarchy* request) override { - const auto& params = request->params; + auto& params = request->params; Out_CclsInheritanceHierarchy out; out.id = request->id; @@ -158,11 +158,11 @@ struct Handler_CclsInheritanceHierarchy if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* working_file = + WorkingFile* wfile = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, - request->params.position)) { + for (SymbolRef sym : + FindSymbolsAtLocation(wfile, file, params.position)) { if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { out.result = BuildInitial(sym, params.derived, params.qualified, params.levels); diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index a29912932..747f4f85b 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -202,7 +202,7 @@ struct Handler_CclsMemberHierarchy } void Run(In_CclsMemberHierarchy* request) override { - const auto& params = request->params; + auto& params = request->params; Out_CclsMemberHierarchy out; out.id = request->id; @@ -218,10 +218,10 @@ struct Handler_CclsMemberHierarchy if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* working_file = + WorkingFile* wfile = working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { + FindSymbolsAtLocation(wfile, file, params.position)) { switch (sym.kind) { case SymbolKind::Func: out.result = BuildInitial(QueryFuncId(sym.id), params.qualified, diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index f431e146c..8a7590a2f 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -50,27 +50,23 @@ struct Handler_TextDocumentDefinition : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDefinition* request) override { + auto& params = request->params; QueryFileId file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) { + params.textDocument.uri.GetPath(), &file, &file_id)) return; - } - - WorkingFile* working_file = - working_files->GetFileByFilename(file->def->path); Out_TextDocumentDefinition out; out.id = request->id; Maybe on_def; bool has_symbol = false; - int target_line = request->params.position.line; - int target_column = request->params.position.character; + WorkingFile* wfile = + working_files->GetFileByFilename(file->def->path); + lsPosition& ls_pos = params.position; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { // Found symbol. Return definition. has_symbol = true; @@ -84,7 +80,7 @@ struct Handler_TextDocumentDefinition Use spell = *def.spell; // If on a definition, clear |uses| to find declarations below. if (spell.file == file_id && - spell.range.Contains(target_line, target_column)) { + spell.range.Contains(ls_pos.line, ls_pos.character)) { on_def = spell; uses.clear(); return false; @@ -114,7 +110,7 @@ struct Handler_TextDocumentDefinition // No symbols - check for includes. if (out.result.empty()) { for (const IndexInclude& include : file->def->includes) { - if (include.line == target_line) { + if (include.line == ls_pos.line) { lsLocationEx result; result.uri = lsDocumentUri::FromPath(include.resolved_path); out.result.push_back(result); @@ -125,7 +121,7 @@ struct Handler_TextDocumentDefinition // Find the best match of the identifier at point. if (!has_symbol) { lsPosition position = request->params.position; - const std::string& buffer = working_file->buffer_content; + const std::string& buffer = wfile->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); std::string_view short_query = query; { diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index ba90af9a4..53232609f 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -45,26 +45,25 @@ struct Handler_TextDocumentReferences MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentReferences* request) override { + auto& params = request->params; QueryFile* file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { + params.textDocument.uri.GetPath(), &file)) return; - } - WorkingFile* working_file = + WorkingFile* wfile = working_files->GetFileByFilename(file->def->path); Out_TextDocumentReferences out; out.id = request->id; bool container = g_config->xref.container; - for (const SymbolRef& sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { // Found symbol. Return references. EachOccurrenceWithParent( - db, sym, request->params.context.includeDeclaration, + db, sym, params.context.includeDeclaration, [&](Use use, lsSymbolKind parent_kind) { - if (use.role & request->params.context.role) + if (use.role & params.context.role) if (std::optional ls_loc = GetLsLocationEx(db, working_files, use, container)) { if (container) @@ -75,24 +74,32 @@ struct Handler_TextDocumentReferences break; } - if (out.result.empty()) + if (out.result.empty()) { + // |path| is the #include line. If the cursor is not on such line but line + // = 0, + // use the current filename. + std::string path; + if (params.position.line == 0) + path = file->def->path; for (const IndexInclude& include : file->def->includes) - if (include.line == request->params.position.line) { - // |include| is the line the cursor is on. - for (QueryFile& file1 : db->files) - if (file1.def) - for (const IndexInclude& include1 : file1.def->includes) - if (include1.resolved_path == include.resolved_path) { - // Another file |file1| has the same include line. - lsLocationEx result; - result.uri = lsDocumentUri::FromPath(file1.def->path); - result.range.start.line = result.range.end.line = - include1.line; - out.result.push_back(std::move(result)); - break; - } + if (include.line == params.position.line) { + path = include.resolved_path; break; } + if (path.size()) + for (QueryFile& file1 : db->files) + if (file1.def) + for (const IndexInclude& include : file1.def->includes) + if (include.resolved_path == path) { + // Another file |file1| has the same include line. + lsLocationEx result; + result.uri = lsDocumentUri::FromPath(file1.def->path); + result.range.start.line = result.range.end.line = + include.line; + out.result.push_back(std::move(result)); + break; + } + } if ((int)out.result.size() >= g_config->xref.maxNum) out.result.resize(g_config->xref.maxNum); diff --git a/src/query_utils.cc b/src/query_utils.cc index 95d33b5a1..c77b180d3 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -318,21 +318,20 @@ std::optional GetSymbolInfo(QueryDatabase* db, std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, - lsPosition position) { + lsPosition& ls_pos) { std::vector symbols; - symbols.reserve(1); - - int target_line = position.line; - int target_column = position.character; if (working_file) { - std::optional index_line = working_file->GetIndexPosFromBufferPos( - target_line, &target_column, false); - if (index_line) - target_line = *index_line; + if (auto line = working_file->GetIndexPosFromBufferPos( + ls_pos.line, &ls_pos.character, false)) { + ls_pos.line = *line; + } else { + ls_pos.line = -1; + return {}; + } } for (const SymbolRef& sym : file->def->all_symbols) { - if (sym.range.Contains(target_line, target_column)) + if (sym.range.Contains(ls_pos.line, ls_pos.character)) symbols.push_back(sym); } diff --git a/src/query_utils.h b/src/query_utils.h index 0365394a5..94ef7009f 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -50,7 +50,7 @@ std::optional GetSymbolInfo(QueryDatabase* db, std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, - lsPosition position); + lsPosition& ls_pos); template void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { From 97b1592475f692061d42bc52f8db5d0a8fde2af7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Apr 2018 10:32:08 -0700 Subject: [PATCH 072/378] Simplify lsp.h and fix qual_name_offset when SetVarDetail is called on an existing variable --- src/clang_indexer.cc | 14 +++-------- src/indexer.h | 23 ++++++------------- src/lsp.cc | 2 -- src/lsp.h | 8 +++---- src/message_handler.cc | 2 ++ src/messages/ccls_random.cc | 2 ++ src/messages/text_document_code_lens.cc | 9 +++----- src/messages/text_document_document_symbol.cc | 2 +- src/messages/workspace_symbol.cc | 5 ++-- src/query_utils.cc | 8 +++---- src/query_utils.h | 2 +- src/serializer.h | 22 +++++++----------- src/working_files.cc | 6 ++--- 13 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index e335a7506..7440acb97 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -632,6 +632,7 @@ void SetVarDetail(IndexVar* var, else hover += std::to_string(clang_getEnumConstantDeclValue(cursor.cx_cursor)); def.detailed_name = std::move(qualified_name); + def.qual_name_offset = 0; def.hover = hover; } else { #if 0 && CINDEX_HAVE_PRETTY @@ -639,9 +640,9 @@ void SetVarDetail(IndexVar* var, #else int offset = type_name.size(); offset += ConcatTypeAndName(type_name, qualified_name); + def.detailed_name = type_name; def.qual_name_offset = offset; def.short_name_offset += offset; - def.detailed_name = type_name; // Append the textual initializer, bit field, constructor to |hover|. // Omit |hover| for these types: // int (*a)(); int (&a)(); int (&&a)(); int a[1]; auto x = ... @@ -664,12 +665,6 @@ void SetVarDetail(IndexVar* var, } #endif } - // FIXME QualifiedName should return index - auto idx = def.detailed_name.rfind(short_name.begin(), std::string::npos, - short_name.size()); - assert(idx != std::string::npos); - def.short_name_offset = idx; - def.short_name_size = short_name.size(); if (is_first_seen) { std::optional var_type = @@ -1711,9 +1706,6 @@ 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 #if CINDEX_HAVE_PRETTY std::tie(func->def.detailed_name, func->def.qual_name_offset, func->def.short_name_offset, func->def.short_name_size) = @@ -2384,7 +2376,7 @@ void Reflect(Writer& visitor, Reference& value) { char buf[99]; snprintf(buf, sizeof buf, "%s|%" PRId32 "|%d|%d", value.range.ToString().c_str(), - static_cast::type>(value.id.id), + static_cast>(value.id.id), int(value.kind), int(value.role)); std::string s(buf); Reflect(visitor, s); diff --git a/src/indexer.h b/src/indexer.h index 05c8e6107..9d6a828d0 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -15,7 +15,6 @@ #include "utils.h" #include -#include #include #include #include @@ -40,14 +39,13 @@ struct Id { explicit Id(RawId id) : id(id) {} // Id -> Id or Id -> Id is allowed implicitly. template ::value || - std::is_same::value, - bool>::type = false> + typename std::enable_if_t || std::is_same_v, + bool> = false> Id(Id o) : id(o.id) {} - template ::value || - std::is_same::value), - bool>::type = false> + template < + typename U, + typename std::enable_if_t || std::is_same_v), + bool> = false> explicit Id(Id o) : id(o.id) {} // Needed for google::dense_hash_map. @@ -84,15 +82,11 @@ struct SymbolIdx { bool operator==(const SymbolIdx& o) const { return id == o.id && kind == o.kind; } - bool operator!=(const SymbolIdx& o) const { return !(*this == o); } bool operator<(const SymbolIdx& o) const { - if (id != o.id) - return id < o.id; - return kind < o.kind; + return !(id == o.id) ? id < o.id : kind < o.kind; } }; MAKE_REFLECT_STRUCT(SymbolIdx, kind, id); -MAKE_HASHABLE(SymbolIdx, t.kind, t.id); struct Reference { Range range; @@ -240,7 +234,6 @@ struct IndexType { bool operator<(const IndexType& other) const { return id < other.id; } }; -MAKE_HASHABLE(IndexType, t.id); template struct FuncDef : NameMixin> { @@ -332,7 +325,6 @@ struct IndexFunc : NameMixin { bool operator<(const IndexFunc& other) const { return id < other.id; } }; -MAKE_HASHABLE(IndexFunc, t.id); MAKE_REFLECT_STRUCT(IndexFunc::Declaration, spell, param_spellings); template @@ -401,7 +393,6 @@ struct IndexVar { bool operator<(const IndexVar& other) const { return id < other.id; } }; -MAKE_HASHABLE(IndexVar, t.id); struct IdCache { std::string primary_file; diff --git a/src/lsp.cc b/src/lsp.cc index 1c1c66735..e40f2d714 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -200,8 +200,6 @@ lsDocumentUri lsDocumentUri::FromPath(const std::string& path) { return result; } -lsDocumentUri::lsDocumentUri() {} - bool lsDocumentUri::operator==(const lsDocumentUri& other) const { return raw_uri == other.raw_uri; } diff --git a/src/lsp.h b/src/lsp.h index 2341e87e0..31ebd07ba 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -89,7 +89,6 @@ struct lsResponseError { struct lsDocumentUri { static lsDocumentUri FromPath(const std::string& path); - lsDocumentUri(); bool operator==(const lsDocumentUri& other) const; void SetPath(const std::string& path); @@ -97,7 +96,6 @@ struct lsDocumentUri { std::string raw_uri; }; -MAKE_HASHABLE(lsDocumentUri, t.raw_uri); template void Reflect(TVisitor& visitor, lsDocumentUri& value) { @@ -115,7 +113,6 @@ struct lsPosition { } std::string ToString() const; }; -MAKE_HASHABLE(lsPosition, t.line, t.character); MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { @@ -128,7 +125,6 @@ struct lsRange { return !(start == o.start) ? start < o.start : end < o.end; } }; -MAKE_HASHABLE(lsRange, t.start, t.end); MAKE_REFLECT_STRUCT(lsRange, start, end); struct lsLocation { @@ -142,7 +138,6 @@ struct lsLocation { : range < o.range; } }; -MAKE_HASHABLE(lsLocation, t.uri, t.range); MAKE_REFLECT_STRUCT(lsLocation, uri, range); enum class lsSymbolKind : uint8_t { @@ -358,11 +353,13 @@ MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, // Show a message to the user. enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; MAKE_REFLECT_TYPE_PROXY(lsMessageType) + struct Out_ShowLogMessageParams { lsMessageType type = lsMessageType::Error; std::string message; }; MAKE_REFLECT_STRUCT(Out_ShowLogMessageParams, type, message); + struct Out_ShowLogMessage : public lsOutMessage { enum class DisplayType { Show, Log }; DisplayType display_type = DisplayType::Show; @@ -370,6 +367,7 @@ struct Out_ShowLogMessage : public lsOutMessage { std::string method(); Out_ShowLogMessageParams params; }; + template void Reflect(TVisitor& visitor, Out_ShowLogMessage& value) { REFLECT_MEMBER_START(); diff --git a/src/message_handler.cc b/src/message_handler.cc index 7c0fd96e8..b43f87648 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -9,6 +9,8 @@ #include +MAKE_HASHABLE(SymbolIdx, t.kind, t.id); + namespace { struct Out_CclsSetInactiveRegion diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index ce0bb4379..80f1e85a2 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -6,6 +6,8 @@ #include #include +MAKE_HASHABLE(SymbolIdx, t.kind, t.id); + namespace { MethodType kMethodType = "$ccls/random"; diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index cbe065cb5..3251e3f21 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -59,13 +59,10 @@ void AddCodeLens(const char* singular, code_lens.command->arguments.position = code_lens.range.start; // Add unique uses. - std::unordered_set unique_uses; + std::vector unique_uses; for (Use use1 : uses) { - std::optional location = - GetLsLocation(common->db, common->working_files, use1); - if (!location) - continue; - unique_uses.insert(*location); + if (auto ls_loc = GetLsLocation(common->db, common->working_files, use1)) + unique_uses.push_back(*ls_loc); } code_lens.command->arguments.locations.assign(unique_uses.begin(), unique_uses.end()); diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 09f6723bd..b3461029b 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -41,7 +41,7 @@ struct Handler_TextDocumentDocumentSymbol for (SymbolRef sym : file->def->outline) { std::optional info = - GetSymbolInfo(db, working_files, sym, true /*use_short_name*/); + GetSymbolInfo(db, working_files, sym, false); if (!info) continue; if (sym.kind == SymbolKind::Var) { diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index e556ba93a..173a53d90 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -20,13 +20,12 @@ bool InsertSymbolIntoResult(QueryDatabase* db, SymbolIdx symbol, std::vector* result) { std::optional info = - GetSymbolInfo(db, working_files, symbol, false /*use_short_name*/); + GetSymbolInfo(db, working_files, symbol, true); if (!info) return false; - Maybe location = GetDefinitionExtent(db, symbol); Use loc; - if (location) + if (Maybe location = GetDefinitionExtent(db, symbol)) loc = *location; else { auto decls = GetNonDefDeclarations(db, symbol); diff --git a/src/query_utils.cc b/src/query_utils.cc index c77b180d3..4c213568a 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -284,7 +284,7 @@ lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym) { std::optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx sym, - bool use_short_name) { + bool detailed_name) { switch (sym.kind) { case SymbolKind::Invalid: break; @@ -301,10 +301,10 @@ std::optional GetSymbolInfo(QueryDatabase* db, default: { lsSymbolInformation info; EachEntityDef(db, sym, [&](const auto& def) { - if (use_short_name) - info.name = def.Name(true); - else + if (detailed_name) info.name = def.detailed_name; + else + info.name = def.Name(true); info.kind = def.kind; info.containerName = def.detailed_name; return false; diff --git a/src/query_utils.h b/src/query_utils.h index 94ef7009f..5b00a7db9 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -46,7 +46,7 @@ std::vector GetLsLocationExs(QueryDatabase* db, std::optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx sym, - bool use_short_name); + bool detailed_name); std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, diff --git a/src/serializer.h b/src/serializer.h index 4ea92cc7b..d7a6ed9eb 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -76,7 +76,7 @@ struct IndexFile; #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) #define MAKE_REFLECT_TYPE_PROXY(type_name) \ - MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type::type) + MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) #define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ as_type value0; \ @@ -243,19 +243,13 @@ struct ReflectVariant { // If T appears in Ts..., we should set the value of std::variant to // what we get from Reader. template - typename std::enable_if...>::value, - void>::type - ReflectTag(Reader& visitor, std::variant& value) { - T a; - Reflect(visitor, a); - value = std::move(a); + void ReflectTag(Reader& visitor, std::variant& value) { + if constexpr (std::disjunction_v...>) { + T a; + Reflect(visitor, a); + value = std::move(a); + } } - // This SFINAE overload is used to prevent compile error. value = a; is not - // allowed if T does not appear in Ts... - template - typename std::enable_if...>::value, - void>::type - ReflectTag(Reader&, std::variant&) {} void operator()(Reader& visitor, std::variant& value) { // Based on tag dispatch, call different ReflectTag helper. @@ -263,7 +257,7 @@ struct ReflectVariant { ReflectTag(visitor, value); // It is possible that IsInt64() && IsInt(). We don't call ReflectTag // if int is not in Ts... - else if (std::disjunction...>::value && visitor.IsInt()) + else if (std::disjunction_v...> && visitor.IsInt()) ReflectTag(visitor, value); else if (visitor.IsInt64()) ReflectTag(visitor, value); diff --git a/src/working_files.cc b/src/working_files.cc index cdc5e5ef1..1bd00aa15 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -256,8 +256,7 @@ void WorkingFile::ComputeLineMapping() { // For index line i, set index_to_buffer[i] to -1 if line i is duplicated. int i = 0; for (auto& line : index_lines) { - std::string trimmed = Trim(line); - uint64_t h = HashUsr(trimmed); + uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { hash_to_unique[h] = i; @@ -274,8 +273,7 @@ void WorkingFile::ComputeLineMapping() { i = 0; hash_to_unique.clear(); for (auto& line : buffer_lines) { - std::string trimmed = Trim(line); - uint64_t h = HashUsr(trimmed); + uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { hash_to_unique[h] = i; From 236e7c13931e0770e96be50a58b0d6f58c02aa6c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 9 Apr 2018 00:52:04 -0700 Subject: [PATCH 073/378] Simplify indexer and query --- src/clang_indexer.cc | 29 ++------------------ src/config.h | 9 +------ src/iindexer.cc | 9 +------ src/indexer.h | 5 +--- src/messages/ccls_file_info.cc | 10 +++++++ src/query.cc | 45 ++++++++++++++++++++++++++++++- src/query.h | 48 ---------------------------------- src/test.cc | 3 +-- 8 files changed, 60 insertions(+), 98 deletions(-) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 7440acb97..ee96345ce 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -717,7 +717,7 @@ const int IndexFile::kMajorVersion = 15; const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(const std::string& path, const std::string& contents) - : id_cache(path), path(path), file_contents(contents) {} + : id_cache{path}, path(path), file_contents(contents) {} IndexTypeId IndexFile::ToTypeId(Usr usr) { auto it = id_cache.usr_to_type_id.find(usr); @@ -843,9 +843,6 @@ void AddUseSpell(IndexFile* db, std::vector& uses, ClangCursor cursor) { AddUse(db, uses, cursor.get_spell(), cursor.get_lexical_parent().cx_cursor); } -IdCache::IdCache(const std::string& primary_file) - : primary_file(primary_file) {} - void OnIndexDiagnostic(CXClientData client_data, CXDiagnosticSet diagnostics, void* reserved) { @@ -903,24 +900,6 @@ CXIdxClientFile OnIndexIncludedFile(CXClientData client_data, return nullptr; } -ClangCursor::VisitResult DumpVisitor(ClangCursor cursor, - ClangCursor parent, - int* level) { - fprintf(stderr, "%*s%s %s\n", *level * 2, "", - ToString(cursor.get_kind()).c_str(), cursor.get_spell_name().c_str()); - - *level += 1; - cursor.VisitChildren(&DumpVisitor, level); - *level -= 1; - - return ClangCursor::VisitResult::Continue; -} - -void Dump(ClangCursor cursor) { - int level = 0; - cursor.VisitChildren(&DumpVisitor, &level); -} - struct FindChildOfKindParam { CXCursorKind target_kind; std::optional result; @@ -2191,8 +2170,7 @@ std::vector> Parse( const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf, - ClangIndex* index, - bool dump_ast) { + ClangIndex* index) { if (!g_config->index.enabled) return {}; @@ -2218,9 +2196,6 @@ std::vector> Parse( perf->index_parse = timer.ElapsedMicrosecondsAndReset(); - if (dump_ast) - Dump(clang_getTranslationUnitCursor(tu->cx_tu)); - return ParseWithTu(file_consumer_shared, perf, tu.get(), index, file, args, unsaved_files); } diff --git a/src/config.h b/src/config.h index 196e564ff..a0b7c55ef 100644 --- a/src/config.h +++ b/src/config.h @@ -223,11 +223,6 @@ struct Config { // Maximum number of definition/reference/... results. int maxNum = 2000; } xref; - - //// For debugging - - // Dump AST after parsing if some pattern matches the source filename. - std::vector dumpAST; }; MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); @@ -277,8 +272,6 @@ MAKE_REFLECT_STRUCT(Config, highlight, index, workspaceSymbol, - xref, - - dumpAST); + xref); extern std::unique_ptr g_config; diff --git a/src/iindexer.cc b/src/iindexer.cc index 9b28942d4..7578fa223 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -12,14 +12,7 @@ struct ClangIndexer : IIndexer { const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf) override { - bool dump_ast = false; - for (const std::string& pattern : g_config->dumpAST) - if (file.find(pattern) != std::string::npos) { - dump_ast = true; - break; - } - return Parse(file_consumer_shared, file, args, file_contents, perf, - &index, dump_ast); + return Parse(file_consumer_shared, file, args, file_contents, perf, &index); } // Note: constructing this acquires a global lock diff --git a/src/indexer.h b/src/indexer.h index 9d6a828d0..6af15b82a 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -402,8 +402,6 @@ struct IdCache { std::unordered_map type_id_to_usr; std::unordered_map func_id_to_usr; std::unordered_map var_id_to_usr; - - IdCache(const std::string& primary_file); }; struct IndexInclude { @@ -484,8 +482,7 @@ std::vector> Parse( const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf, - ClangIndex* index, - bool dump_ast = false); + ClangIndex* index); std::vector> ParseWithTu( FileConsumerSharedState* file_consumer_shared, PerformanceImportFile* perf, diff --git a/src/messages/ccls_file_info.cc b/src/messages/ccls_file_info.cc index 94475b692..4a8acf592 100644 --- a/src/messages/ccls_file_info.cc +++ b/src/messages/ccls_file_info.cc @@ -2,6 +2,16 @@ #include "query_utils.h" #include "queue_manager.h" +MAKE_REFLECT_STRUCT(QueryFile::Def, + file, + path, + args, + language, + outline, + all_symbols, + inactive_regions, + dependencies); + namespace { MethodType kMethodType = "$ccls/fileInfo"; diff --git a/src/query.cc b/src/query.cc index 8d28f2a01..e6bd14e93 100644 --- a/src/query.cc +++ b/src/query.cc @@ -22,6 +22,49 @@ MAKE_HASHABLE(Range, t.start, t.end); MAKE_HASHABLE(Use, t.range); +template +void Reflect(TVisitor& visitor, MergeableUpdate& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(id); + REFLECT_MEMBER(to_add); + REFLECT_MEMBER(to_remove); + REFLECT_MEMBER_END(); +} + +template +void Reflect(TVisitor& visitor, WithUsr& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(usr); + REFLECT_MEMBER(value); + REFLECT_MEMBER_END(); +} + +template +void Reflect(TVisitor& visitor, WithFileContent& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(value); + REFLECT_MEMBER(file_content); + REFLECT_MEMBER_END(); +} + +// NOTICE: We're not reflecting on files_removed or files_def_update, it is too +// much output when logging +MAKE_REFLECT_STRUCT(IndexUpdate, + types_removed, + types_def_update, + types_derived, + types_instances, + types_uses, + funcs_removed, + funcs_def_update, + funcs_declarations, + funcs_derived, + funcs_uses, + vars_removed, + vars_def_update, + vars_declarations, + vars_uses); + namespace { template @@ -414,7 +457,7 @@ Maybe QueryDatabase::GetQueryVarIdFromUsr(Usr usr) { } IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids) - : local_ids(local_ids) { + : local_ids{local_ids} { // LOG_S(INFO) << "Creating IdMap for " << local_ids.primary_file; primary_file = *GetQueryFileIdFromPath(query_db, local_ids.primary_file, true); diff --git a/src/query.h b/src/query.h index 7a15c239d..e5cdd7198 100644 --- a/src/query.h +++ b/src/query.h @@ -46,14 +46,6 @@ struct MergeableUpdate { std::vector&& to_remove) : id(id), to_add(std::move(to_add)), to_remove(std::move(to_remove)) {} }; -template -void Reflect(TVisitor& visitor, MergeableUpdate& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(to_add); - REFLECT_MEMBER(to_remove); - REFLECT_MEMBER_END(); -} template struct WithUsr { @@ -63,13 +55,6 @@ struct WithUsr { WithUsr(Usr usr, const T& value) : usr(usr), value(value) {} WithUsr(Usr usr, T&& value) : usr(usr), value(std::move(value)) {} }; -template -void Reflect(TVisitor& visitor, WithUsr& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(usr); - REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); -} template struct WithFileContent { @@ -79,13 +64,6 @@ struct WithFileContent { WithFileContent(const T& value, const std::string& file_content) : value(value), file_content(file_content) {} }; -template -void Reflect(TVisitor& visitor, WithFileContent& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(value); - REFLECT_MEMBER(file_content); - REFLECT_MEMBER_END(); -} struct QueryFamily { using FileId = Id; @@ -124,15 +102,6 @@ struct QueryFile { def->path = path; } }; -MAKE_REFLECT_STRUCT(QueryFile::Def, - file, - path, - args, - language, - outline, - all_symbols, - inactive_regions, - dependencies); template struct QueryEntity { @@ -239,23 +208,6 @@ struct IndexUpdate { IndexFile& previous, IndexFile& current); }; -// NOTICE: We're not reflecting on files_removed or files_def_update, it is too -// much output when logging -MAKE_REFLECT_STRUCT(IndexUpdate, - types_removed, - types_def_update, - types_derived, - types_instances, - types_uses, - funcs_removed, - funcs_def_update, - funcs_declarations, - funcs_derived, - funcs_uses, - vars_removed, - vars_def_update, - vars_declarations, - vars_uses); // The query database is heavily optimized for fast queries. It is stored // in-memory. diff --git a/src/test.cc b/src/test.cc index 7155b0bd5..2aea66467 100644 --- a/src/test.cc +++ b/src/test.cc @@ -294,8 +294,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { g_config = std::make_unique(); FileConsumerSharedState file_consumer_shared; PerformanceImportFile perf; - auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, - false /*dump_ast*/); + auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; From fa4b8c78c16a13c8ca2bfb57cec1b2c1c4e8f228 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 9 Apr 2018 20:38:23 -0700 Subject: [PATCH 074/378] Remove eyesore --- .appveyor.yml | 49 ------------- .clang_complete | 6 -- .gitattributes | 7 -- .pep8 | 2 - .travis.yml | 166 --------------------------------------------- .ycm_extra_conf.py | 15 ---- 6 files changed, 245 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .clang_complete delete mode 100644 .gitattributes delete mode 100644 .pep8 delete mode 100644 .travis.yml delete mode 100644 .ycm_extra_conf.py diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 0b89cb118..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,49 +0,0 @@ -version: "{build}" -image: Visual Studio 2017 -platform: x64 - -clone_folder: C:\projects\cquery - -install: - - git submodule update --init - -environment: - CLICOLOR_FORCE: 1 - matrix: - - MSYSTEM: MINGW64 - - MSYSTEM: MSVC - -matrix: - fast_finish: true # set this flag to immediately finish build once one of the jobs fails. - allow_failures: - - platform: x64 - -build_script: - - ps: | - If ($Env:MSYSTEM -Eq "MSVC") { - $dir = "cquery-${env:appveyor_build_version}-win64" - cd C:\projects\cquery - python waf configure --msvc_version="msvc 15.0" - python waf build - mkdir "${dir}\build\release\bin" -ea 0 - mkdir "${dir}\build\release\lib\LLVM-6.0.0-win64\lib\clang\6.0.0\" - copy "build\release\bin\*" "${dir}\build\release\bin" - copy -recurse "build\LLVM-6.0.0-win64\lib\clang\6.0.0\include" "${dir}\build\release\lib\LLVM-6.0.0-win64\lib\clang\6.0.0\" - 7z a -tzip "C:\projects\cquery\${dir}.zip" "${dir}" - } Else { - C:\msys64\usr\bin\bash -lc @' - pacman -S --needed --noconfirm mingw-w64-x86_64-clang python - cd /c/projects/cquery - CXXFLAGS=-Wall /usr/bin/python waf configure build --llvm-config llvm-config 2>&1 - '@ - } - - set PATH=%PATH%;C:\msys64\%MSYSTEM%\bin - - build\release\bin\cquery --ci --log-all-to-stderr --test-unit - - IF "%MSYSTEM%"=="MSVC" build\release\bin\cquery --ci --log-all-to-stderr --test-index - -artifacts: - - path: 'cquery-*.zip' - -cache: - - C:\projects\cquery\build\LLVM-6.0.0-win64.exe - - C:\projects\cquery\build\LLVM-6.0.0-win64\ diff --git a/.clang_complete b/.clang_complete deleted file mode 100644 index d0dac3366..000000000 --- a/.clang_complete +++ /dev/null @@ -1,6 +0,0 @@ --std=c++11 --Ithird_party/rapidjson/include --IC:/Program Files/LLVM/include --std=c++11 --fms-compatibility --fdelayed-template-parsing \ No newline at end of file diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 5fa46b3e6..000000000 --- a/.gitattributes +++ /dev/null @@ -1,7 +0,0 @@ -# By default, use platform specific endings. -*.h text eol=auto -*.cpp text eol=auto -*.cc text eol=auto - -# Tests must always be crlf -index_tests/** text eol=crlf diff --git a/.pep8 b/.pep8 deleted file mode 100644 index 1fe66c12e..000000000 --- a/.pep8 +++ /dev/null @@ -1,2 +0,0 @@ -[pep8] -indent-size=2 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c9ac2e618..000000000 --- a/.travis.yml +++ /dev/null @@ -1,166 +0,0 @@ -dist: trusty -sudo: false -language: c++ - -env: - global: - - COMPILER=g++ - -# Default --recursive (rapidjson/thirdparty/gtest) is unnecessary -git: - submodules: false - depth: 1 - -before_install: - - git submodule update --init - -addons: - apt: - sources: &apt_sources - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.5 - - llvm-toolchain-trusty-5.0 - -compiler: clang -os: linux - -cache: - directories: - - build/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04/ - - build/clang+llvm-6.0.0-x86_64-apple-darwin/ - -matrix: - fast_finish: true - include: - - env: COMPILER=g++-5 - compiler: gcc - addons: &gcc5 - apt: - packages: ["g++-5"] - sources: *apt_sources - - - env: COMPILER=g++-7 - compiler: gcc - addons: &gcc7 - apt: - packages: ["g++-7"] - sources: *apt_sources - - - env: COMPILER=clang++-3.5 - addons: &clang35 - apt: - packages: ["clang-3.5", "g++-7"] - sources: *apt_sources - - - env: COMPILER=clang++-5.0 - addons: &clang50 - apt: - packages: ["clang-5.0", "g++-7"] - sources: *apt_sources - - - env: COMPILER=clang++ - osx_image: xcode9.1 - os: osx - - - env: COMPILER=g++-7 - compiler: gcc - osx_image: xcode9.1 - os: osx - - - allow_failures: - - # macOS takes too long. - - #- env: COMPILER=clang++ - # osx_image: xcode9.1 - # os: osx - - #- env: COMPILER=g++-7 - # compiler: gcc - # osx_image: xcode9.1 - # os: osx - - # gcc builds that should be fixed at some point - - #- env: COMPILER=g++-5 - # compiler: gcc - - #- env: COMPILER=g++-6 - # compiler: gcc - - #- env: COMPILER=g++-7 - # compiler: gcc - - #- env: COMPILER=g++-5 - # compiler: gcc - # osx_image: xcode9.1 - # os: osx - - #- env: COMPILER=g++-6 - # compiler: gcc - # osx_image: xcode9.1 - # os: osx - - #- env: COMPILER=g++-7 - # compiler: gcc - # osx_image: xcode9.1 - # os: osx - -install: - - | - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then - if [[ "${COMPILER}" == "g++-5" ]]; then - brew install gcc@5 - brew link --overwrite gcc@5 - fi - if [[ "${COMPILER}" == "g++-6" ]]; then - brew install gcc@6 - brew link --overwrite gcc@6 - fi - if [[ "${COMPILER}" == "g++-7" ]]; then - brew install gcc@7 - brew link --overwrite gcc@7 - fi - fi - - - | - if [[ "${COMPILER}" == g++* ]]; then - export J="-j1" - fi - - - export CXX="${COMPILER}" - -before_script: - - ${CXX} --version - -script: - - travis_retry ./waf configure - - ./waf build ${J} - - ./build/release/bin/cquery --ci --log-all-to-stderr --test-unit - - ./build/release/bin/cquery --ci --log-all-to-stderr --test-index - -notifications: - email: false - irc: - channels: - - "ircs://chat.freenode.net:6697/#cquery" - template: - - "[ %{repository_slug}#%{commit}] %{result} on %{branch} by %{author} (%{build_url} )" - -before_deploy: - #- zip -r build/cquery-$TRAVIS_TAG-$TRAVIS_OS_NAME.zip build/release/bin/ build/release/lib/clang+llvm-*/lib/libclang.* build/release/lib/clang+llvm-*/lib/clang/5.0.1/include/ - - ci/before_deploy.sh - -deploy: - provider: releases - api_key: - secure: Ahv4Wp1wveWILqp6HB8UmsXwwfZ103fuJV/u6W4oJFRpnbIXRCGFKaDR1Ql0hsHduKFd/76nNQGSVvNNuTXlWaK2n0bTu1EZ4VYmXk7Q7gn4ROP9XFrIZu0c9XKJ/bzehCLj3t6KT0R5MK5gQe+cBmx4S5uGsGG5/nM+GZpE1N4craRCh64UNXMvIx20sW4VQcgj1Ccrc/6Skb3HET7PKbY+IB/LXnaF3nM6V71LxKW2wlakBmzzaNatQ46QOcOCduY4edE8FqBs7yZ0eFktNZusmjiaZT12t0r1hVe0O8e0ER3u9/c3t+hbPUplMR2FAPBZXojgLVhSfFtBaj45T74oCIi0eUaDeS+Oxl6IzgyVho9RurOtaru3hLOVoaD9wR6lGhj6Nz/2Na3lOIorxHfAZ4OgUmluoFLCynO4ylMD03fMBGBshChnmYbrxLw0xLZP2005WUAj8JN64QOmFmLt3gV7TfVldSFHuwoZyESfkXPRM1Xn8RtgFi/89p4jtPtyBFLSaeDggCwfWEMfADCfJ/j8lXtAPdyEINoaKrxkH8qCPoMLNPXE7JhkP8L0Smdq4cFUEXg3wKWM2hXmWmh2Y25BAyh4qu9CrDPd5qqFcXMtyix4ZjmThLFs/oKYbbMUo4FQ5xT5dpt/VZOi4NpcAj0G/M3jWhu85tMdtTc= - #file: build/cquery-$TRAVIS_TAG-$TRAVIS_OS_NAME.zip - file: build/cquery-$TRAVIS_TAG-x86_64-apple-darwin.tar.xz - file: build/cquery-$TRAVIS_TAG-x86_64-unknown-linux-gnu.tar.xz - skip_cleanup: true - on: - repo: cquery-project/cquery - tags: true - diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py deleted file mode 100644 index 385f768c1..000000000 --- a/.ycm_extra_conf.py +++ /dev/null @@ -1,15 +0,0 @@ -def FlagsForFile( filename, **kwargs ): - return { - 'flags': [ - '-xc++', - '-std=c++11', - '-DLOGURU_WITH_STREAMS=1', - '-Isrc/', - '-Ithird_party/', - '-Ithird_party/doctest', - '-Ithird_party/rapidjson/include', - '-Ithird_party/sparsepp', - '-Ithird_party/loguru', - '-Ibuild/clang+llvm-4.0.0-x86_64-linux-gnu-ubuntu-14.04/include' - ] - } From a7c89fbe210de2f07954a2bb56bc27bc852fef76 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 10 Apr 2018 23:32:53 -0700 Subject: [PATCH 075/378] Catch filesystem_error --- src/filesystem.cc | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/filesystem.cc b/src/filesystem.cc index be32b081f..541bdfcbb 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -13,21 +13,25 @@ static void GetFilesInFolderHelper( std::queue> q; q.emplace(fs::path(folder), fs::path(output_prefix)); while (!q.empty()) { - for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { - auto path = it->path(); - std::string filename = path.filename(); - if (filename[0] != '.' || filename == ".ccls") { - fs::file_status status = it->symlink_status(); - if (fs::is_regular_file(status)) - handler(q.front().second / filename); - else if (fs::is_directory(status) || fs::is_symlink(status)) { - if (recursive) { - std::string child_dir = q.front().second / filename; - if (fs::is_directory(status)) - q.push(make_pair(path, child_dir)); + try { + for (auto it = fs::directory_iterator(q.front().first); + it != fs::directory_iterator(); ++it) { + auto path = it->path(); + std::string filename = path.filename(); + if (filename[0] != '.' || filename == ".ccls") { + fs::file_status status = it->symlink_status(); + if (fs::is_regular_file(status)) + handler(q.front().second / filename); + else if (fs::is_directory(status) || fs::is_symlink(status)) { + if (recursive) { + std::string child_dir = q.front().second / filename; + if (fs::is_directory(status)) + q.push(make_pair(path, child_dir)); + } } } } + } catch (fs::filesystem_error&) { } q.pop(); } From d45c057dd4dceecf5fd9ce09ecfe627e0c3b11d8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Apr 2018 09:52:17 -0700 Subject: [PATCH 076/378] Backport recent update of completion --- src/clang_complete.cc | 375 +++++++++++------------ src/clang_complete.h | 54 ++-- src/messages/text_document_completion.cc | 47 ++- src/threaded_queue.h | 9 + src/working_files.cc | 11 +- src/working_files.h | 3 +- 6 files changed, 271 insertions(+), 228 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 05a89ed84..b3c271d65 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -270,7 +270,8 @@ void BuildDetailString(CXCompletionString completion_string, bool& do_insert, lsInsertTextFormat& format, std::vector* parameters, - bool include_snippets) { + bool include_snippets, + int& angle_stack) { int num_chunks = clang_getNumCompletionChunks(completion_string); auto append = [&](const char* text) { detail += text; @@ -285,8 +286,11 @@ void BuildDetailString(CXCompletionString completion_string, case CXCompletionChunk_Optional: { CXCompletionString nested = clang_getCompletionChunkCompletionString(completion_string, i); - BuildDetailString(nested, label, detail, insert, do_insert, format, - parameters, include_snippets); + // Do not add text to insert string if we're in angle brackets. + bool should_insert = do_insert && angle_stack == 0; + BuildDetailString(nested, label, detail, insert, + should_insert, format, parameters, + include_snippets, angle_stack); break; } @@ -348,8 +352,8 @@ void BuildDetailString(CXCompletionString completion_string, case CXCompletionChunk_RightBracket: append("]"); break; case CXCompletionChunk_LeftBrace: append("{"); break; case CXCompletionChunk_RightBrace: append("}"); break; - case CXCompletionChunk_LeftAngle: append("<"); break; - case CXCompletionChunk_RightAngle: append(">"); break; + case CXCompletionChunk_LeftAngle: append("<"); angle_stack++; break; + case CXCompletionChunk_RightAngle: append(">"); angle_stack--; break; case CXCompletionChunk_Comma: append(", "); break; case CXCompletionChunk_Colon: append(":"); break; case CXCompletionChunk_SemiColon: append(";"); break; @@ -366,7 +370,8 @@ void BuildDetailString(CXCompletionString completion_string, void TryEnsureDocumentParsed(ClangCompleteManager* manager, std::shared_ptr session, std::unique_ptr* tu, - ClangIndex* index) { + ClangIndex* index, + bool emit_diag) { // Nothing to do. We already have a translation unit. if (*tu) return; @@ -414,11 +419,10 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, } } -void CompletionParseMain(ClangCompleteManager* completion_manager) { +void CompletionPreloadMain(ClangCompleteManager* completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. - ClangCompleteManager::ParseRequest request = - completion_manager->parse_requests_.Dequeue(); + auto request = completion_manager->preload_requests_.Dequeue(); // If we don't get a session then that means we don't care about the file // anymore - abandon the request. @@ -429,23 +433,23 @@ void CompletionParseMain(ClangCompleteManager* completion_manager) { if (!session) continue; + // Note: we only preload completion. We emit diagnostics for the + // completion preload though. + CompletionSession::Tu* tu = &session->completion; + // If we've parsed it more recently than the request time, don't bother // reparsing. - if (session->tu_last_parsed_at && - *session->tu_last_parsed_at > request.request_time) { + if (tu->last_parsed_at && *tu->last_parsed_at > request.request_time) continue; - } std::unique_ptr parsing; - TryEnsureDocumentParsed(completion_manager, session, &parsing, - &session->index); + TryEnsureDocumentParsed(completion_manager, session, &parsing, &tu->index, + true); // Activate new translation unit. - // tu_last_parsed_at is only read by this thread, so it doesn't need to be - // under the mutex. - session->tu_last_parsed_at = std::chrono::high_resolution_clock::now(); - std::lock_guard lock(session->tu_lock); - session->tu = std::move(parsing); + std::lock_guard lock(tu->lock); + tu->last_parsed_at = std::chrono::high_resolution_clock::now(); + tu->tu = std::move(parsing); } } @@ -468,15 +472,15 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { completion_manager->TryGetSession(path, true /*mark_as_completion*/, true /*create_if_needed*/); - std::lock_guard lock(session->tu_lock); + std::lock_guard lock(session->completion.lock); Timer timer; - TryEnsureDocumentParsed(completion_manager, session, &session->tu, - &session->index); + TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, + &session->completion.index, false); timer.ResetAndPrint("[complete] TryEnsureDocumentParsed"); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. - if (!session->tu) + if (!session->completion.tu) continue; timer.Reset(); @@ -485,184 +489,160 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { std::vector unsaved = snapshot.AsUnsavedFiles(); timer.ResetAndPrint("[complete] Creating WorkingFile snapshot"); - // Emit code completion data. - if (request->position) { - // Language server is 0-based, clang is 1-based. - unsigned line = request->position->line + 1; - unsigned column = request->position->character + 1; - - timer.Reset(); - unsigned const kCompleteOptions = - CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeBriefComments; - CXCodeCompleteResults* cx_results = clang_codeCompleteAt( - session->tu->cx_tu, session->file.filename.c_str(), line, column, - unsaved.data(), (unsigned)unsaved.size(), kCompleteOptions); - timer.ResetAndPrint("[complete] clangCodeCompleteAt"); - if (!cx_results) { - if (request->on_complete) - request->on_complete({}, false /*is_cached_result*/); + unsigned const kCompleteOptions = + CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeBriefComments; + CXCodeCompleteResults* cx_results = clang_codeCompleteAt( + session->completion.tu->cx_tu, session->file.filename.c_str(), + request->position.line + 1, request->position.character + 1, + unsaved.data(), (unsigned)unsaved.size(), kCompleteOptions); + timer.ResetAndPrint("[complete] clangCodeCompleteAt"); + if (!cx_results) { + request->on_complete({}, false /*is_cached_result*/); + continue; + } + + std::vector ls_result; + // this is a guess but can be larger in case of std::optional + // parameters, as they may be expanded into multiple items + ls_result.reserve(cx_results->NumResults); + + timer.Reset(); + for (unsigned i = 0; i < cx_results->NumResults; ++i) { + CXCompletionResult& result = cx_results->Results[i]; + + // TODO: Try to figure out how we can hide base method calls without + // also hiding method implementation assistance, ie, + // + // void Foo::* { + // } + // + + if (clang_getCompletionAvailability(result.CompletionString) == + CXAvailability_NotAvailable) continue; - } - { - if (request->on_complete) { - std::vector ls_result; - // this is a guess but can be larger in case of std::optional parameters, - // as they may be expanded into multiple items - ls_result.reserve(cx_results->NumResults); - - timer.Reset(); - for (unsigned i = 0; i < cx_results->NumResults; ++i) { - CXCompletionResult& result = cx_results->Results[i]; - - // TODO: Try to figure out how we can hide base method calls without - // also hiding method implementation assistance, ie, - // - // void Foo::* { - // } - // - - if (clang_getCompletionAvailability(result.CompletionString) == - CXAvailability_NotAvailable) - continue; - - // TODO: fill in more data - lsCompletionItem ls_completion_item; - - ls_completion_item.kind = GetCompletionKind(result.CursorKind); - ls_completion_item.documentation = ToString( - clang_getCompletionBriefComment(result.CompletionString)); - - // label/detail/filterText/insertText/priority - if (g_config->completion.detailedLabel) { - ls_completion_item.detail = ToString( - clang_getCompletionParent(result.CompletionString, nullptr)); - - auto first_idx = ls_result.size(); - ls_result.push_back(ls_completion_item); - - // label/filterText/insertText - BuildCompletionItemTexts( - ls_result, result.CompletionString, - g_config->client.snippetSupport); - - for (auto i = first_idx; i < ls_result.size(); ++i) { - if (g_config->client.snippetSupport && - ls_result[i].insertTextFormat == - lsInsertTextFormat::Snippet) { - ls_result[i].insertText += "$0"; - } - - ls_result[i].priority_ = GetCompletionPriority( - result.CompletionString, result.CursorKind, - ls_result[i].filterText); - } - } else { - bool do_insert = true; - BuildDetailString( - result.CompletionString, ls_completion_item.label, - ls_completion_item.detail, ls_completion_item.insertText, - do_insert, ls_completion_item.insertTextFormat, - &ls_completion_item.parameters_, - g_config->client.snippetSupport); - if (g_config->client.snippetSupport && - ls_completion_item.insertTextFormat == - lsInsertTextFormat::Snippet) { - ls_completion_item.insertText += "$0"; - } - ls_completion_item.priority_ = GetCompletionPriority( - result.CompletionString, result.CursorKind, - ls_completion_item.label); - ls_result.push_back(ls_completion_item); - } - } + // TODO: fill in more data + lsCompletionItem ls_completion_item; - timer.ResetAndPrint("[complete] Building " + - std::to_string(ls_result.size()) + - " completion results"); + ls_completion_item.kind = GetCompletionKind(result.CursorKind); + ls_completion_item.documentation = + ToString(clang_getCompletionBriefComment(result.CompletionString)); - request->on_complete(ls_result, false /*is_cached_result*/); - } - } + // label/detail/filterText/insertText/priority + if (g_config->completion.detailedLabel) { + ls_completion_item.detail = ToString( + clang_getCompletionParent(result.CompletionString, nullptr)); - // Make sure |ls_results| is destroyed before clearing |cx_results|. - clang_disposeCodeCompleteResults(cx_results); - } + auto first_idx = ls_result.size(); + ls_result.push_back(ls_completion_item); - // Emit diagnostics. - if (request->emit_diagnostics) { - // TODO: before emitting diagnostics check if we have another completion - // request and think about servicing that first, because it may be much - // faster than reparsing the document. - // TODO: have a separate thread for diagnostics? - - timer.Reset(); - session->tu = - ClangTranslationUnit::Reparse(std::move(session->tu), unsaved); - timer.ResetAndPrint("[complete] clang_reparseTranslationUnit"); - if (!session->tu) { - LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " - << path; - continue; - } + // label/filterText/insertText + BuildCompletionItemTexts(ls_result, result.CompletionString, + g_config->client.snippetSupport); - size_t num_diagnostics = clang_getNumDiagnostics(session->tu->cx_tu); - std::vector ls_diagnostics; - ls_diagnostics.reserve(num_diagnostics); - for (unsigned i = 0; i < num_diagnostics; ++i) { - CXDiagnostic cx_diag = clang_getDiagnostic(session->tu->cx_tu, i); - std::optional diagnostic = - BuildAndDisposeDiagnostic(cx_diag, path); - // Filter messages like "too many errors emitted, stopping now - // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after - // conversion to lsDiagnostic - if (diagnostic && diagnostic->range.start.line >= 0) - ls_diagnostics.push_back(*diagnostic); + for (auto i = first_idx; i < ls_result.size(); ++i) { + if (g_config->client.snippetSupport && + ls_result[i].insertTextFormat == lsInsertTextFormat::Snippet) { + ls_result[i].insertText += "$0"; + } + + ls_result[i].priority_ = + GetCompletionPriority(result.CompletionString, result.CursorKind, + ls_result[i].filterText); + } + } else { + bool do_insert = true; + int angle_stack = 0; + BuildDetailString(result.CompletionString, ls_completion_item.label, + ls_completion_item.detail, + ls_completion_item.insertText, do_insert, + ls_completion_item.insertTextFormat, + &ls_completion_item.parameters_, + g_config->client.snippetSupport, angle_stack); + if (g_config->client.snippetSupport && + ls_completion_item.insertTextFormat == + lsInsertTextFormat::Snippet) { + ls_completion_item.insertText += "$0"; + } + ls_completion_item.priority_ = + GetCompletionPriority(result.CompletionString, result.CursorKind, + ls_completion_item.label); + ls_result.push_back(ls_completion_item); } - completion_manager->on_diagnostic_(session->file.filename, - ls_diagnostics); - - /* - timer.Reset(); - completion_manager->on_index_(session->tu.get(), unsaved, - session->file.filename, session->file.args); - timer.ResetAndPrint("[complete] Reindex file"); - */ } - continue; + timer.ResetAndPrint("[complete] Building " + + std::to_string(ls_result.size()) + + " completion results"); + + request->on_complete(ls_result, false /*is_cached_result*/); + + // Make sure |ls_results| is destroyed before clearing |cx_results|. + clang_disposeCodeCompleteResults(cx_results); } } -} // namespace +void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { + while (true) { + // Fetching the completion request blocks until we have a request. + ClangCompleteManager::DiagnosticRequest request = + completion_manager->diagnostic_request_.Dequeue(); + std::string path = request.document.uri.GetPath(); -CompletionSession::CompletionSession(const Project::Entry& file, - WorkingFiles* working_files) - : file(file), - working_files(working_files), - index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/) {} + std::shared_ptr session = + completion_manager->TryGetSession(path, true /*mark_as_completion*/, + true /*create_if_needed*/); -CompletionSession::~CompletionSession() {} + // At this point, we must have a translation unit. Block until we have one. + std::lock_guard lock(session->diagnostics.lock); + Timer timer; + TryEnsureDocumentParsed( + completion_manager, session, &session->diagnostics.tu, + &session->diagnostics.index, false /*emit_diagnostics*/); + timer.ResetAndPrint("[diagnostics] TryEnsureDocumentParsed"); -ClangCompleteManager::ParseRequest::ParseRequest(const std::string& path) - : request_time(std::chrono::high_resolution_clock::now()), path(path) {} + // It is possible we failed to create the document despite + // |TryEnsureDocumentParsed|. + if (!session->diagnostics.tu) + continue; -ClangCompleteManager::CompletionRequest::CompletionRequest( - const lsRequestId& id, - const lsTextDocumentIdentifier& document, - bool emit_diagnostics) - : id(id), document(document), emit_diagnostics(emit_diagnostics) {} -ClangCompleteManager::CompletionRequest::CompletionRequest( - const lsRequestId& id, - const lsTextDocumentIdentifier& document, - const lsPosition& position, - const OnComplete& on_complete, - bool emit_diagnostics) - : id(id), - document(document), - position(position), - on_complete(on_complete), - emit_diagnostics(emit_diagnostics) {} + timer.Reset(); + WorkingFiles::Snapshot snapshot = + completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + std::vector unsaved = snapshot.AsUnsavedFiles(); + timer.ResetAndPrint("[diagnostics] Creating WorkingFile snapshot"); + + // Emit diagnostics. + timer.Reset(); + session->diagnostics.tu = ClangTranslationUnit::Reparse( + std::move(session->diagnostics.tu), unsaved); + timer.ResetAndPrint("[diagnostics] clang_reparseTranslationUnit"); + if (!session->diagnostics.tu) { + LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " + << path; + continue; + } + + size_t num_diagnostics = + clang_getNumDiagnostics(session->diagnostics.tu->cx_tu); + std::vector ls_diagnostics; + ls_diagnostics.reserve(num_diagnostics); + for (unsigned i = 0; i < num_diagnostics; ++i) { + CXDiagnostic cx_diag = + clang_getDiagnostic(session->diagnostics.tu->cx_tu, i); + std::optional diagnostic = + BuildAndDisposeDiagnostic(cx_diag, path); + // Filter messages like "too many errors emitted, stopping now + // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after + // conversion to lsDiagnostic + if (diagnostic && diagnostic->range.start.line >= 0) + ls_diagnostics.push_back(*diagnostic); + } + completion_manager->on_diagnostic_(session->file.filename, ls_diagnostics); + } +} + +} // namespace ClangCompleteManager::ClangCompleteManager(Project* project, WorkingFiles* working_files, @@ -677,13 +657,16 @@ ClangCompleteManager::ClangCompleteManager(Project* project, preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { new std::thread([&]() { - SetThreadName("completequery"); + SetThreadName("comp-query"); CompletionQueryMain(this); }); - new std::thread([&]() { - SetThreadName("completeparse"); - CompletionParseMain(this); + SetThreadName("comp-preload"); + CompletionPreloadMain(this); + }); + new std::thread([&]() { + SetThreadName("diag-query"); + DiagnosticQueryMain(this); }); } @@ -693,14 +676,20 @@ void ClangCompleteManager::CodeComplete( const OnComplete& on_complete) { completion_request_.PushBack(std::make_unique( id, completion_location.textDocument, completion_location.position, - on_complete, false)); + on_complete)); } void ClangCompleteManager::DiagnosticsUpdate( const lsRequestId& id, const lsTextDocumentIdentifier& document) { - completion_request_.PushBack( - std::make_unique(id, document, true)); + bool has = false; + diagnostic_request_.Iterate([&](const DiagnosticRequest& request) { + if (request.document.uri == document.uri) + has = true; + }); + if (!has) + diagnostic_request_.PushBack(DiagnosticRequest{document}, + true /*priority*/); } void ClangCompleteManager::NotifyView(const std::string& filename) { @@ -712,7 +701,7 @@ void ClangCompleteManager::NotifyView(const std::string& filename) { // Only reparse the file if we create a new CompletionSession. if (EnsureCompletionOrCreatePreloadSession(filename)) - parse_requests_.PushBack(ParseRequest(filename), true); + preload_requests_.PushBack(PreloadRequest(filename), true); } void ClangCompleteManager::NotifyEdit(const std::string& filename) { @@ -731,7 +720,7 @@ void ClangCompleteManager::NotifySave(const std::string& filename) { // EnsureCompletionOrCreatePreloadSession(filename); - parse_requests_.PushBack(ParseRequest(filename), true); + preload_requests_.PushBack(PreloadRequest(filename), true); } void ClangCompleteManager::NotifyClose(const std::string& filename) { diff --git a/src/clang_complete.h b/src/clang_complete.h index 015609a8b..904bc704d 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -18,22 +18,26 @@ struct CompletionSession : public std::enable_shared_from_this { + // Translation unit for clang. + struct Tu { + ClangIndex index{0, 0}; + + // When |tu| was last parsed. + std::optional> + last_parsed_at; + // Acquired when |tu| is being used. + std::mutex lock; + std::unique_ptr tu; + }; + Project::Entry file; WorkingFiles* working_files; - ClangIndex index; - - // When |tu| was last parsed. - std::optional> - tu_last_parsed_at; - - // Acquired when |tu| is being used. - std::mutex tu_lock; - // The active translation unit. - std::unique_ptr tu; + Tu completion; + Tu diagnostics; - CompletionSession(const Project::Entry& file, WorkingFiles* working_files); - ~CompletionSession(); + CompletionSession(const Project::Entry& file, WorkingFiles* wfiles) + : file(file), working_files(wfiles) {} }; struct ClangCompleteManager { @@ -49,27 +53,30 @@ struct ClangCompleteManager { bool is_cached_result)>; using OnDropped = std::function; - struct ParseRequest { - ParseRequest(const std::string& path); + struct PreloadRequest { + PreloadRequest(const std::string& path) + : request_time(std::chrono::high_resolution_clock::now()), path(path) {} std::chrono::time_point request_time; std::string path; }; struct CompletionRequest { - CompletionRequest(const lsRequestId& id, - const lsTextDocumentIdentifier& document, - bool emit_diagnostics); CompletionRequest(const lsRequestId& id, const lsTextDocumentIdentifier& document, const lsPosition& position, - const OnComplete& on_complete, - bool emit_diagnostics); + const OnComplete& on_complete) + : id(id), + document(document), + position(position), + on_complete(on_complete) {} lsRequestId id; lsTextDocumentIdentifier document; - std::optional position; - OnComplete on_complete; // May be null/empty. - bool emit_diagnostics = false; + lsPosition position; + OnComplete on_complete; + }; + struct DiagnosticRequest { + lsTextDocumentIdentifier document; }; ClangCompleteManager(Project* project, @@ -138,9 +145,10 @@ struct ClangCompleteManager { // Request a code completion at the given location. ThreadedQueue> completion_request_; + ThreadedQueue diagnostic_request_; // Parse requests. The path may already be parsed, in which case it should be // reparsed. - ThreadedQueue parse_requests_; + ThreadedQueue preload_requests_; }; // Cached completion information, so we can give fast completion results when diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index b0f629603..3f70405be 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -123,7 +123,7 @@ static const std::vector preprocessorKeywords = { "define", "undef", "include", "if", "ifdef", "ifndef", "else", "elif", "endif", "line", "error", "pragma"}; -std::vector preprocessorKeywordCompletionItems( +std::vector PreprocessorKeywordCompletionItems( const std::smatch& match) { std::vector items; for (auto& keyword : preprocessorKeywords) { @@ -160,7 +160,8 @@ char* tofixedbase64(T input, char* out) { // when given 1000+ completion items. void FilterAndSortCompletionResponse( Out_TextDocumentComplete* complete_response, - const std::string& complete_text) { + const std::string& complete_text, + bool has_open_paren) { if (!g_config->completion.filterAndSort) return; @@ -189,6 +190,10 @@ void FilterAndSortCompletionResponse( complete_response->result.isIncomplete = true; } + if (has_open_paren) + for (auto& item: items) + item.insertText = item.label; + // Set sortText. Note that this happens after resizing - we could do it // before, but then we should also sort by priority. char buf[16]; @@ -236,6 +241,26 @@ void FilterAndSortCompletionResponse( finalize(); } +// Returns true if position is an points to a '(' character in |lines|. Skips +// whitespace. +bool IsOpenParenOrAngle(const std::vector& lines, + const lsPosition& position) { + auto [c, l] = position; + while (l < lines.size()) { + const auto& line = lines[l]; + if (c >= line.size()) + return false; + if (line[c] == '(' || line[c] == '<') + return true; + if (!isspace(line[c])) break; + if (++c >= line.size()) { + c = 0; + l++; + } + } + return false; +} + struct Handler_TextDocumentCompletion : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -306,13 +331,15 @@ struct Handler_TextDocumentCompletion : MessageHandler { bool is_global_completion = false; std::string existing_completion; + lsPosition end_pos = request->params.position; if (file) { request->params.position = file->FindStableCompletionSource( request->params.position, &is_global_completion, - &existing_completion); + &existing_completion, &end_pos); } ParseIncludeLineResult result = ParseIncludeLine(buffer_line); + bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos); if (result.ok) { Out_TextDocumentComplete out; @@ -325,8 +352,8 @@ struct Handler_TextDocumentCompletion : MessageHandler { [&result](std::string_view k) { return k == result.keyword; })) { - out.result.items = preprocessorKeywordCompletionItems(result.match); - FilterAndSortCompletionResponse(&out, result.keyword); + out.result.items = PreprocessorKeywordCompletionItems(result.match); + FilterAndSortCompletionResponse(&out, result.keyword, has_open_paren); } } else if (result.keyword.compare("include") == 0) { { @@ -340,7 +367,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) out.result.items.push_back(item); } - FilterAndSortCompletionResponse(&out, result.pattern); + FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren); DecorateIncludePaths(result.match, &out.result.items); } @@ -354,15 +381,15 @@ struct Handler_TextDocumentCompletion : MessageHandler { QueueManager::WriteStdout(kMethodType, out); } else { ClangCompleteManager::OnComplete callback = std::bind( - [this, is_global_completion, existing_completion, request]( - const std::vector& results, - bool is_cached_result) { + [this, request, is_global_completion, existing_completion, + has_open_paren](const std::vector& results, + bool is_cached_result) { Out_TextDocumentComplete out; out.id = request->id; out.result.items = results; // Emit completion results. - FilterAndSortCompletionResponse(&out, existing_completion); + FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren); QueueManager::WriteStdout(kMethodType, out); // Cache completion results. diff --git a/src/threaded_queue.h b/src/threaded_queue.h index f72950e05..c14fed3bd 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -205,6 +205,15 @@ struct ThreadedQueue : public BaseThreadQueue { std::optional TryPopFrontHigh() { return TryPopFrontHelper(2); } + template + void Iterate(Fn fn) { + std::lock_guard lock(mutex_); + for (auto& entry : priority_) + fn(entry); + for (auto& entry : queue_) + fn(entry); + } + mutable std::mutex mutex_; private: diff --git a/src/working_files.cc b/src/working_files.cc index 1bd00aa15..e759b5d54 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -415,7 +415,8 @@ std::string WorkingFile::FindClosestCallNameInBuffer( lsPosition WorkingFile::FindStableCompletionSource( lsPosition position, bool* is_global_completion, - std::string* existing_completion) const { + std::string* existing_completion, + lsPosition* replace_end_pos) const { *is_global_completion = true; int start_offset = GetOffsetForPosition(position, buffer_content); @@ -441,6 +442,14 @@ lsPosition WorkingFile::FindStableCompletionSource( --offset; } + *replace_end_pos = position; + for (int i = start_offset; i < buffer_content.size(); i++) { + char c = buffer_content[i]; + if (!isalnum(c) && c != '_') break; + // We know that replace_end_pos and position are on the same line. + replace_end_pos->character++; + } + *existing_completion = buffer_content.substr(offset, start_offset - offset); return GetPositionForOffset(buffer_content, offset); } diff --git a/src/working_files.h b/src/working_files.h index c48c57d83..46e71b996 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -69,7 +69,8 @@ struct WorkingFile { // content the user has entered. lsPosition FindStableCompletionSource(lsPosition position, bool* is_global_completion, - std::string* existing_completion) const; + std::string* existing_completion, + lsPosition* replace_end_pos) const; private: // Compute index_to_buffer and buffer_to_index. From f8752cdca0d1c3b05c600ea8ded1ef1941201d93 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Apr 2018 11:57:23 -0700 Subject: [PATCH 077/378] Add caseSensitivity to config->{completion,workspaceSymbol} --- CMakeLists.txt | 15 +++++----- src/clang_indexer.cc | 3 -- src/config.h | 9 +++++- src/file_consumer.cc | 15 ++++------ src/file_consumer.h | 2 -- src/fuzzy_match.cc | 22 ++++++++------ src/fuzzy_match.h | 3 +- src/indexer.h | 7 ----- src/lsp.cc | 2 +- src/messages/text_document_completion.cc | 2 +- src/messages/workspace_symbol.cc | 2 +- src/query.cc | 37 ++++++++++++------------ 12 files changed, 57 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0594e2bab..36085bd0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ include(DefaultCMakeBuildType) # Required libclang version set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version") -set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} +set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} CACHE STRING "Downloaded libclang location") option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \ downloading libclang" OFF) @@ -33,7 +33,8 @@ if(NOT CYGWIN) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) endif() -if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) +# CMake sets MSVC for both MSVC and Clang(Windows) +if(MSVC) # Common MSVC/Clang(Windows) options target_compile_options(ccls PRIVATE /nologo @@ -87,7 +88,7 @@ endif() ### Libraries # See cmake/FindClang.cmake -find_package(Clang ${CLANG_VERSION} REQUIRED) +find_package(Clang ${LIBCLANG_VERSION} REQUIRED) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support @@ -97,7 +98,7 @@ target_link_libraries(ccls PRIVATE Threads::Threads) if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) target_link_libraries(ccls PRIVATE -lc++experimental) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) +elseif(MSVC) else() target_link_libraries(ccls PRIVATE -lstdc++fs) endif() @@ -161,8 +162,8 @@ endif() if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) add_custom_command(TARGET ccls POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${DOWNLOADED_CLANG_DIR}/bin/libclang.dll + COMMAND ${CMAKE_COMMAND} -E copy + ${DOWNLOADED_CLANG_DIR}/bin/libclang.dll $ COMMENT "Copying libclang.dll to build directory ...") endif() @@ -190,7 +191,7 @@ else() support clang-format 6.0.0") endif() - add_custom_target(format + add_custom_target(format COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold ${Clang_FORMAT_ERROR}) endif() diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index ee96345ce..d04053214 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -15,9 +15,6 @@ #include #include -// TODO: See if we can use clang_indexLoc_getFileLocation to get a type ref on -// |Foobar| in DISALLOW_COPY(Foobar) - #if CINDEX_VERSION >= 47 #define CINDEX_HAVE_PRETTY 1 #endif diff --git a/src/config.h b/src/config.h index a0b7c55ef..d4cfe1638 100644 --- a/src/config.h +++ b/src/config.h @@ -89,6 +89,11 @@ struct Config { } codeLens; struct Completion { + // 0: case-insensitive + // 1: case-folded, i.e. insensitive if no input character is uppercase. + // 2: case-sensitive + int caseSensitivity = 2; + // Some completion UI, such as Emacs' completion-at-point and company-lsp, // display completion item label and detail side by side. // This does not look right, when you see things like: @@ -209,6 +214,7 @@ struct Config { } index; struct WorkspaceSymbol { + int caseSensitivity = 1; // Maximum workspace search results. int maxNum = 1000; // If true, workspace search results will be dynamically rescored/reordered @@ -227,6 +233,7 @@ struct Config { MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, + caseSensitivity, detailedLabel, filterAndSort, includeBlacklist, @@ -248,7 +255,7 @@ MAKE_REFLECT_STRUCT(Config::Index, onDidChange, threads, whitelist); -MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, maxNum, sort); +MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 9d1d276a6..a85c666fc 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -81,7 +81,11 @@ IndexFile* FileConsumer::TryConsumeFile( CXFileUniqueID file_id; if (clang_getFileUniqueID(file, &file_id) != 0) { - EmitError(file); + std::string file_name = FileName(file); + if (!file_name.empty()) { + LOG_S(ERROR) << "Could not get unique file id for " << file_name + << " when parsing " << parse_file_; + } return nullptr; } @@ -126,12 +130,3 @@ std::vector> FileConsumer::TakeLocalState() { } return result; } - -void FileConsumer::EmitError(CXFile file) const { - std::string file_name = ToString(clang_getFileName(file)); - // TODO: Investigate this more, why can we get an empty file name? - if (!file_name.empty()) { - LOG_S(ERROR) << "Could not get unique file id for " << file_name - << " when parsing " << parse_file_; - } -} diff --git a/src/file_consumer.h b/src/file_consumer.h index de7162c3c..520aa5edb 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -68,8 +68,6 @@ struct FileConsumer { std::vector> TakeLocalState(); private: - void EmitError(CXFile file) const; - std::unordered_map> local_; FileConsumerSharedState* shared_; std::string parse_file_; diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 8bbd6b8cb..49b45de16 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -78,8 +78,11 @@ int FuzzyMatcher::MatchScore(int i, int j, bool last) { return s; } -FuzzyMatcher::FuzzyMatcher(std::string_view pattern) { +FuzzyMatcher::FuzzyMatcher(std::string_view pattern, int sensitivity) { CalculateRoles(pattern, pat_role, &pat_set); + if (sensitivity == 1) + sensitivity = pat_set & 1 << Upper ? 2 : 0; + case_sensitivity = sensitivity; size_t n = 0; for (size_t i = 0; i < pattern.size(); i++) if (pattern[i] != ' ') { @@ -112,12 +115,13 @@ int FuzzyMatcher::Match(std::string_view text) { cur[j][1] + MissScore(j, true)); // For the first char of pattern, apply extra restriction to filter bad // candidates (e.g. |int| in |PRINT|) - if (low_pat[i] == low_text[j] && - (i || text_role[j] != Tail || pat[i] == text[j])) { - cur[j + 1][1] = std::max(pre[j][0] + MatchScore(i, j, false), - pre[j][1] + MatchScore(i, j, true)); - } else - cur[j + 1][1] = kMinScore * 2; + cur[j + 1][1] = (case_sensitivity ? pat[i] == text[j] + : low_pat[i] == low_text[j] && + (i || text_role[j] != Tail || + pat[i] == text[j])) + ? std::max(pre[j][0] + MatchScore(i, j, false), + pre[j][1] + MatchScore(i, j, true)) + : cur[j + 1][1] = kMinScore * 2; } } @@ -131,7 +135,7 @@ int FuzzyMatcher::Match(std::string_view text) { TEST_SUITE("fuzzy_match") { bool Ranks(std::string_view pat, std::vector texts) { - FuzzyMatcher fuzzy(pat); + FuzzyMatcher fuzzy(pat, 0); std::vector scores; for (auto text : texts) scores.push_back(fuzzy.Match(text)); @@ -150,7 +154,7 @@ TEST_SUITE("fuzzy_match") { } TEST_CASE("test") { - FuzzyMatcher fuzzy(""); + FuzzyMatcher fuzzy("", 0); CHECK(fuzzy.Match("") == 0); CHECK(fuzzy.Match("aaa") < 0); diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 958f35cda..9dd132efd 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -12,10 +12,11 @@ class FuzzyMatcher { // overflow. constexpr static int kMinScore = INT_MIN / 4; - FuzzyMatcher(std::string_view pattern); + FuzzyMatcher(std::string_view pattern, int case_sensitivity); int Match(std::string_view text); private: + int case_sensitivity; std::string pat; std::string_view text; int pat_set, text_set; diff --git a/src/indexer.h b/src/indexer.h index 6af15b82a..43035a6b4 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -188,9 +188,6 @@ struct TypeDef : NameMixin> { types == o.types && funcs == o.funcs && vars == o.vars && kind == o.kind && hover == o.hover && comments == o.comments; } - bool operator!=(const TypeDef& o) const { - return !(*this == o); - } }; template void Reflect(TVisitor& visitor, TypeDef& value) { @@ -269,9 +266,6 @@ struct FuncDef : NameMixin> { kind == o.kind && storage == o.storage && hover == o.hover && comments == o.comments; } - bool operator!=(const FuncDef& o) const { - return !(*this == o); - } }; template @@ -359,7 +353,6 @@ struct VarDef : NameMixin> { extent == o.extent && type == o.type && kind == o.kind && storage == o.storage && hover == o.hover && comments == o.comments; } - bool operator!=(const VarDef& o) const { return !(*this == o); } }; template diff --git a/src/lsp.cc b/src/lsp.cc index e40f2d714..717cbb531 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -49,7 +49,7 @@ std::optional ReadJsonRpcContentFrom( return opt_c && *opt_c == expected; }; if (!expect_char('\r') || !expect_char('\n')) { - LOG_S(INFO) << "Unexpected token (expected \r\n sequence)"; + LOG_S(INFO) << "Unexpected token (expected \\r\\n sequence)"; return std::nullopt; } diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 3f70405be..e67d60833 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -214,7 +214,7 @@ void FilterAndSortCompletionResponse( } // Fuzzy match and remove awful candidates. - FuzzyMatcher fuzzy(complete_text); + FuzzyMatcher fuzzy(complete_text, g_config->completion.caseSensitivity); for (auto& item : items) { item.score_ = CaseFoldingSubsequenceMatch(complete_text, *item.filterText).first diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 173a53d90..e138d4a79 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -129,7 +129,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { int longest = 0; for (int i : result_indices) longest = std::max(longest, int(db->GetSymbolName(i, true).size())); - FuzzyMatcher fuzzy(query); + FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); std::vector> permutation(result_indices.size()); for (int i = 0; i < int(result_indices.size()); i++) { permutation[i] = { diff --git a/src/query.cc b/src/query.cc index e6bd14e93..093d2b401 100644 --- a/src/query.cc +++ b/src/query.cc @@ -625,15 +625,15 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexType* previous, IndexType* current) { - std::optional previous_remapped_def = + std::optional prev_remapped = ToQuery(previous_id_map, previous->def); - std::optional current_remapped_def = + std::optional current_remapped = ToQuery(current_id_map, current->def); - if (current_remapped_def && - previous_remapped_def != current_remapped_def && - !current_remapped_def->detailed_name.empty()) { + if (current_remapped && + !(prev_remapped == current_remapped) && + !current_remapped->detailed_name.empty()) { types_def_update.push_back(QueryType::DefUpdate( - current->usr, std::move(*current_remapped_def))); + current->usr, std::move(*current_remapped))); } PROCESS_UPDATE_DIFF(QueryTypeId, types_declarations, declarations, Use); @@ -686,15 +686,15 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexFunc* previous, IndexFunc* current) { - std::optional previous_remapped_def = + std::optional prev_remapped = ToQuery(previous_id_map, previous->def); - std::optional current_remapped_def = + std::optional current_remapped = ToQuery(current_id_map, current->def); - if (current_remapped_def && - previous_remapped_def != current_remapped_def && - !current_remapped_def->detailed_name.empty()) { + if (current_remapped && + !(prev_remapped == current_remapped) && + !current_remapped->detailed_name.empty()) { funcs_def_update.push_back(QueryFunc::DefUpdate( - current->usr, std::move(*current_remapped_def))); + current->usr, std::move(*current_remapped))); } PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, Use); @@ -736,15 +736,14 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexVar* previous, IndexVar* current) { - std::optional previous_remapped_def = + std::optional prev_remapped = ToQuery(previous_id_map, previous->def); - std::optional current_remapped_def = + std::optional current_remapped = ToQuery(current_id_map, current->def); - if (current_remapped_def && - previous_remapped_def != current_remapped_def && - !current_remapped_def->detailed_name.empty()) - vars_def_update.push_back(QueryVar::DefUpdate( - current->usr, std::move(*current_remapped_def))); + if (current_remapped && !(prev_remapped == current_remapped) && + !current_remapped->detailed_name.empty()) + vars_def_update.push_back( + QueryVar::DefUpdate(current->usr, std::move(*current_remapped))); PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, Use); PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Use); From 2c4d387222b19832007e643f1ad1319b9da410f5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Apr 2018 16:48:56 -0700 Subject: [PATCH 078/378] MessagePack -> custom binary format --- .gitmodules | 3 - CMakeLists.txt | 3 +- src/cache_manager.cc | 4 +- src/config.h | 8 +-- src/file_consumer.cc | 4 +- src/serializer.cc | 101 +++++++++++++---------------- src/serializer.h | 26 +++++--- src/serializers/binary.h | 131 ++++++++++++++++++++++++++++++++++++++ src/serializers/json.h | 12 ++-- src/serializers/msgpack.h | 84 ------------------------ third_party/msgpack-c | 1 - 11 files changed, 208 insertions(+), 169 deletions(-) create mode 100644 src/serializers/binary.h delete mode 100644 src/serializers/msgpack.h delete mode 160000 third_party/msgpack-c diff --git a/.gitmodules b/.gitmodules index e2c0733dd..27ff39f04 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,3 @@ [submodule "third_party/loguru"] path = third_party/loguru url = https://github.com/emilk/loguru -[submodule "third_party/msgpack-c"] - path = third_party/msgpack-c - url = https://github.com/msgpack/msgpack-c diff --git a/CMakeLists.txt b/CMakeLists.txt index 36085bd0f..f5183c7e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,8 +135,7 @@ target_include_directories(ccls PRIVATE third_party/rapidjson/include third_party/sparsepp third_party/loguru - third_party/doctest - third_party/msgpack-c/include) + third_party/doctest) ### Install diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 19e7bb59c..beb9186b1 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -59,10 +59,10 @@ struct RealCacheManager : ICacheManager { std::string AppendSerializationFormat(const std::string& base) { switch (g_config->cacheFormat) { + case SerializeFormat::Binary: + return base + ".blob"; case SerializeFormat::Json: return base + ".json"; - case SerializeFormat::MessagePack: - return base + ".mpack"; } } }; diff --git a/src/config.h b/src/config.h index d4cfe1638..c0d3774a8 100644 --- a/src/config.h +++ b/src/config.h @@ -38,12 +38,10 @@ struct Config { // "json" generates `cacheDirectory/.../xxx.json` files which can be pretty // printed with jq. // - // "msgpack" uses a compact binary serialization format (the underlying wire - // format is [MessagePack](https://msgpack.org/index.html)) which typically - // takes only 60% of the corresponding JSON size, but is difficult to inspect. - // msgpack does not store map keys and you need to re-index whenever a struct + // "binary" uses a compact binary serialization format. + // It is not schema-aware and you need to re-index whenever a struct // member has changed. - SerializeFormat cacheFormat = SerializeFormat::MessagePack; + SerializeFormat cacheFormat = SerializeFormat::Binary; // Value to use for clang -resource-dir if not present in // compile_commands.json. // diff --git a/src/file_consumer.cc b/src/file_consumer.cc index a85c666fc..796bb9f03 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -83,8 +83,8 @@ IndexFile* FileConsumer::TryConsumeFile( if (clang_getFileUniqueID(file, &file_id) != 0) { std::string file_name = FileName(file); if (!file_name.empty()) { - LOG_S(ERROR) << "Could not get unique file id for " << file_name - << " when parsing " << parse_file_; + // LOG_S(ERROR) << "Could not get unique file id for " << file_name + // << " when parsing " << parse_file_; } return nullptr; } diff --git a/src/serializer.cc b/src/serializer.cc index 978e2550e..2531c20ed 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,8 +1,8 @@ #include "serializer.h" #include "filesystem.hh" +#include "serializers/binary.h" #include "serializers/json.h" -#include "serializers/msgpack.h" #include "indexer.h" @@ -15,12 +15,10 @@ bool gTestOutputMode = false; //// Elementary types void Reflect(Reader& visitor, uint8_t& value) { - if (!visitor.IsInt()) - throw std::invalid_argument("uint8_t"); - value = (uint8_t)visitor.GetInt(); + value = visitor.GetUInt8(); } void Reflect(Writer& visitor, uint8_t& value) { - visitor.Int(value); + visitor.UInt8(value); } void Reflect(Reader& visitor, short& value) { @@ -51,12 +49,12 @@ void Reflect(Writer& visitor, int& value) { } void Reflect(Reader& visitor, unsigned& value) { - if (!visitor.IsUint64()) + if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned"); - value = visitor.GetUint32(); + value = visitor.GetUInt32(); } void Reflect(Writer& visitor, unsigned& value) { - visitor.Uint32(value); + visitor.UInt32(value); } void Reflect(Reader& visitor, long& value) { @@ -69,12 +67,12 @@ void Reflect(Writer& visitor, long& value) { } void Reflect(Reader& visitor, unsigned long& value) { - if (!visitor.IsUint64()) + if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned long"); - value = (unsigned long)visitor.GetUint64(); + value = (unsigned long)visitor.GetUInt64(); } void Reflect(Writer& visitor, unsigned long& value) { - visitor.Uint64(value); + visitor.UInt64(value); } void Reflect(Reader& visitor, long long& value) { @@ -87,12 +85,12 @@ void Reflect(Writer& visitor, long long& value) { } void Reflect(Reader& visitor, unsigned long long& value) { - if (!visitor.IsUint64()) + if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned long long"); - value = visitor.GetUint64(); + value = visitor.GetUInt64(); } void Reflect(Writer& visitor, unsigned long long& value) { - visitor.Uint64(value); + visitor.UInt64(value); } void Reflect(Reader& visitor, double& value) { @@ -302,6 +300,7 @@ void Reflect(TVisitor& visitor, IndexFile& value) { } void Reflect(Reader& visitor, std::monostate&) { + assert(visitor.Format() == SerializeFormat::Json); visitor.GetNull(); } @@ -311,22 +310,31 @@ void Reflect(Writer& visitor, std::monostate&) { void Reflect(Reader& visitor, SerializeFormat& value) { std::string fmt = visitor.GetString(); - value = fmt[0] == 'm' ? SerializeFormat::MessagePack : SerializeFormat::Json; + value = fmt[0] == 'b' ? SerializeFormat::Binary : SerializeFormat::Json; } void Reflect(Writer& visitor, SerializeFormat& value) { switch (value) { + case SerializeFormat::Binary: + visitor.String("binary"); + break; case SerializeFormat::Json: visitor.String("json"); break; - case SerializeFormat::MessagePack: - visitor.String("msgpack"); - break; } } std::string Serialize(SerializeFormat format, IndexFile& file) { switch (format) { + case SerializeFormat::Binary: { + BinaryWriter writer; + int major = IndexFile::kMajorVersion; + int minor = IndexFile::kMinorVersion; + Reflect(writer, major); + Reflect(writer, minor); + Reflect(writer, file); + return writer.Take(); + } case SerializeFormat::Json: { rapidjson::StringBuffer output; rapidjson::PrettyWriter writer(output); @@ -343,17 +351,6 @@ std::string Serialize(SerializeFormat format, IndexFile& file) { Reflect(json_writer, file); return output.GetString(); } - case SerializeFormat::MessagePack: { - msgpack::sbuffer buf; - msgpack::packer pk(&buf); - MessagePackWriter msgpack_writer(&pk); - uint64_t magic = IndexFile::kMajorVersion; - int version = IndexFile::kMinorVersion; - Reflect(msgpack_writer, magic); - Reflect(msgpack_writer, version); - Reflect(msgpack_writer, file); - return std::string(buf.data(), buf.size()); - } } return ""; } @@ -369,6 +366,26 @@ std::unique_ptr Deserialize( std::unique_ptr file; switch (format) { + case SerializeFormat::Binary: { + try { + int major, minor; + if (serialized_index_content.size() < 8) + throw std::invalid_argument("Invalid"); + BinaryReader reader(serialized_index_content); + Reflect(reader, major); + Reflect(reader, minor); + if (major != IndexFile::kMajorVersion || + minor != IndexFile::kMinorVersion) + throw std::invalid_argument("Invalid version"); + file = std::make_unique(path, file_content); + Reflect(reader, *file); + } catch (std::invalid_argument& e) { + LOG_S(INFO) << "Failed to deserialize '" << path + << "': " << e.what(); + return nullptr; + } + break; + } case SerializeFormat::Json: { rapidjson::Document reader; if (gTestOutputMode || !expected_version) { @@ -395,32 +412,6 @@ std::unique_ptr Deserialize( } break; } - - case SerializeFormat::MessagePack: { - try { - int major, minor; - if (serialized_index_content.size() < 8) - 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()); - upk.buffer_consumed(serialized_index_content.size()); - file = std::make_unique(path, file_content); - MessagePackReader reader(&upk); - Reflect(reader, major); - Reflect(reader, minor); - if (major != IndexFile::kMajorVersion || - minor != IndexFile::kMinorVersion) - throw std::invalid_argument("Invalid version"); - Reflect(reader, *file); - } catch (std::invalid_argument& e) { - LOG_S(INFO) << "Failed to deserialize msgpack '" << path - << "': " << e.what(); - return nullptr; - } - break; - } } // Restore non-serialized state. diff --git a/src/serializer.h b/src/serializer.h index d7a6ed9eb..edb35e1fe 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -16,7 +16,7 @@ #include #include -enum class SerializeFormat { Json, MessagePack }; +enum class SerializeFormat { Binary, Json }; class Reader { public: @@ -27,16 +27,17 @@ class Reader { virtual bool IsNull() = 0; virtual bool IsInt() = 0; virtual bool IsInt64() = 0; - virtual bool IsUint64() = 0; + virtual bool IsUInt64() = 0; virtual bool IsDouble() = 0; virtual bool IsString() = 0; virtual void GetNull() = 0; virtual bool GetBool() = 0; + virtual uint8_t GetUInt8() = 0; virtual int GetInt() = 0; - virtual uint32_t GetUint32() = 0; + virtual uint32_t GetUInt32() = 0; virtual int64_t GetInt64() = 0; - virtual uint64_t GetUint64() = 0; + virtual uint64_t GetUInt64() = 0; virtual double GetDouble() = 0; virtual std::string GetString() = 0; @@ -55,9 +56,10 @@ class Writer { virtual void Null() = 0; virtual void Bool(bool x) = 0; virtual void Int(int x) = 0; - virtual void Uint32(uint32_t x) = 0; virtual void Int64(int64_t x) = 0; - virtual void Uint64(uint64_t x) = 0; + virtual void UInt8(uint8_t x) = 0; + virtual void UInt32(uint32_t x) = 0; + virtual void UInt64(uint64_t x) = 0; virtual void Double(double x) = 0; virtual void String(const char* x) = 0; virtual void String(const char* x, size_t len) = 0; @@ -192,9 +194,11 @@ void Reflect(Reader& visitor, std::optional& value) { } template void Reflect(Writer& visitor, std::optional& value) { - if (value) + if (value) { + if (visitor.Format() != SerializeFormat::Json) + visitor.UInt8(1); Reflect(visitor, *value); - else + } else visitor.Null(); } @@ -211,9 +215,11 @@ void Reflect(Reader& visitor, Maybe& value) { } template void Reflect(Writer& visitor, Maybe& value) { - if (value) + if (value) { + if (visitor.Format() != SerializeFormat::Json) + visitor.UInt8(1); Reflect(visitor, *value); - else + } else visitor.Null(); } diff --git a/src/serializers/binary.h b/src/serializers/binary.h new file mode 100644 index 000000000..ad6d64fe5 --- /dev/null +++ b/src/serializers/binary.h @@ -0,0 +1,131 @@ +#pragma once + +#include "serializer.h" + +#include + +class BinaryReader : public Reader { + const char* p_; + + template + T Get() { + auto ret = *reinterpret_cast(p_); + p_ += sizeof(T); + return ret; + } + + uint64_t VarUInt() { + auto x = *reinterpret_cast(p_++); + if (x < 253) + return x; + if (x == 253) + return Get(); + if (x == 254) + return Get(); + return Get(); + } + int64_t VarInt() { + uint64_t x = VarUInt(); + return int64_t(x >> 1 ^ -(x & 1)); + } + + public: + BinaryReader(std::string_view buf) : p_(buf.data()) {} + SerializeFormat Format() const override { + return SerializeFormat::Binary; + } + + bool IsBool() override { return true; } + // Abuse how the function is called in serializer.h + bool IsNull() override { return !*p_++; } + bool IsInt() override { return true; } + bool IsInt64() override {return true;} + bool IsUInt64() override {return true;} + bool IsDouble() override {return true;}; + bool IsString() override {return true;} + + void GetNull() override {} + bool GetBool() override { return Get(); } + int GetInt() override { return VarInt(); } + int64_t GetInt64() override { return VarInt(); } + uint8_t GetUInt8() override { return Get(); } + uint32_t GetUInt32() override { return VarUInt(); } + uint64_t GetUInt64() override { return VarUInt(); } + double GetDouble() override { return Get(); } + std::string GetString() override { + if (auto n = VarUInt()) { + std::string ret(p_, n); + p_ += n; + return ret; + } + return ""; + } + + bool HasMember(const char* x) override { return true; } + std::unique_ptr operator[](const char* x) override { return {}; } + + void IterArray(std::function fn) override { + for (auto n = VarUInt(); n; n--) + fn(*this); + } + + void DoMember(const char*, std::function fn) override { + fn(*this); + } +}; + +class BinaryWriter : public Writer { + std::string buf_; + + template + void Pack(T x) { + auto i = buf_.size(); + buf_.resize(i + sizeof(x)); + *reinterpret_cast(buf_.data() + i) = x; + } + + void VarUInt(uint64_t n) { + if (n < 253) + Pack(n); + else if (n < 65536) { + Pack(253); + Pack(n); + } else if (n < 4294967296) { + Pack(254); + Pack(n); + } else { + Pack(255); + Pack(n); + } + } + void VarInt(int64_t n) { + VarUInt(uint64_t(n) << 1 ^ n >> 63); + } + + public: + SerializeFormat Format() const override { + return SerializeFormat::Binary; + } + std::string Take() { return std::move(buf_); } + + void Null() override { Pack(uint8_t(0)); } + void Bool(bool x) override { Pack(x); } + void Int(int x) override { VarInt(x); } + void Int64(int64_t x) override { VarInt(x); } + void UInt8(uint8_t x) override { Pack(x); } + void UInt32(uint32_t x) override { VarUInt(x); } + void UInt64(uint64_t x) override { VarUInt(x); } + void Double(double x) override { Pack(x); } + void String(const char* x) override { String(x, strlen(x)); } + void String(const char* x, size_t len) override { + VarUInt(len); + auto i = buf_.size(); + buf_.resize(i + len); + memcpy(buf_.data() + i, x, len); + } + void StartArray(size_t n) override { VarUInt(n); } + void EndArray() override {} + void StartObject() override {} + void EndObject() override {} + void Key(const char* name) override {} +}; diff --git a/src/serializers/json.h b/src/serializers/json.h index aa9d5f0f4..d4f25f489 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -17,16 +17,17 @@ class JsonReader : public Reader { bool IsNull() override { return m_->IsNull(); } bool IsInt() override { return m_->IsInt(); } bool IsInt64() override { return m_->IsInt64(); } - bool IsUint64() override { return m_->IsUint64(); } + bool IsUInt64() override { return m_->IsUint64(); } bool IsDouble() override { return m_->IsDouble(); } bool IsString() override { return m_->IsString(); } void GetNull() override {} bool GetBool() override { return m_->GetBool(); } int GetInt() override { return m_->GetInt(); } - uint32_t GetUint32() override { return uint32_t(m_->GetUint64()); } int64_t GetInt64() override { return m_->GetInt64(); } - uint64_t GetUint64() override { return m_->GetUint64(); } + uint8_t GetUInt8() override { return uint8_t(m_->GetInt()); } + uint32_t GetUInt32() override { return uint32_t(m_->GetUint64()); } + uint64_t GetUInt64() override { return m_->GetUint64(); } double GetDouble() override { return m_->GetDouble(); } std::string GetString() override { return m_->GetString(); } @@ -83,9 +84,10 @@ class JsonWriter : public Writer { void Null() override { m_->Null(); } void Bool(bool x) override { m_->Bool(x); } void Int(int x) override { m_->Int(x); } - void Uint32(uint32_t x) override { m_->Uint64(x); } void Int64(int64_t x) override { m_->Int64(x); } - void Uint64(uint64_t x) override { m_->Uint64(x); } + void UInt8(uint8_t x) override { m_->Int(x); } + void UInt32(uint32_t x) override { m_->Uint64(x); } + void UInt64(uint64_t x) override { m_->Uint64(x); } void Double(double x) override { m_->Double(x); } void String(const char* x) override { m_->String(x); } void String(const char* x, size_t len) override { m_->String(x, len); } diff --git a/src/serializers/msgpack.h b/src/serializers/msgpack.h deleted file mode 100644 index 83ea59836..000000000 --- a/src/serializers/msgpack.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "serializer.h" - -#include - -class MessagePackReader : public Reader { - msgpack::unpacker* pk_; - msgpack::object_handle oh_; - - template - T Get() { - T ret = oh_.get().as(); - pk_->next(oh_); - return ret; - } - - public: - MessagePackReader(msgpack::unpacker* pk) : pk_(pk) { pk->next(oh_); } - SerializeFormat Format() const override { - return SerializeFormat::MessagePack; - } - - bool IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; } - bool IsNull() override { return oh_.get().is_nil(); } - bool IsInt() override { - return oh_.get().type == msgpack::type::POSITIVE_INTEGER || - oh_.get().type == msgpack::type::NEGATIVE_INTEGER; - } - bool IsInt64() override { return IsInt(); } - bool IsUint64() override { return IsInt(); } - bool IsDouble() override { return oh_.get().type == msgpack::type::FLOAT64; }; - bool IsString() override { return oh_.get().type == msgpack::type::STR; } - - void GetNull() override { pk_->next(oh_); } - bool GetBool() override { return Get(); } - int GetInt() override { return Get(); } - uint32_t GetUint32() override { return Get(); } - int64_t GetInt64() override { return Get(); } - uint64_t GetUint64() override { return Get(); } - double GetDouble() override { return Get(); } - std::string GetString() override { return Get(); } - - bool HasMember(const char* x) override { return true; } - std::unique_ptr operator[](const char* x) override { return {}; } - - void IterArray(std::function fn) override { - size_t n = Get(); - for (size_t i = 0; i < n; i++) - fn(*this); - } - - void DoMember(const char*, std::function fn) override { - fn(*this); - } -}; - -class MessagePackWriter : public Writer { - msgpack::packer* m_; - - public: - MessagePackWriter(msgpack::packer* m) : m_(m) {} - SerializeFormat Format() const override { - return SerializeFormat::MessagePack; - } - - void Null() override { m_->pack_nil(); } - void Bool(bool x) override { m_->pack(x); } - void Int(int x) override { m_->pack(x); } - void Uint32(uint32_t x) override { m_->pack(x); } - void Int64(int64_t x) override { m_->pack(x); } - void Uint64(uint64_t x) override { m_->pack(x); } - void Double(double x) override { m_->pack(x); } - void String(const char* x) override { m_->pack(x); } - // TODO Remove std::string - void String(const char* x, size_t len) override { - m_->pack(std::string(x, len)); - } - void StartArray(size_t n) override { m_->pack(n); } - void EndArray() override {} - void StartObject() override {} - void EndObject() override {} - void Key(const char* name) override {} -}; diff --git a/third_party/msgpack-c b/third_party/msgpack-c deleted file mode 160000 index 208595b26..000000000 --- a/third_party/msgpack-c +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 208595b2620cf6260ce3d6d4cf8543f13b206449 From 4d519dcbcbf4b5fe845bf052ae43a01997cae20e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Apr 2018 10:21:26 -0700 Subject: [PATCH 079/378] Update loguru --- CMakeLists.txt | 30 +++++++++++++++--------------- src/clang_indexer.cc | 5 ++--- src/command_line.cc | 3 +++ third_party/loguru | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5183c7e8..9ecb46804 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,12 +4,12 @@ project(ccls LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) -# Required libclang version -set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version") -set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} - CACHE STRING "Downloaded libclang location") -option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \ - downloading libclang" OFF) +# Required Clang version +set(CLANG_VERSION 6.0.0 CACHE STRING "Clang version") +set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} + CACHE STRING "Downloaded Clang location") +option(SYSTEM_CLANG "Use system installation of Clang instead of \ + downloading Clang" OFF) option(ASAN "Compile with address sanitizers" OFF) # Sources for the executable are specified at end of CMakeLists.txt @@ -72,23 +72,23 @@ else() endif() endif() -### Download libclang if required +### Download Clang if required + +if(NOT SYSTEM_CLANG) + message(STATUS "Using downloaded Clang") -if(NOT SYSTEM_LIBCLANG) - message(STATUS "Using downloaded libclang") - include(DownloadAndExtractClang) - download_and_extract_clang(${LIBCLANG_VERSION} ${LIBCLANG_DOWNLOAD_LOCATION}) + download_and_extract_clang(${CLANG_VERSION} ${CLANG_DOWNLOAD_LOCATION}) # Used by FindClang set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) else() - message(STATUS "Using system libclang") + message(STATUS "Using system Clang") endif() ### Libraries # See cmake/FindClang.cmake -find_package(Clang ${LIBCLANG_VERSION} REQUIRED) +find_package(Clang ${CLANG_VERSION} REQUIRED) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support @@ -142,7 +142,7 @@ target_include_directories(ccls PRIVATE install(TARGETS ccls RUNTIME DESTINATION bin) # TODO: install libclang.dll on Windows as well -if(NOT SYSTEM_LIBCLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) +if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) set_property(TARGET ccls APPEND PROPERTY @@ -158,7 +158,7 @@ if(NOT SYSTEM_LIBCLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) endif() # Allow running from build Windows by copying libclang.dll to build directory -if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) +if(NOT SYSTEM_CLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) add_custom_command(TARGET ccls POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index d04053214..6c6426b03 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -664,9 +664,8 @@ void SetVarDetail(IndexVar* var, } if (is_first_seen) { - std::optional var_type = - ResolveToDeclarationType(db, cursor, param); - if (var_type) { + if (std::optional var_type = + ResolveToDeclarationType(db, cursor, param)) { // Don't treat enum definition variables as instantiations. bool is_enum_member = semanticContainer && semanticContainer->cursor.kind == CXCursor_EnumDecl; diff --git a/src/command_line.cc b/src/command_line.cc index 6eb155962..1e5691384 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -341,6 +341,9 @@ int main(int argc, char** argv) { if (!HasOption(options, "--log-all-to-stderr")) loguru::g_stderr_verbosity = loguru::Verbosity_WARNING; + loguru::g_preamble_date = false; + loguru::g_preamble_time = false; + loguru::g_preamble_verbose = false; loguru::g_flush_interval_ms = 0; loguru::init(argc, argv); diff --git a/third_party/loguru b/third_party/loguru index 2c35b5e72..6bf94c5f2 160000 --- a/third_party/loguru +++ b/third_party/loguru @@ -1 +1 @@ -Subproject commit 2c35b5e7251ab5d364b1b3164eccef7b5d2293c5 +Subproject commit 6bf94c5f2bec437e871402d0a27e8a3094b261d5 From fa9df5bcef05aad7ac172a6f3f1719ab8ee24a34 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 16 Apr 2018 12:36:02 -0700 Subject: [PATCH 080/378] Remove variant and clean up --- src/clang_complete.cc | 13 ++- src/clang_complete.h | 3 +- src/command_line.cc | 12 +-- src/import_pipeline.cc | 3 +- src/include_complete.cc | 44 ++++----- src/lsp.cc | 13 +++ src/lsp.h | 11 ++- src/messages/ccls_freshen_index.cc | 2 +- src/messages/initialize.cc | 4 +- src/messages/shutdown.cc | 4 +- src/messages/text_document_did_change.cc | 1 - src/messages/text_document_hover.cc | 89 +++++++++---------- .../workspace_did_change_configuration.cc | 2 +- src/method.cc | 40 ++++++++- src/method.h | 15 +++- src/project.h | 1 - src/serializer.cc | 18 ++-- src/serializer.h | 64 ++----------- src/working_files.cc | 22 ++--- 19 files changed, 171 insertions(+), 190 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index b3c271d65..25eec8e75 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -656,18 +656,18 @@ ClangCompleteManager::ClangCompleteManager(Project* project, on_dropped_(on_dropped), preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { - new std::thread([&]() { + std::thread([&]() { SetThreadName("comp-query"); CompletionQueryMain(this); - }); - new std::thread([&]() { + }).detach(); + std::thread([&]() { SetThreadName("comp-preload"); CompletionPreloadMain(this); - }); - new std::thread([&]() { + }).detach(); + std::thread([&]() { SetThreadName("diag-query"); DiagnosticQueryMain(this); - }); + }).detach(); } void ClangCompleteManager::CodeComplete( @@ -680,7 +680,6 @@ void ClangCompleteManager::CodeComplete( } void ClangCompleteManager::DiagnosticsUpdate( - const lsRequestId& id, const lsTextDocumentIdentifier& document) { bool has = false; diagnostic_request_.Iterate([&](const DiagnosticRequest& request) { diff --git a/src/clang_complete.h b/src/clang_complete.h index 904bc704d..7eace6269 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -91,8 +91,7 @@ struct ClangCompleteManager { const lsTextDocumentPositionParams& completion_location, const OnComplete& on_complete); // Request a diagnostics update. - void DiagnosticsUpdate(const lsRequestId& request_id, - const lsTextDocumentIdentifier& document); + void DiagnosticsUpdate(const lsTextDocumentIdentifier& document); // Notify the completion manager that |filename| has been viewed and we // should begin preloading completion data. diff --git a/src/command_line.cc b/src/command_line.cc index 1e5691384..cea671912 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -172,7 +172,7 @@ void RunQueryDbThread(const std::string& bin_name, args); }, [](lsRequestId id) { - if (!std::holds_alternative(id)) { + if (id.Valid()) { Out_Error out; out.id = id; out.error.code = lsErrorCodes::InternalError; @@ -243,7 +243,7 @@ void RunQueryDbThread(const std::string& bin_name, // // |ipc| is connected to a server. void LaunchStdinLoop(std::unordered_map* request_times) { - new std::thread([request_times]() { + std::thread([request_times]() { SetThreadName("stdin"); auto* queue = QueueManager::instance(); while (true) { @@ -257,7 +257,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { // Emit an error ResponseMessage if |id| is available. if (message) { lsRequestId id = message->GetRequestId(); - if (!std::holds_alternative(id)) { + if (id.Valid()) { Out_Error out; out.id = id; out.error.code = lsErrorCodes::InvalidParams; @@ -279,12 +279,12 @@ void LaunchStdinLoop(std::unordered_map* request_times) { if (method_type == kMethodType_Exit) break; } - }); + }).detach(); } void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { - new std::thread([=]() { + std::thread([=]() { SetThreadName("stdout"); auto* queue = QueueManager::instance(); @@ -305,7 +305,7 @@ void LaunchStdoutThread(std::unordered_map* request_times, fflush(stdout); } } - }); + }).detach(); } void LanguageServerMain(const std::string& bin_name, diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 89bc4d389..cea5ad6e7 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -393,8 +393,7 @@ void ParseFile(DiagnosticsEngine* diag_engine, file_contents, &perf); if (indexes.empty()) { - if (g_config->index.enabled && - !std::holds_alternative(request.id)) { + if (g_config->index.enabled && request.id.Valid()) { Out_Error out; out.id = request.id; out.error.code = lsErrorCodes::InternalError; diff --git a/src/include_complete.cc b/src/include_complete.cc index f44bedcc6..4bedad394 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -29,21 +29,16 @@ std::string ElideLongPath(const std::string& path) { size_t TrimCommonPathPrefix(const std::string& result, const std::string& trimmer) { - size_t i = 0; - while (i < result.size() && i < trimmer.size()) { - char a = result[i]; - char b = trimmer[i]; -#if defined(_WIN32) - a = (char)tolower(a); - b = (char)tolower(b); +#ifdef _WIN32 + std::string s = result, t = trimmer; + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + std::transform(t.begin(), t.end(), t.begin(), ::tolower); + if (s.compare(0, t.size(), t) == 0) + return t.size(); +#else + if (result.compare(0, trimmer.size(), trimmer) == 0) + return trimmer.size(); #endif - if (a != b) - break; - ++i; - } - - if (i == trimmer.size()) - return i; return 0; } @@ -51,21 +46,14 @@ size_t TrimCommonPathPrefix(const std::string& result, bool TrimPath(Project* project, const std::string& project_root, std::string* insert_path) { - size_t start = 0; + size_t start = TrimCommonPathPrefix(*insert_path, project_root); bool angle = false; - size_t len = TrimCommonPathPrefix(*insert_path, project_root); - if (len > start) - start = len; - - for (auto& include_dir : project->quote_include_directories) { - len = TrimCommonPathPrefix(*insert_path, include_dir); - if (len > start) - start = len; - } + for (auto& include_dir : project->quote_include_directories) + start = std::max(start, TrimCommonPathPrefix(*insert_path, include_dir)); for (auto& include_dir : project->angle_include_directories) { - len = TrimCommonPathPrefix(*insert_path, include_dir); + auto len = TrimCommonPathPrefix(*insert_path, include_dir); if (len > start) { start = len; angle = true; @@ -115,8 +103,8 @@ void IncludeComplete::Rescan() { g_config->completion.includeBlacklist); is_scanning = true; - new std::thread([this]() { - SetThreadName("scan_includes"); + std::thread([this]() { + SetThreadName("scan_includes"); Timer timer; InsertStlIncludes(); @@ -129,7 +117,7 @@ void IncludeComplete::Rescan() { timer.ResetAndPrint("[perf] Scanning for includes"); is_scanning = false; - }); + }).detach(); } void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, diff --git a/src/lsp.cc b/src/lsp.cc index 717cbb531..9b11ac76b 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -275,6 +275,19 @@ bool lsTextEdit::operator==(const lsTextEdit& that) { return range == that.range && newText == that.newText; } +void Reflect(Writer& visitor, lsMarkedString& value) { + // If there is a language, emit a `{language:string, value:string}` object. If + // not, emit a string. + if (value.language) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(language); + REFLECT_MEMBER(value); + REFLECT_MEMBER_END(); + } else { + Reflect(visitor, value.value); + } +} + std::string Out_ShowLogMessage::method() { if (display_type == DisplayType::Log) return "window/logMessage"; diff --git a/src/lsp.h b/src/lsp.h index 31ebd07ba..a72410b68 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -239,7 +239,7 @@ MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri); struct lsVersionedTextDocumentIdentifier { lsDocumentUri uri; // The version number of this document. number | null - std::variant version; + std::optional version; lsTextDocumentIdentifier AsTextDocumentIdentifier() const; }; @@ -325,12 +325,11 @@ MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); // // Note that markdown strings will be sanitized - that means html will be // escaped. -struct lsMarkedString1 { - std::string_view language; - std::string_view value; +struct lsMarkedString { + std::optional language; + std::string value; }; -using lsMarkedString = std::variant; -MAKE_REFLECT_STRUCT(lsMarkedString1, language, value); +void Reflect(Writer& visitor, lsMarkedString& value); struct lsTextDocumentContentChangeEvent { // The range of the document that changed. diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 10220b538..91d0bc007 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -87,7 +87,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { Timer time; // Send index requests for every file. - project->Index(QueueManager::instance(), working_files, std::monostate()); + project->Index(QueueManager::instance(), working_files, lsRequestId()); time.ResetAndPrint("[perf] Dispatched $ccls/freshenIndex index requests"); } }; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index d2aa51676..8ee38d91f 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -518,12 +518,12 @@ struct Handler_Initialize : BaseMessageHandler { } LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; for (int i = 0; i < g_config->index.threads; i++) { - new std::thread([=]() { + std::thread([=]() { SetThreadName("indexer" + std::to_string(i)); Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, import_manager, import_pipeline_status, project, working_files, waiter); - }); + }).detach(); } // Start scanning include directories before dispatching project diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index 5967e2399..e16721d47 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -11,8 +11,8 @@ MAKE_REFLECT_STRUCT(In_Shutdown, id); REGISTER_IN_MESSAGE(In_Shutdown); struct Out_Shutdown : public lsOutMessage { - lsRequestId id; // defaults to std::monostate (null) - std::monostate result; // null + lsRequestId id; + JsonNull result; }; MAKE_REFLECT_STRUCT(Out_Shutdown, jsonrpc, id, result); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 5f5d2a71c..bc976cbd8 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -39,7 +39,6 @@ struct Handler_TextDocumentDidChange } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( - std::monostate(), request->params.textDocument.AsTextDocumentIdentifier()); } }; diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index a5b518128..7ea1aeee3 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -5,41 +5,40 @@ namespace { MethodType kMethodType = "textDocument/hover"; -std::pair GetCommentsAndHover( - QueryDatabase* db, - SymbolRef sym) { - switch (sym.kind) { - case SymbolKind::Type: { - if (const auto* def = db->GetType(sym).AnyDef()) { - return {def->comments, !def->hover.empty() - ? std::string_view(def->hover) - : std::string_view(def->detailed_name)}; +// Find the comments for |sym|, if any. +std::optional GetComments(QueryDatabase* db, SymbolRef sym) { + std::optional ret; + WithEntity(db, sym, [&](const auto& entity) { + if (const auto* def = entity.AnyDef()) + if (!def->comments.empty()) { + lsMarkedString m; + m.value = def->comments; + ret = m; } - break; - } - case SymbolKind::Func: { - if (const auto* def = db->GetFunc(sym).AnyDef()) { - return {def->comments, !def->hover.empty() - ? std::string_view(def->hover) - : std::string_view(def->detailed_name)}; - } - break; - } - case SymbolKind::Var: { - if (const auto* def = db->GetVar(sym).AnyDef()) { - return {def->comments, !def->hover.empty() - ? std::string_view(def->hover) - : std::string_view(def->detailed_name)}; + }); + return ret; +} + +// Returns the hover or detailed name for `sym`, if any. +std::optional GetHoverOrName(QueryDatabase* db, + const std::string& language, + SymbolRef sym) { + + std::optional ret; + WithEntity(db, sym, [&](const auto& entity) { + if (const auto* def = entity.AnyDef()) { + lsMarkedString m; + m.language = language; + if (!def->hover.empty()) { + m.value = def->hover; + ret = m; + } else if (!def->detailed_name.empty()) { + m.value = def->detailed_name; + ret = m; } - break; - } - case SymbolKind::File: - case SymbolKind::Invalid: { - assert(false && "unexpected"); - break; } - } - return {"", ""}; + }); + return ret; } struct In_TextDocumentHover : public RequestInMessage { @@ -66,7 +65,7 @@ void Reflect(Writer& visitor, Out_TextDocumentHover& value) { if (value.result) REFLECT_MEMBER(result); else { - // Empty std::optional<> is elided by the default serializer, we need to write + // Empty optional<> is elided by the default serializer, we need to write // |null| to be compliant with the LSP. visitor.Key("result"); visitor.Null(); @@ -77,11 +76,11 @@ void Reflect(Writer& visitor, Out_TextDocumentHover& value) { struct Handler_TextDocumentHover : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentHover* request) override { + auto& params = request->params; QueryFile* file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { + params.textDocument.uri.GetPath(), &file)) return; - } WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); @@ -90,25 +89,23 @@ struct Handler_TextDocumentHover : BaseMessageHandler { out.id = request->id; for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + FindSymbolsAtLocation(working_file, file, params.position)) { // Found symbol. Return hover. std::optional ls_range = GetLsRange( working_files->GetFileByFilename(file->def->path), sym.range); if (!ls_range) continue; - std::pair comments_hover = - GetCommentsAndHover(db, sym); - if (comments_hover.first.size() || comments_hover.second.size()) { + std::optional comments = GetComments(db, sym); + std::optional hover = + GetHoverOrName(db, file->def->language, sym); + if (comments || hover) { out.result = Out_TextDocumentHover::Result(); - if (comments_hover.first.size()) { - out.result->contents.emplace_back(comments_hover.first); - } - if (comments_hover.second.size()) { - out.result->contents.emplace_back(lsMarkedString1{ - std::string_view(file->def->language), comments_hover.second}); - } out.result->range = *ls_range; + if (comments) + out.result->contents.push_back(*comments); + if (hover) + out.result->contents.push_back(*hover); break; } } diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 8d81b892d..afe578ca1 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -33,7 +33,7 @@ struct Handler_WorkspaceDidChangeConfiguration std::to_string(project->entries.size()) + " files)"); time.Reset(); - project->Index(QueueManager::instance(), working_files, std::monostate()); + project->Index(QueueManager::instance(), working_files, lsRequestId()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); diff --git a/src/method.cc b/src/method.cc index 99af41a37..f0ba5ce18 100644 --- a/src/method.cc +++ b/src/method.cc @@ -2,6 +2,40 @@ MethodType kMethodType_Unknown = "$unknown"; MethodType kMethodType_Exit = "exit"; -MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; -MethodType kMethodType_CclsPublishInactiveRegions = "$ccls/publishInactiveRegions"; -MethodType kMethodType_CclsPublishSemanticHighlighting = "$ccls/publishSemanticHighlighting"; +MethodType kMethodType_TextDocumentPublishDiagnostics = + "textDocument/publishDiagnostics"; +MethodType kMethodType_CclsPublishInactiveRegions = + "$ccls/publishInactiveRegions"; +MethodType kMethodType_CclsPublishSemanticHighlighting = + "$ccls/publishSemanticHighlighting"; + +void Reflect(Reader& visitor, lsRequestId& value) { + if (visitor.IsInt64()) { + value.type = lsRequestId::kInt; + value.value = visitor.GetInt64(); + } else if (visitor.IsInt()) { + value.type = lsRequestId::kInt; + value.value = visitor.GetInt(); + } else if (visitor.IsString()) { + value.type = lsRequestId::kString; + value.value = atoll(visitor.GetString().c_str()); + } else { + value.type = lsRequestId::kNone; + value.value = -1; + } +} + +void Reflect(Writer& visitor, lsRequestId& value) { + switch (value.type) { + case lsRequestId::kNone: + visitor.Null(); + break; + case lsRequestId::kInt: + visitor.Int(value.value); + break; + case lsRequestId::kString: + auto s = std::to_string(value.value); + visitor.String(s.c_str(), s.length()); + break; + } +} diff --git a/src/method.h b/src/method.h index a336ed5be..525c409ae 100644 --- a/src/method.h +++ b/src/method.h @@ -12,7 +12,18 @@ extern MethodType kMethodType_TextDocumentPublishDiagnostics; extern MethodType kMethodType_CclsPublishInactiveRegions; extern MethodType kMethodType_CclsPublishSemanticHighlighting; -using lsRequestId = std::variant; +struct lsRequestId { + // The client can send the request id as an int or a string. We should output + // the same format we received. + enum Type { kNone, kInt, kString }; + Type type = kNone; + + int value = -1; + + bool Valid() const { return type != kNone; } +}; +void Reflect(Reader& visitor, lsRequestId& value); +void Reflect(Writer& visitor, lsRequestId& value); struct InMessage { virtual ~InMessage() = default; @@ -32,6 +43,6 @@ struct RequestInMessage : public InMessage { // NotificationInMessage does not have |id|. struct NotificationInMessage : public InMessage { lsRequestId GetRequestId() const override { - return std::monostate(); + return lsRequestId(); } }; diff --git a/src/project.h b/src/project.h index d67562ab8..0767e9453 100644 --- a/src/project.h +++ b/src/project.h @@ -8,7 +8,6 @@ #include #include #include -#include #include class QueueManager; diff --git a/src/serializer.cc b/src/serializer.cc index 2531c20ed..2f2acd051 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -140,6 +140,15 @@ void Reflect(Writer& visitor, NtString& value) { visitor.String(s ? s : ""); } +void Reflect(Reader& visitor, JsonNull& value) { + assert(visitor.Format() == SerializeFormat::Json); + visitor.GetNull(); +} + +void Reflect(Writer& visitor, JsonNull& value) { + visitor.Null(); +} + // TODO: Move this to indexer.cc void Reflect(Reader& visitor, IndexInclude& value) { REFLECT_MEMBER_START(); @@ -299,15 +308,6 @@ void Reflect(TVisitor& visitor, IndexFile& value) { REFLECT_MEMBER_END(); } -void Reflect(Reader& visitor, std::monostate&) { - assert(visitor.Format() == SerializeFormat::Json); - visitor.GetNull(); -} - -void Reflect(Writer& visitor, std::monostate&) { - visitor.Null(); -} - void Reflect(Reader& visitor, SerializeFormat& value) { std::string fmt = visitor.GetString(); value = fmt[0] == 'b' ? SerializeFormat::Binary : SerializeFormat::Json; diff --git a/src/serializer.h b/src/serializer.h index edb35e1fe..b31ae2b48 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -13,11 +13,12 @@ #include #include #include -#include #include enum class SerializeFormat { Binary, Json }; +struct JsonNull {}; + class Reader { public: virtual ~Reader() {} @@ -168,20 +169,18 @@ void Reflect(Writer& visitor, std::string_view& view); void Reflect(Reader& visitor, NtString& value); void Reflect(Writer& visitor, NtString& value); -// std::monostate is used to represent JSON null -void Reflect(Reader& visitor, std::monostate&); -void Reflect(Writer& visitor, std::monostate&); +void Reflect(Reader& visitor, JsonNull& value); +void Reflect(Writer& visitor, JsonNull& value); void Reflect(Reader& visitor, SerializeFormat& value); void Reflect(Writer& visitor, SerializeFormat& value); //// Type constructors -// ReflectMember std::optional is used to represent TypeScript std::optional properties +// ReflectMember std::optional is used to represent TypeScript optional properties // (in `key: value` context). // Reflect std::optional is used for a different purpose, whether an object is -// nullable (possibly in `value` context). For the nullable semantics, -// std::variant is recommended. +// nullable (possibly in `value` context). template void Reflect(Reader& visitor, std::optional& value) { if (visitor.IsNull()) { @@ -243,57 +242,6 @@ void ReflectMember(Writer& visitor, const char* name, Maybe& value) { } } -// Helper struct to reflect std::variant -template -struct ReflectVariant { - // If T appears in Ts..., we should set the value of std::variant to - // what we get from Reader. - template - void ReflectTag(Reader& visitor, std::variant& value) { - if constexpr (std::disjunction_v...>) { - T a; - Reflect(visitor, a); - value = std::move(a); - } - } - - void operator()(Reader& visitor, std::variant& value) { - // Based on tag dispatch, call different ReflectTag helper. - if (visitor.IsNull()) - ReflectTag(visitor, value); - // It is possible that IsInt64() && IsInt(). We don't call ReflectTag - // if int is not in Ts... - else if (std::disjunction_v...> && visitor.IsInt()) - ReflectTag(visitor, value); - else if (visitor.IsInt64()) - ReflectTag(visitor, value); - else if (visitor.IsString()) - ReflectTag(visitor, value); - else - assert(0); - } - - // Check which type the variant contains and call corresponding Reflect. - void operator()(Writer& visitor, std::variant& value) { - if (value.index() == N - 1) - Reflect(visitor, std::get(value)); - else - ReflectVariant()(visitor, value); - } -}; - -// Writer reflection on std::variant recurses. This is induction basis. -template -struct ReflectVariant<0, Ts...> { - void operator()(Writer& visitor, std::variant& value) {} -}; - -// std::variant -template -void Reflect(TVisitor& visitor, std::variant& value) { - ReflectVariant()(visitor, value); -} - // std::vector template void Reflect(Reader& visitor, std::vector& values) { diff --git a/src/working_files.cc b/src/working_files.cc index e759b5d54..5e2934641 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -24,19 +24,15 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) { if (offset >= content.size()) offset = (int)content.size() - 1; - lsPosition result; + int line = 0, col = 0; int i = 0; - while (i < offset) { - if (content[i] == '\n') { - result.line += 1; - result.character = 0; - } else { - result.character += 1; - } - ++i; + for (; i < offset; i++) { + if (content[i] == '\n') + line++, col = 0; + else + col++; } - - return result; + return {line, col}; } std::vector ToLines(const std::string& content) { @@ -511,8 +507,8 @@ void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { } // version: number | null - if (std::holds_alternative(change.textDocument.version)) - file->version = std::get(change.textDocument.version); + if (change.textDocument.version) + file->version = *change.textDocument.version; for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) { // Per the spec replace everything if the rangeLength and range are not set. From b4cca890c657028ddb834320e2e0ec6a0bada77e Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Wed, 18 Apr 2018 15:17:24 +0800 Subject: [PATCH 081/378] using SIGSTOP (avoid interactive signal blocking) (#2) --- src/platform_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 6af30d70b..4e9b952f6 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -199,7 +199,7 @@ void TraceMe() { // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. if (getenv("CCLS_TRACEME")) - raise(SIGTSTP); + raise(SIGSTOP); } std::string GetExternalCommandOutput(const std::vector& command, From d821ac34d811975224394b8b62d1886bcd1de3c4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 22 Apr 2018 10:01:44 -0700 Subject: [PATCH 082/378] Merge {timestamp_manager,iindexer}.{cc,h}; remove standard_includes.*; use last_write_time --- CMakeLists.txt | 10 +- src/cache_manager.cc | 7 -- src/cache_manager.h | 8 +- src/clang_indexer.cc | 59 +++++++++- src/clang_utils.cc | 3 + src/command_line.cc | 1 - src/file_consumer.cc | 2 - src/file_consumer.h | 2 +- src/iindexer.cc | 83 ------------- src/iindexer.h | 42 ------- src/import_pipeline.cc | 42 +++++-- src/import_pipeline.h | 19 ++- src/include_complete.cc | 10 -- src/include_complete.h | 1 - src/indexer.h | 37 ++++++ src/lsp_code_action.h | 27 +---- src/messages/ccls_freshen_index.cc | 4 +- src/platform_posix.cc | 22 ---- src/platform_win.cc | 22 ---- src/query.h | 1 - src/standard_includes.cc | 182 ----------------------------- src/standard_includes.h | 4 - src/symbol.h | 2 - src/timestamp_manager.cc | 27 ----- src/timestamp_manager.h | 22 ---- src/utils.cc | 11 ++ src/utils.h | 12 +- 27 files changed, 171 insertions(+), 491 deletions(-) delete mode 100644 src/iindexer.h delete mode 100644 src/standard_includes.cc delete mode 100644 src/standard_includes.h delete mode 100644 src/timestamp_manager.cc delete mode 100644 src/timestamp_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ecb46804..97694a29f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,11 +96,12 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) -if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - target_link_libraries(ccls PRIVATE -lc++experimental) +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + target_link_libraries(ccls PRIVATE -lstdc++fs) elseif(MSVC) else() - target_link_libraries(ccls PRIVATE -lstdc++fs) + # e.g. Darwin, FreeBSD + target_link_libraries(ccls PRIVATE -lc++experimental) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) @@ -212,7 +213,6 @@ target_sources(ccls PRIVATE src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc - src/iindexer.cc src/import_pipeline.cc src/include_complete.cc src/method.cc @@ -229,11 +229,9 @@ target_sources(ccls PRIVATE src/query.cc src/queue_manager.cc src/serializer.cc - src/standard_includes.cc src/test.cc src/third_party_impl.cc src/timer.cc - src/timestamp_manager.cc src/type_printer.cc src/utils.cc src/working_files.cc) diff --git a/src/cache_manager.cc b/src/cache_manager.cc index beb9186b1..d33f66fe6 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -143,10 +143,3 @@ std::unique_ptr ICacheManager::TakeOrLoad(const std::string& path) { assert(result); return result; } - -void ICacheManager::IterateLoadedCaches(std::function fn) { - for (const auto& cache : caches_) { - assert(cache.second); - fn(cache.second.get()); - } -} diff --git a/src/cache_manager.h b/src/cache_manager.h index 0904f0981..920e37195 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -2,7 +2,6 @@ #include -#include #include #include #include @@ -41,8 +40,11 @@ struct ICacheManager { virtual std::optional LoadCachedFileContents( const std::string& path) = 0; - // Iterate over all loaded caches. - void IterateLoadedCaches(std::function fn); + template + void IterateLoadedCaches(Fn fn) { + for (const auto& cache : caches_) + fn(cache.second.get()); + } protected: virtual std::unique_ptr RawCacheLoad(const std::string& path) = 0; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 6c6426b03..8c4d25cd8 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -371,7 +371,7 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { param->seen_files.push_back(file_name); // Set modification time. - std::optional modification_time = GetLastModificationTime(file_name); + std::optional modification_time = LastWriteTime(file_name); LOG_IF_S(ERROR, !modification_time) << "Failed fetching modification time for " << file_name; if (modification_time) @@ -2358,3 +2358,60 @@ void Reflect(Writer& visitor, Reference& value) { Reflect(visitor, value.role); } } + +namespace { + +struct TestIndexer : IIndexer { + static std::unique_ptr FromEntries( + const std::vector& entries) { + auto result = std::make_unique(); + + for (const TestEntry& entry : entries) { + std::vector> indexes; + + if (entry.num_indexes > 0) + indexes.push_back(std::make_unique(entry.path, "")); + for (int i = 1; i < entry.num_indexes; ++i) { + indexes.push_back(std::make_unique( + entry.path + "_extra_" + std::to_string(i) + ".h", "")); + } + + result->indexes.insert(std::make_pair(entry.path, std::move(indexes))); + } + + return result; + } + + ~TestIndexer() override = default; + + std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) override { + auto it = indexes.find(file); + if (it == indexes.end()) { + // Don't return any indexes for unexpected data. + assert(false && "no indexes"); + return {}; + } + + // FIXME: allow user to control how many times we return the index for a + // specific file (atm it is always 1) + auto result = std::move(it->second); + indexes.erase(it); + return result; + } + + std::unordered_map>> + indexes; +}; + +} // namespace + +// static +std::unique_ptr IIndexer::MakeTestIndexer( + std::initializer_list entries) { + return TestIndexer::FromEntries(entries); +} diff --git a/src/clang_utils.cc b/src/clang_utils.cc index b9da4daf6..076850502 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -138,6 +138,8 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { case CXType_Bool: return "bool"; case CXType_Char_U: return "char"; case CXType_UChar: return "unsigned char"; + case CXType_Char16: return "char16_t"; + case CXType_Char32: return "char32_t"; case CXType_UShort: return "unsigned short"; case CXType_UInt: return "unsigned int"; case CXType_ULong: return "unsigned long"; @@ -146,6 +148,7 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { case CXType_Char_S: return "char"; case CXType_SChar: return "signed char"; case CXType_WChar: return "wchar_t"; + case CXType_Short: return "short"; case CXType_Int: return "int"; case CXType_Long: return "long"; case CXType_LongLong: return "long long"; diff --git a/src/command_line.cc b/src/command_line.cc index cea671912..c244811fd 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -21,7 +21,6 @@ #include "serializers/json.h" #include "test.h" #include "timer.h" -#include "timestamp_manager.h" #include "working_files.h" #include diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 796bb9f03..6ba69cfb3 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -29,8 +29,6 @@ bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) { a.data[2] == b.data[2]; } -FileContents::FileContents() : line_offsets_{0} {} - FileContents::FileContents(const std::string& path, const std::string& content) : path(path), content(content) { line_offsets_.push_back(0); diff --git a/src/file_consumer.h b/src/file_consumer.h index 520aa5edb..4f8216a40 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -18,7 +18,7 @@ MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]); bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b); struct FileContents { - FileContents(); + FileContents() = default; FileContents(const std::string& path, const std::string& content); std::optional ToOffset(Position p) const; diff --git a/src/iindexer.cc b/src/iindexer.cc index 7578fa223..e69de29bb 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -1,83 +0,0 @@ -#include "iindexer.h" - -#include "indexer.h" - -namespace { -struct ClangIndexer : IIndexer { - ~ClangIndexer() override = default; - - std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) override { - return Parse(file_consumer_shared, file, args, file_contents, perf, &index); - } - - // Note: constructing this acquires a global lock - ClangIndex index; -}; - -struct TestIndexer : IIndexer { - static std::unique_ptr FromEntries( - const std::vector& entries) { - auto result = std::make_unique(); - - for (const TestEntry& entry : entries) { - std::vector> indexes; - - if (entry.num_indexes > 0) - indexes.push_back(std::make_unique(entry.path, "")); - for (int i = 1; i < entry.num_indexes; ++i) { - indexes.push_back(std::make_unique( - entry.path + "_extra_" + std::to_string(i) + ".h", "")); - } - - result->indexes.insert(std::make_pair(entry.path, std::move(indexes))); - } - - return result; - } - - ~TestIndexer() override = default; - - std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) override { - auto it = indexes.find(file); - if (it == indexes.end()) { - // Don't return any indexes for unexpected data. - assert(false && "no indexes"); - return {}; - } - - // FIXME: allow user to control how many times we return the index for a - // specific file (atm it is always 1) - auto result = std::move(it->second); - indexes.erase(it); - return result; - } - - std::unordered_map>> - indexes; -}; - -} // namespace - -IIndexer::TestEntry::TestEntry(const std::string& path, int num_indexes) - : path(path), num_indexes(num_indexes) {} - -// static -std::unique_ptr IIndexer::MakeClangIndexer() { - return std::make_unique(); -} - -// static -std::unique_ptr IIndexer::MakeTestIndexer( - std::initializer_list entries) { - return TestIndexer::FromEntries(entries); -} diff --git a/src/iindexer.h b/src/iindexer.h deleted file mode 100644 index 84b73a847..000000000 --- a/src/iindexer.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -// TODO: -// - rename indexer.h to clang_indexer.h and pull out non-clang specific code -// like IndexFile -// - rename this file to indexer.h - -struct IndexFile; -struct FileContents; -struct FileConsumerSharedState; -struct PerformanceImportFile; - -// Abstracts away the actual indexing process. Each IIndexer instance is -// per-thread and constructing an instance may be extremely expensive (ie, -// acquire a lock) and should be done as rarely as possible. -struct IIndexer { - struct TestEntry { - std::string path; - int num_indexes = 0; - - TestEntry(const std::string& path, int num_indexes); - }; - - static std::unique_ptr MakeClangIndexer(); - static std::unique_ptr MakeTestIndexer( - std::initializer_list entries); - - virtual ~IIndexer() = default; - virtual std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) = 0; -}; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index cea5ad6e7..f970e92b3 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -3,7 +3,6 @@ #include "cache_manager.h" #include "config.h" #include "diagnostics_engine.h" -#include "iindexer.h" #include "import_manager.h" #include "lsp.h" #include "message_handler.h" @@ -12,15 +11,11 @@ #include "query_utils.h" #include "queue_manager.h" #include "timer.h" -#include "timestamp_manager.h" #include #include -#include #include -#include -#include namespace { @@ -63,14 +58,14 @@ struct IterationLoop { struct IModificationTimestampFetcher { virtual ~IModificationTimestampFetcher() = default; - virtual std::optional GetModificationTime(const std::string& path) = 0; + virtual std::optional LastWriteTime(const std::string& path) = 0; }; struct RealModificationTimestampFetcher : IModificationTimestampFetcher { ~RealModificationTimestampFetcher() override = default; // IModificationTimestamp: - std::optional GetModificationTime(const std::string& path) override { - return GetLastModificationTime(path); + std::optional LastWriteTime(const std::string& path) override { + return ::LastWriteTime(path); } }; struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { @@ -79,7 +74,7 @@ struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { ~FakeModificationTimestampFetcher() override = default; // IModificationTimestamp: - std::optional GetModificationTime(const std::string& path) override { + std::optional LastWriteTime(const std::string& path) override { auto it = entries.find(path); assert(it != entries.end()); return it->second; @@ -174,7 +169,7 @@ ShouldParse FileNeedsParse( } std::optional modification_timestamp = - modification_timestamp_fetcher->GetModificationTime(path); + modification_timestamp_fetcher->LastWriteTime(path); // Cannot find file. if (!modification_timestamp) @@ -327,7 +322,7 @@ std::vector PreloadFileContents( // still valid. if so, we can use it, otherwise we need to load from disk. auto get_latest_content = [](const std::string& path, int64_t cached_time, const std::string& cached) -> std::string { - std::optional mod_time = GetLastModificationTime(path); + std::optional mod_time = LastWriteTime(path); if (!mod_time) return ""; @@ -533,6 +528,29 @@ bool IndexMergeIndexUpdates() { } // namespace +std::optional TimestampManager::GetLastCachedModificationTime( + ICacheManager* cache_manager, + const std::string& path) { + { + std::lock_guard guard(mutex_); + auto it = timestamps_.find(path); + if (it != timestamps_.end()) + return it->second; + } + IndexFile* file = cache_manager->TryLoad(path); + if (!file) + return std::nullopt; + + UpdateCachedModificationTime(path, file->last_modification_time); + return file->last_modification_time; +} + +void TimestampManager::UpdateCachedModificationTime(const std::string& path, + int64_t timestamp) { + std::lock_guard guard(mutex_); + timestamps_[path] = timestamp; +} + ImportPipelineStatus::ImportPipelineStatus() : num_active_threads(0), next_progress_output(0) {} @@ -586,7 +604,7 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, RealModificationTimestampFetcher modification_timestamp_fetcher; auto* queue = QueueManager::instance(); // Build one index per-indexer, as building the index acquires a global lock. - auto indexer = IIndexer::MakeClangIndexer(); + auto indexer = std::make_unique(); while (true) { bool did_work = false; diff --git a/src/import_pipeline.h b/src/import_pipeline.h index f7e750f9c..5a0fbc4e0 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -5,20 +5,37 @@ #include #include +#include #include +#include +#include #include struct ClangTranslationUnit; class DiagnosticsEngine; struct FileConsumerSharedState; +struct ICacheManager; struct ImportManager; struct MultiQueueWaiter; struct Project; struct QueryDatabase; struct SemanticHighlightSymbolCache; -struct TimestampManager; struct WorkingFiles; +// Caches timestamps of cc files so we can avoid a filesystem reads. This is +// important for import perf, as during dependency checking the same files are +// checked over and over again if they are common headers. +struct TimestampManager { + std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, + const std::string& path); + + void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); + + // TODO: use std::shared_mutex so we can have multiple readers. + std::mutex mutex_; + std::unordered_map timestamps_; +}; + struct ImportPipelineStatus { std::atomic num_active_threads; std::atomic next_progress_output; diff --git a/src/include_complete.cc b/src/include_complete.cc index 4bedad394..f5ea1fc3c 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -4,7 +4,6 @@ #include "match.h" #include "platform.h" #include "project.h" -#include "standard_includes.h" #include "timer.h" #include @@ -107,7 +106,6 @@ void IncludeComplete::Rescan() { SetThreadName("scan_includes"); Timer timer; - InsertStlIncludes(); InsertIncludesFromDirectory(g_config->projectRoot, false /*use_angle_brackets*/); for (const std::string& dir : project_->quote_include_directories) @@ -189,14 +187,6 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, std::move(result.completion_item)); } -void IncludeComplete::InsertStlIncludes() { - std::lock_guard lock(completion_items_mutex); - for (const char* stl_header : kStandardLibraryIncludes) { - completion_items.push_back(BuildCompletionItem( - stl_header, true /*use_angle_brackets*/, true /*is_stl*/)); - } -} - std::optional IncludeComplete::FindCompletionItemForAbsolutePath( const std::string& absolute_path) { std::lock_guard lock(completion_items_mutex); diff --git a/src/include_complete.h b/src/include_complete.h index 9cbee1abb..c45c25622 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -22,7 +22,6 @@ struct IncludeComplete { // blocking function and should be run off the querydb thread. void InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets); - void InsertStlIncludes(); std::optional FindCompletionItemForAbsolutePath( const std::string& absolute_path); diff --git a/src/indexer.h b/src/indexer.h index 43035a6b4..7b46b4e8a 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -488,3 +488,40 @@ std::vector> ParseWithTu( bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); + +// Abstracts away the actual indexing process. Each IIndexer instance is +// per-thread and constructing an instance may be extremely expensive (ie, +// acquire a lock) and should be done as rarely as possible. +struct IIndexer { + struct TestEntry { + std::string path; + int num_indexes = 0; + }; + + static std::unique_ptr MakeTestIndexer( + std::initializer_list entries); + + virtual ~IIndexer() = default; + virtual std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) = 0; +}; + +struct ClangIndexer : IIndexer { + ~ClangIndexer() override = default; + + std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) override { + return Parse(file_consumer_shared, file, args, file_contents, perf, &index); + } + + // Note: constructing this acquires a global lock + ClangIndex index; +}; diff --git a/src/lsp_code_action.h b/src/lsp_code_action.h index 44aa13814..2fbc5f4a6 100644 --- a/src/lsp_code_action.h +++ b/src/lsp_code_action.h @@ -18,29 +18,4 @@ struct lsCodeLensCommandArguments { lsPosition position; std::vector locations; }; - -// FIXME Don't use array in vscode-ccls -inline void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) { - visitor.StartArray(3); - Reflect(visitor, value.uri); - Reflect(visitor, value.position); - Reflect(visitor, value.locations); - visitor.EndArray(); -} - -inline void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) { - int i = 0; - visitor.IterArray([&](Reader& visitor) { - switch (i++) { - case 0: - Reflect(visitor, value.uri); - break; - case 1: - Reflect(visitor, value.position); - break; - case 2: - Reflect(visitor, value.locations); - break; - } - }); -} +MAKE_REFLECT_STRUCT(lsCodeLensCommandArguments, uri, position, locations) diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 91d0bc007..1989578dc 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -1,11 +1,11 @@ #include "cache_manager.h" +#include "import_pipeline.h" #include "match.h" #include "message_handler.h" #include "platform.h" #include "project.h" #include "queue_manager.h" #include "timer.h" -#include "timestamp_manager.h" #include "working_files.h" #include @@ -66,7 +66,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { need_index.insert(file->def->path); std::optional modification_timestamp = - GetLastModificationTime(file->def->path); + LastWriteTime(file->def->path); if (!modification_timestamp) continue; std::optional cached_modification = diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 4e9b952f6..aba1b7f0f 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -166,28 +166,6 @@ void SetThreadName(const std::string& thread_name) { #endif } -std::optional GetLastModificationTime(const std::string& absolute_path) { - struct stat buf; - if (stat(absolute_path.c_str(), &buf) != 0) { - switch (errno) { - case ENOENT: - // std::cerr << "GetLastModificationTime: unable to find file " << - // absolute_path << std::endl; - return std::nullopt; - case EINVAL: - // std::cerr << "GetLastModificationTime: invalid param to _stat for - // file file " << absolute_path << std::endl; - return std::nullopt; - default: - // std::cerr << "GetLastModificationTime: unhandled for " << - // absolute_path << std::endl; exit(1); - return std::nullopt; - } - } - - return buf.st_mtime; -} - void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); diff --git a/src/platform_win.cc b/src/platform_win.cc index f4c71a959..471c73be0 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -79,28 +79,6 @@ void SetThreadName(const std::string& thread_name) { } } -std::optional GetLastModificationTime(const std::string& absolute_path) { - struct _stat buf; - if (_stat(absolute_path.c_str(), &buf) != 0) { - switch (errno) { - case ENOENT: - // std::cerr << "GetLastModificationTime: unable to find file " << - // absolute_path << std::endl; - return std::nullopt; - case EINVAL: - // std::cerr << "GetLastModificationTime: invalid param to _stat for - // file file " << absolute_path << std::endl; - return std::nullopt; - default: - // std::cerr << "GetLastModificationTime: unhandled for " << - // absolute_path << std::endl; exit(1); - return std::nullopt; - } - } - - return buf.st_mtime; -} - void FreeUnusedMemory() {} // TODO Wait for debugger to attach diff --git a/src/query.h b/src/query.h index e5cdd7198..f75ad5514 100644 --- a/src/query.h +++ b/src/query.h @@ -6,7 +6,6 @@ #include #include -#include struct QueryFile; struct QueryType; diff --git a/src/standard_includes.cc b/src/standard_includes.cc deleted file mode 100644 index 43a67c301..000000000 --- a/src/standard_includes.cc +++ /dev/null @@ -1,182 +0,0 @@ -#include "standard_includes.h" - -// See http://stackoverflow.com/a/2029106. -const char* kStandardLibraryIncludes[177] = { - "aio.h", - "algorithm", - "any", - "arpa/inet.h", - "array", - "assert.h", - "atomic", - "bitset", - "cassert", - "ccomplex", - "cctype", - "cerrno", - "cfenv", - "cfloat", - "chrono", - "cinttypes", - "ciso646", - "climits", - "clocale", - "cmath", - "codecvt", - "complex", - "complex.h", - "condition_variable", - "cpio.h", - "csetjmp", - "csignal", - "cstdalign", - "cstdarg", - "cstdbool", - "cstddef", - "cstdint", - "cstdio", - "cstdlib", - "cstring", - "ctgmath", - "ctime", - "ctype.h", - "cuchar", - "curses.h", - "cwchar", - "cwctype", - "deque", - "dirent.h", - "dlfcn.h", - "errno.h", - "exception", - "execution", - "fcntl.h", - "fenv.h", - "filesystem", - "float.h", - "fmtmsg.h", - "fnmatch.h", - "forward_list", - "fstream", - "ftw.h", - "functional", - "future", - "glob.h", - "grp.h", - "iconv.h", - "initializer_list", - "inttypes.h", - "iomanip", - "ios", - "iosfwd", - "iostream", - "iso646.h", - "istream", - "iterator", - "langinfo.h", - "libgen.h", - "limits", - "limits.h", - "list", - "locale", - "locale.h", - "map", - "math.h", - "memory", - "memory_resource", - "monetary.h", - "mqueue.h", - "mutex", - "ndbm.h", - "net/if.h", - "netdb.h", - "netinet/in.h", - "netinet/tcp.h", - "new", - "nl_types.h", - "numeric", - "std::optional", - "ostream", - "poll.h", - "pthread.h", - "pwd.h", - "queue", - "random", - "ratio", - "regex", - "regex.h", - "sched.h", - "scoped_allocator", - "search.h", - "semaphore.h", - "set", - "setjmp.h", - "shared_mutex", - "signal.h", - "spawn.h", - "sstream", - "stack", - "stdalign.h", - "stdarg.h", - "stdatomic.h", - "stdbool.h", - "stddef.h", - "stdexcept", - "stdint.h", - "stdio.h", - "stdlib.h", - "stdnoreturn.h", - "streambuf", - "string", - "string.h", - "string_view", - "strings.h", - "stropts.h", - "strstream", - "sys/ipc.h", - "sys/mman.h", - "sys/msg.h", - "sys/resource.h", - "sys/select.h", - "sys/sem.h", - "sys/shm.h", - "sys/socket.h", - "sys/stat.h", - "sys/statvfs.h", - "sys/time.h", - "sys/times.h", - "sys/types.h", - "sys/uio.h", - "sys/un.h", - "sys/utsname.h", - "sys/wait.h", - "syslog.h", - "system_error", - "tar.h", - "term.h", - "termios.h", - "tgmath.h", - "thread", - "threads.h", - "time.h", - "trace.h", - "tuple", - "type_traits", - "typeindex", - "typeinfo", - "uchar.h", - "ulimit.h", - "uncntrl.h", - "unistd.h", - "unordered_map", - "unordered_set", - "utility", - "utime.h", - "utmpx.h", - "valarray", - "variant", - "vector", - "wchar.h", - "wctype.h", - "wordexp.h", -}; \ No newline at end of file diff --git a/src/standard_includes.h b/src/standard_includes.h deleted file mode 100644 index 6c50227d1..000000000 --- a/src/standard_includes.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -// A set of standard libary header names, ie, "vector". -extern const char* kStandardLibraryIncludes[177]; \ No newline at end of file diff --git a/src/symbol.h b/src/symbol.h index 54a09272e..13b9f39ac 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -7,7 +7,6 @@ // front of others. enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; MAKE_REFLECT_TYPE_PROXY(SymbolKind); -MAKE_ENUM_HASHABLE(SymbolKind); // clang/Basic/Specifiers.h clang::StorageClass enum class StorageClass : uint8_t { @@ -44,7 +43,6 @@ enum class Role : uint16_t { All = (1 << 9) - 1, }; MAKE_REFLECT_TYPE_PROXY(Role); -MAKE_ENUM_HASHABLE(Role); inline uint16_t operator&(Role lhs, Role rhs) { return uint16_t(lhs) & uint16_t(rhs); diff --git a/src/timestamp_manager.cc b/src/timestamp_manager.cc deleted file mode 100644 index 77f69accd..000000000 --- a/src/timestamp_manager.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "timestamp_manager.h" - -#include "cache_manager.h" -#include "indexer.h" - -std::optional TimestampManager::GetLastCachedModificationTime( - ICacheManager* cache_manager, - const std::string& path) { - { - std::lock_guard guard(mutex_); - auto it = timestamps_.find(path); - if (it != timestamps_.end()) - return it->second; - } - IndexFile* file = cache_manager->TryLoad(path); - if (!file) - return std::nullopt; - - UpdateCachedModificationTime(path, file->last_modification_time); - return file->last_modification_time; -} - -void TimestampManager::UpdateCachedModificationTime(const std::string& path, - int64_t timestamp) { - std::lock_guard guard(mutex_); - timestamps_[path] = timestamp; -} diff --git a/src/timestamp_manager.h b/src/timestamp_manager.h deleted file mode 100644 index ac02b10fc..000000000 --- a/src/timestamp_manager.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include -#include - -struct ICacheManager; - -// Caches timestamps of cc files so we can avoid a filesystem reads. This is -// important for import perf, as during dependency checking the same files are -// checked over and over again if they are common headers. -struct TimestampManager { - std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, - const std::string& path); - - void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); - - // TODO: use std::shared_mutex so we can have multiple readers. - std::mutex mutex_; - std::unordered_map timestamps_; -}; \ No newline at end of file diff --git a/src/utils.cc b/src/utils.cc index eb8fb6a38..c9d05a8d3 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,6 @@ #include "utils.h" +#include "filesystem.hh" #include "platform.h" #include @@ -130,6 +131,7 @@ std::optional ReadContent(const std::string& filename) { size_t n; while ((n = fread(buf, 1, sizeof buf, f)) > 0) ret.append(buf, n); + fclose(f); return ret; } @@ -142,6 +144,15 @@ void WriteToFile(const std::string& filename, const std::string& content) { fclose(f); } +std::optional LastWriteTime(const std::string& filename) { + std::error_code ec; + auto ftime = fs::last_write_time(filename, ec); + if (ec) return std::nullopt; + return std::chrono::time_point_cast(ftime) + .time_since_epoch() + .count(); +} + std::string GetDefaultResourceDirectory() { std::string result; diff --git a/src/utils.h b/src/utils.h index 6b117d051..3c49bab88 100644 --- a/src/utils.h +++ b/src/utils.h @@ -62,8 +62,8 @@ void EnsureEndsInSlash(std::string& path); std::string EscapeFileName(std::string path); std::optional ReadContent(const std::string& filename); - void WriteToFile(const std::string& filename, const std::string& content); +std::optional LastWriteTime(const std::string& filename); // http://stackoverflow.com/a/38140932 // @@ -95,14 +95,4 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { }; \ } -#define MAKE_ENUM_HASHABLE(type) \ - namespace std { \ - template <> \ - struct hash { \ - std::size_t operator()(const type& t) const { \ - return hash()(static_cast(t)); \ - } \ - }; \ - } - std::string GetDefaultResourceDirectory(); From 01f10645764cdbed48e899da254325ba3ffe91b8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 29 Apr 2018 19:51:25 -0700 Subject: [PATCH 083/378] Improve workspace/symbol sorting heuristic --- src/clang_indexer.cc | 2 + src/iindexer.cc | 0 src/lex_utils.cc | 47 +++------- src/lex_utils.h | 5 +- src/messages/text_document_completion.cc | 5 +- src/messages/workspace_symbol.cc | 105 +++++++++-------------- 6 files changed, 64 insertions(+), 100 deletions(-) delete mode 100644 src/iindexer.cc diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 8c4d25cd8..2c2ce6334 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -354,6 +354,8 @@ struct IndexParam { }; IndexFile* ConsumeFile(IndexParam* param, CXFile file) { + if (!file) + return nullptr; bool is_first_ownership = false; IndexFile* db = param->file_consumer->TryConsumeFile( file, &is_first_ownership, ¶m->file_contents); diff --git a/src/iindexer.cc b/src/iindexer.cc deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/lex_utils.cc b/src/lex_utils.cc index 6045eb9da..9380f723f 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -49,21 +49,20 @@ std::string_view LexIdentifierAroundPos(lsPosition position, // Find discontinous |search| in |content|. // Return |found| and the count of skipped chars before found. -std::pair CaseFoldingSubsequenceMatch(std::string_view search, - std::string_view content) { - bool hasUppercaseLetter = std::any_of(search.begin(), search.end(), isupper); - int skip = 0; - size_t j = 0; - for (char c : search) { - while (j < content.size() && - (hasUppercaseLetter ? content[j] != c - : tolower(content[j]) != tolower(c))) - ++j, ++skip; - if (j == content.size()) - return {false, skip}; - ++j; - } - return {true, skip}; +int ReverseSubseqMatch(std::string_view pat, + std::string_view text, + int case_sensitivity) { + if (case_sensitivity == 1) + case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0; + int j = pat.size(); + if (!j) + return text.size(); + for (int i = text.size(); i--;) + if ((case_sensitivity ? text[i] == pat[j - 1] + : tolower(text[i]) == tolower(pat[j - 1])) && + !--j) + return i; + return -1; } TEST_SUITE("Offset") { @@ -86,21 +85,3 @@ TEST_SUITE("Offset") { REQUIRE(GetOffsetForPosition(lsPosition{0, 1}, "a") == 1); } } - -TEST_SUITE("Substring") { - TEST_CASE("skip") { - REQUIRE(CaseFoldingSubsequenceMatch("a", "a") == std::make_pair(true, 0)); - REQUIRE(CaseFoldingSubsequenceMatch("b", "a") == std::make_pair(false, 1)); - REQUIRE(CaseFoldingSubsequenceMatch("", "") == std::make_pair(true, 0)); - REQUIRE(CaseFoldingSubsequenceMatch("a", "ba") == std::make_pair(true, 1)); - REQUIRE(CaseFoldingSubsequenceMatch("aa", "aba") == - std::make_pair(true, 1)); - REQUIRE(CaseFoldingSubsequenceMatch("aa", "baa") == - std::make_pair(true, 1)); - REQUIRE(CaseFoldingSubsequenceMatch("aA", "aA") == std::make_pair(true, 0)); - REQUIRE(CaseFoldingSubsequenceMatch("aA", "aa") == - std::make_pair(false, 1)); - REQUIRE(CaseFoldingSubsequenceMatch("incstdioh", "include ") == - std::make_pair(true, 7)); - } -} diff --git a/src/lex_utils.h b/src/lex_utils.h index 13d6a043c..4206a1204 100644 --- a/src/lex_utils.h +++ b/src/lex_utils.h @@ -11,5 +11,6 @@ int GetOffsetForPosition(lsPosition position, std::string_view content); std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content); -std::pair CaseFoldingSubsequenceMatch(std::string_view search, - std::string_view content); +int ReverseSubseqMatch(std::string_view pat, + std::string_view text, + int case_sensitivity); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index e67d60833..a08205499 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -214,10 +214,11 @@ void FilterAndSortCompletionResponse( } // Fuzzy match and remove awful candidates. - FuzzyMatcher fuzzy(complete_text, g_config->completion.caseSensitivity); + bool sensitive = g_config->completion.caseSensitivity; + FuzzyMatcher fuzzy(complete_text, sensitive); for (auto& item : items) { item.score_ = - CaseFoldingSubsequenceMatch(complete_text, *item.filterText).first + ReverseSubseqMatch(complete_text, *item.filterText, sensitive) >= 0 ? fuzzy.Match(*item.filterText) : FuzzyMatcher::kMinScore; } diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index e138d4a79..910cfdabc 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -15,10 +15,13 @@ namespace { MethodType kMethodType = "workspace/symbol"; // Lookup |symbol| in |db| and insert the value into |result|. -bool InsertSymbolIntoResult(QueryDatabase* db, - WorkingFiles* working_files, - SymbolIdx symbol, - std::vector* result) { +bool AddSymbol( + QueryDatabase* db, + WorkingFiles* working_files, + int i, + bool use_detailed, + std::vector>* result) { + SymbolIdx symbol = db->symbols[i]; std::optional info = GetSymbolInfo(db, working_files, symbol, true); if (!info) @@ -38,7 +41,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db, if (!ls_location) return false; info->location = *ls_location; - result->push_back(*info); + result->emplace_back(*info, use_detailed, i); return true; } @@ -72,82 +75,58 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { std::string query = request->params.query; - std::unordered_set inserted_results; - // db->detailed_names indices of each lsSymbolInformation in out.result - std::vector result_indices; - std::vector unsorted_results; - inserted_results.reserve(g_config->workspaceSymbol.maxNum); - result_indices.reserve(g_config->workspaceSymbol.maxNum); + // {symbol info, matching detailed_name or short_name, index} + std::vector> unsorted; + bool sensitive = g_config->workspaceSymbol.caseSensitivity; - // We use detailed_names without parameters for matching. + // Find subsequence matches. + std::string query_without_space; + query_without_space.reserve(query.size()); + for (char c : query) + if (!isspace(c)) + query_without_space += c; - // Find exact substring matches. - for (int i = 0; i < db->symbols.size(); ++i) { + for (int i = 0; i < (int)db->symbols.size(); ++i) { std::string_view detailed_name = db->GetSymbolName(i, true); - if (detailed_name.find(query) != std::string::npos) { - // Do not show the same entry twice. - if (!inserted_results.insert(std::string(detailed_name)).second) - continue; - - if (InsertSymbolIntoResult(db, working_files, db->symbols[i], - &unsorted_results)) { - result_indices.push_back(i); - if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum) - break; - } - } - } - - // Find subsequence matches. - if (unsorted_results.size() < g_config->workspaceSymbol.maxNum) { - std::string query_without_space; - query_without_space.reserve(query.size()); - for (char c : query) - if (!isspace(c)) - query_without_space += c; - - for (int i = 0; i < (int)db->symbols.size(); ++i) { - std::string_view detailed_name = db->GetSymbolName(i, true); - if (CaseFoldingSubsequenceMatch(query_without_space, detailed_name) - .first) { - // Do not show the same entry twice. - if (!inserted_results.insert(std::string(detailed_name)).second) - continue; - - if (InsertSymbolIntoResult(db, working_files, db->symbols[i], - &unsorted_results)) { - result_indices.push_back(i); - if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum) - break; - } - } - } + int pos = + ReverseSubseqMatch(query_without_space, detailed_name, sensitive); + if (pos >= 0 && + AddSymbol(db, working_files, i, + detailed_name.find(':', pos) != std::string::npos, + &unsorted) && + unsorted.size() >= g_config->workspaceSymbol.maxNum) + break; } if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { // Sort results with a fuzzy matching algorithm. int longest = 0; - for (int i : result_indices) - longest = std::max(longest, int(db->GetSymbolName(i, true).size())); + for (int i = 0; i < int(unsorted.size()); i++) { + longest = std::max( + longest, + int(db->GetSymbolName(std::get<2>(unsorted[i]), true).size())); + } FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); - std::vector> permutation(result_indices.size()); - for (int i = 0; i < int(result_indices.size()); i++) { + std::vector> permutation(unsorted.size()); + for (int i = 0; i < int(unsorted.size()); i++) { permutation[i] = { - fuzzy.Match(db->GetSymbolName(result_indices[i], true)), i}; + fuzzy.Match(db->GetSymbolName(std::get<2>(unsorted[i]), + std::get<1>(unsorted[i]))), + i}; } std::sort(permutation.begin(), permutation.end(), std::greater>()); - out.result.reserve(result_indices.size()); + out.result.reserve(unsorted.size()); // Discard awful candidates. - for (int i = 0; i < int(result_indices.size()) && + for (int i = 0; i < int(unsorted.size()) && permutation[i].first > FuzzyMatcher::kMinScore; i++) out.result.push_back( - std::move(unsorted_results[permutation[i].second])); + std::move(std::get<0>(unsorted[permutation[i].second]))); } else { - out.result.reserve(unsorted_results.size()); - for (const auto& entry : unsorted_results) - out.result.push_back(std::move(entry)); + out.result.reserve(unsorted.size()); + for (auto& entry : unsorted) + out.result.push_back(std::get<0>(entry)); } LOG_S(INFO) << "[querydb] Found " << out.result.size() From fac5c56682cc9ffa82008d14e0eb0993120273b0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 29 Apr 2018 21:49:03 -0700 Subject: [PATCH 084/378] Use usr as primary key and remove id; simplify import pipeline Remove on_id_map, IndexMergeIndexUpdates --- index_tests/_empty_test.cc | 6 +- index_tests/class_forward_declaration.cc | 14 +- index_tests/constructors/constructor.cc | 77 +- index_tests/constructors/destructor.cc | 93 +- .../constructors/implicit_constructor.cc | 91 +- index_tests/constructors/invalid_reference.cc | 47 +- index_tests/constructors/make_functions.cc | 370 ++++--- .../declaration_vs_definition/class.cc | 14 +- .../declaration_vs_definition/class_member.cc | 45 +- .../class_member_static.cc | 51 +- index_tests/declaration_vs_definition/func.cc | 23 +- .../func_associated_function_params.cc | 77 +- .../declaration_vs_definition/method.cc | 68 +- index_tests/enums/enum_class_decl.cc | 37 +- index_tests/enums/enum_decl.cc | 26 +- index_tests/enums/enum_inherit.cc | 79 +- index_tests/enums/enum_usage.cc | 59 +- index_tests/foobar.cc | 90 +- index_tests/function_declaration.cc | 13 +- .../function_declaration_definition.cc | 17 +- index_tests/function_definition.cc | 12 +- index_tests/inheritance/class_inherit.cc | 26 +- .../class_inherit_templated_parent.cc | 157 ++- .../inheritance/class_multiple_inherit.cc | 78 +- index_tests/inheritance/function_override.cc | 95 +- .../inheritance/interface_pure_virtual.cc | 46 +- .../inheritance/multiple_base_functions.cc | 157 ++- index_tests/lambdas/lambda.cc | 115 ++- index_tests/macros/complex.cc | 84 +- index_tests/macros/foo.cc | 114 ++- index_tests/method_declaration.cc | 46 +- index_tests/method_definition.cc | 52 +- index_tests/method_inline_declaration.cc | 47 +- index_tests/multi_file/funky_enum.cc | 57 +- index_tests/multi_file/impl.cc | 224 ++--- index_tests/multi_file/simple_impl.cc | 31 +- index_tests/multi_file/static.cc | 85 +- index_tests/namespaces/anonymous_function.cc | 42 +- .../namespaces/function_declaration.cc | 56 +- index_tests/namespaces/function_definition.cc | 57 +- index_tests/namespaces/method_declaration.cc | 80 +- index_tests/namespaces/method_definition.cc | 88 +- .../namespaces/method_inline_declaration.cc | 81 +- index_tests/namespaces/namespace_alias.cc | 189 ++-- index_tests/namespaces/namespace_reference.cc | 147 ++- index_tests/operators/operator.cc | 88 +- .../outline/static_function_in_type.cc | 190 ++-- index_tests/preprocessor/include_guard.cc | 14 +- index_tests/preprocessor/skipped.cc | 6 +- .../func_specialized_template_param.cc | 74 +- .../implicit_variable_instantiation.cc | 141 ++- .../templates/member_ref_in_template.cc | 94 +- ...ass_template_func_usage_folded_into_one.cc | 127 ++- ...ace_template_type_usage_folded_into_one.cc | 64 +- index_tests/templates/specialization.cc | 477 +++++---- .../templates/specialized_func_definition.cc | 70 +- ...mplate_class_func_usage_folded_into_one.cc | 91 +- ...ass_template_func_usage_folded_into_one.cc | 91 +- ...mplate_class_type_usage_folded_into_one.cc | 82 +- ...emplate_class_var_usage_folded_into_one.cc | 79 +- .../template_func_usage_folded_into_one.cc | 72 +- .../template_type_usage_folded_into_one.cc | 46 +- .../template_var_usage_folded_into_one.cc | 86 +- index_tests/types/anonymous_struct.cc | 92 +- index_tests/types/typedefs.cc | 64 +- index_tests/unions/union_decl.cc | 72 +- index_tests/unions/union_usage.cc | 119 ++- .../usage/func_called_from_constructor.cc | 62 +- .../usage/func_called_from_macro_argument.cc | 31 +- .../usage/func_called_from_template.cc | 47 +- .../usage/func_called_implicit_ctor.cc | 84 +- index_tests/usage/func_usage_addr_func.cc | 64 +- index_tests/usage/func_usage_addr_method.cc | 78 +- index_tests/usage/func_usage_call_func.cc | 22 +- index_tests/usage/func_usage_call_method.cc | 81 +- .../usage/func_usage_class_inline_var_def.cc | 71 +- .../usage/func_usage_forward_decl_func.cc | 23 +- .../usage/func_usage_forward_decl_method.cc | 81 +- index_tests/usage/func_usage_template_func.cc | 65 +- .../usage/type_usage_as_template_parameter.cc | 89 +- ...ype_usage_as_template_parameter_complex.cc | 204 ++-- ...type_usage_as_template_parameter_simple.cc | 29 +- .../usage/type_usage_declare_extern.cc | 21 +- index_tests/usage/type_usage_declare_field.cc | 60 +- index_tests/usage/type_usage_declare_local.cc | 100 +- index_tests/usage/type_usage_declare_param.cc | 100 +- .../type_usage_declare_param_prototype.cc | 58 +- .../usage/type_usage_declare_param_unnamed.cc | 42 +- .../usage/type_usage_declare_qualifiers.cc | 144 ++- .../usage/type_usage_declare_static.cc | 23 +- .../usage/type_usage_on_return_type.cc | 162 ++- .../usage/type_usage_typedef_and_using.cc | 222 ++--- .../type_usage_typedef_and_using_template.cc | 48 +- index_tests/usage/type_usage_various.cc | 82 +- index_tests/usage/usage_inside_of_call.cc | 165 ++- .../usage/usage_inside_of_call_simple.cc | 49 +- index_tests/usage/var_usage_call_function.cc | 34 +- index_tests/usage/var_usage_class_member.cc | 153 ++- .../usage/var_usage_class_member_static.cc | 94 +- index_tests/usage/var_usage_cstyle_cast.cc | 35 +- index_tests/usage/var_usage_extern.cc | 49 +- index_tests/usage/var_usage_func_parameter.cc | 51 +- index_tests/usage/var_usage_local.cc | 53 +- index_tests/usage/var_usage_shadowed_local.cc | 64 +- .../usage/var_usage_shadowed_parameter.cc | 68 +- index_tests/usage/var_usage_static.cc | 51 +- index_tests/vars/class_member.cc | 25 +- index_tests/vars/class_static_member.cc | 27 +- .../vars/class_static_member_decl_only.cc | 39 +- index_tests/vars/deduce_auto_type.cc | 66 +- index_tests/vars/function_local.cc | 53 +- index_tests/vars/function_param.cc | 70 +- index_tests/vars/function_param_unnamed.cc | 12 +- index_tests/vars/function_shadow_local.cc | 64 +- index_tests/vars/function_shadow_param.cc | 58 +- index_tests/vars/global_variable.cc | 17 +- index_tests/vars/global_variable_decl_only.cc | 15 +- .../vars/type_instance_on_using_type.cc | 66 +- src/cache_manager.cc | 6 - src/cache_manager.h | 4 - src/clang_indexer.cc | 622 +++++------- src/command_line.cc | 12 +- src/import_manager.h | 17 - src/import_pipeline.cc | 279 ++---- src/import_pipeline.h | 3 - src/indexer.h | 327 +++--- src/message_handler.cc | 14 +- src/message_handler.h | 2 +- src/messages/ccls_base.cc | 8 +- src/messages/ccls_call_hierarchy.cc | 49 +- src/messages/ccls_derived.cc | 8 +- src/messages/ccls_file_info.cc | 1 - src/messages/ccls_inheritance_hierarchy.cc | 41 +- src/messages/ccls_member_hierarchy.cc | 120 ++- src/messages/ccls_random.cc | 75 +- src/messages/ccls_vars.cc | 15 +- src/messages/initialize.cc | 2 +- src/messages/text_document_code_lens.cc | 19 +- src/messages/text_document_definition.cc | 8 +- .../text_document_document_highlight.cc | 4 +- src/messages/text_document_document_symbol.cc | 4 +- src/messages/text_document_rename.cc | 8 +- src/messages/text_document_type_definition.cc | 8 +- src/performance.h | 5 +- src/platform_posix.cc | 5 +- src/query.cc | 940 ++++++------------ src/query.h | 221 ++-- src/query_utils.cc | 86 +- src/query_utils.h | 39 +- src/queue_manager.cc | 33 +- src/queue_manager.h | 40 +- src/serializer.cc | 30 +- src/serializer.h | 22 + src/test.cc | 2 +- 154 files changed, 5447 insertions(+), 6805 deletions(-) delete mode 100644 src/import_manager.h diff --git a/index_tests/_empty_test.cc b/index_tests/_empty_test.cc index 237e15534..87accc882 100644 --- a/index_tests/_empty_test.cc +++ b/index_tests/_empty_test.cc @@ -3,8 +3,8 @@ { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [], - "vars": [] + "usr2func": [], + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index 231a7c445..297282989 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -8,16 +8,17 @@ class Foo; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, - "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], - "spell": "3:7-3:10|-1|1|2", - "extent": "3:1-3:13|-1|1|0", + "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], + "spell": "3:7-3:10|0|1|2", + "extent": "3:1-3:13|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -26,7 +27,6 @@ class Foo; "instances": [], "uses": [] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index 8e26369d0..a6affdf3c 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -13,26 +13,7 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": ["3:3-3:6|-1|1|4"], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-4:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [0, 1], - "uses": ["3:3-3:6|0|2|4", "7:3-7:6|-1|1|4", "8:3-8:6|-1|1|4", "8:17-8:20|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", "qual_name_offset": 5, @@ -40,16 +21,15 @@ void foo() { "kind": 9, "storage": 1, "declarations": [], - "spell": "3:3-3:6|0|2|2", - "extent": "3:3-3:11|0|2|0", - "declaring_type": 0, + "spell": "3:3-3:6|15041163540773201510|2|2", + "extent": "3:3-3:11|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|1|3|288", "8:17-8:20|1|3|32"], + "uses": ["7:7-7:8|4259594751088586730|3|288", "8:17-8:20|4259594751088586730|3|32"], "callees": [] }, { - "id": 1, "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, @@ -57,38 +37,55 @@ void foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "6:6-6:9|-1|1|2", - "extent": "6:1-9:2|-1|1|0", + "spell": "6:6-6:9|0|1|2", + "extent": "6:1-9:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0, 1], + "vars": [10983126130596230582, 17165811951126099095], "uses": [], - "callees": ["7:7-7:8|0|3|288", "7:7-7:8|0|3|288", "8:17-8:20|0|3|32", "8:17-8:20|0|3|32"] + "callees": ["7:7-7:8|3385168158331140247|3|288", "7:7-7:8|3385168158331140247|3|288", "8:17-8:20|3385168158331140247|3|32", "8:17-8:20|3385168158331140247|3|32"] + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": ["3:3-3:6|0|1|4"], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [3385168158331140247], + "vars": [], + "instances": [10983126130596230582, 17165811951126099095], + "uses": ["3:3-3:6|15041163540773201510|2|4", "7:3-7:6|0|1|4", "8:3-8:6|0|1|4", "8:17-8:20|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 18410644574635149442, + "usr2var": [{ + "usr": 10983126130596230582, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "7:7-7:8|1|3|2", - "extent": "7:3-7:8|1|3|0", - "type": 0, + "spell": "7:7-7:8|4259594751088586730|3|2", + "extent": "7:3-7:8|4259594751088586730|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 11468802633764653592, + "usr": 17165811951126099095, "detailed_name": "Foo *f2", "qual_name_offset": 5, "short_name": "f2", "hover": "Foo *f2 = new Foo()", "declarations": [], - "spell": "8:8-8:10|1|3|2", - "extent": "8:3-8:22|1|3|0", - "type": 0, + "spell": "8:8-8:10|4259594751088586730|3|2", + "extent": "8:3-8:22|4259594751088586730|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index d750286fb..e49e62c51 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -18,26 +18,7 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": ["3:3-3:6|-1|1|4", "4:4-4:7|-1|1|4"], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0, 1], - "vars": [], - "instances": [0], - "uses": ["3:3-3:6|0|2|4", "8:3-8:6|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", "qual_name_offset": 5, @@ -45,58 +26,74 @@ void foo() { "kind": 9, "storage": 1, "declarations": [], - "spell": "3:3-3:6|0|2|2", - "extent": "3:3-3:11|0|2|0", - "declaring_type": 0, + "spell": "3:3-3:6|15041163540773201510|2|2", + "extent": "3:3-3:11|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|2|3|288"], + "uses": ["8:7-8:8|4259594751088586730|3|288"], "callees": [] }, { - "id": 1, - "usr": 7440261702884428359, - "detailed_name": "void Foo::~Foo() noexcept", + "usr": 4259594751088586730, + "detailed_name": "void foo()", "qual_name_offset": 5, - "short_name": "~Foo", - "kind": 6, + "short_name": "foo", + "kind": 12, "storage": 1, "declarations": [], - "spell": "4:3-4:7|0|2|2", - "extent": "4:3-4:12|0|2|0", + "spell": "7:6-7:9|0|1|2", + "extent": "7:1-9:2|0|1|0", "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [1893354193220338759], "uses": [], - "callees": [] + "callees": ["8:7-8:8|3385168158331140247|3|288", "8:7-8:8|3385168158331140247|3|288"] }, { - "id": 2, - "usr": 4259594751088586730, - "detailed_name": "void foo()", + "usr": 7440261702884428359, + "detailed_name": "void Foo::~Foo() noexcept", "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, + "short_name": "~Foo", + "kind": 6, "storage": 1, "declarations": [], - "spell": "7:6-7:9|-1|1|2", - "extent": "7:1-9:2|-1|1|0", + "spell": "4:3-4:7|15041163540773201510|2|2", + "extent": "4:3-4:12|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], - "vars": [0], + "vars": [], "uses": [], - "callees": ["8:7-8:8|0|3|288", "8:7-8:8|0|3|288"] + "callees": [] + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": ["3:3-3:6|0|1|4", "4:4-4:7|0|1|4"], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [3385168158331140247, 7440261702884428359], + "vars": [], + "instances": [1893354193220338759], + "uses": ["3:3-3:6|15041163540773201510|2|4", "8:3-8:6|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 9954632887635271906, + "usr2var": [{ + "usr": 1893354193220338759, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "8:7-8:8|2|3|2", - "extent": "8:3-8:8|2|3|0", - "type": 0, + "spell": "8:7-8:8|4259594751088586730|3|2", + "extent": "8:3-8:8|4259594751088586730|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index 06c475c95..cc12e0235 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -12,26 +12,23 @@ void Make() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, - "short_name": "Type", - "kind": 23, - "declarations": ["2:3-2:7|-1|1|4"], - "spell": "1:8-1:12|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "usr2func": [{ + "usr": 3957104924306079513, + "detailed_name": "void Make()", + "qual_name_offset": 5, + "short_name": "Make", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:6-5:10|0|1|2", + "extent": "5:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [0, 1], - "uses": ["2:3-2:7|0|2|4", "6:3-6:7|-1|1|4", "7:15-7:19|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "vars": [449111627548814328, 17097499197730163115], + "uses": [], + "callees": ["6:8-6:12|10530961286677896857|3|288", "6:8-6:12|10530961286677896857|3|288", "7:15-7:19|10530961286677896857|3|32", "7:15-7:19|10530961286677896857|3|32"] + }, { "usr": 10530961286677896857, "detailed_name": "void Type::Type()", "qual_name_offset": 5, @@ -39,54 +36,54 @@ void Make() { "kind": 9, "storage": 1, "declarations": [], - "spell": "2:3-2:7|0|2|2", - "extent": "2:3-2:12|0|2|0", - "declaring_type": 0, + "spell": "2:3-2:7|13487927231218873822|2|2", + "extent": "2:3-2:12|13487927231218873822|2|0", + "declaring_type": 13487927231218873822, "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|1|3|288", "7:15-7:19|1|3|32"], + "uses": ["6:8-6:12|3957104924306079513|3|288", "7:15-7:19|3957104924306079513|3|32"], "callees": [] - }, { - "id": 1, - "usr": 3957104924306079513, - "detailed_name": "void Make()", - "qual_name_offset": 5, - "short_name": "Make", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "5:6-5:10|-1|1|2", - "extent": "5:1-8:2|-1|1|0", + }], + "usr2type": [{ + "usr": 13487927231218873822, + "detailed_name": "Type", + "qual_name_offset": 0, + "short_name": "Type", + "kind": 23, + "declarations": ["2:3-2:7|0|1|4"], + "spell": "1:8-1:12|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [0, 1], - "uses": [], - "callees": ["6:8-6:12|0|3|288", "6:8-6:12|0|3|288", "7:15-7:19|0|3|32", "7:15-7:19|0|3|32"] + "types": [], + "funcs": [10530961286677896857], + "vars": [], + "instances": [449111627548814328, 17097499197730163115], + "uses": ["2:3-2:7|13487927231218873822|2|4", "6:3-6:7|0|1|4", "7:15-7:19|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 17348451315735351657, + "usr2var": [{ + "usr": 449111627548814328, "detailed_name": "Type foo0", "qual_name_offset": 5, "short_name": "foo0", "declarations": [], - "spell": "6:8-6:12|1|3|2", - "extent": "6:3-6:12|1|3|0", - "type": 0, + "spell": "6:8-6:12|3957104924306079513|3|2", + "extent": "6:3-6:12|3957104924306079513|3|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 3757978174345638825, + "usr": 17097499197730163115, "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", "declarations": [], - "spell": "7:8-7:12|1|3|2", - "extent": "7:3-7:21|1|3|0", - "type": 0, + "spell": "7:8-7:12|3957104924306079513|3|2", + "extent": "7:3-7:21|3957104924306079513|3|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 6b8087932..38af29024 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -12,26 +12,7 @@ Foo::Foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["4:6-4:9|-1|1|4"], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-1:14|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": ["4:6-4:9|-1|1|4", "4:1-4:4|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 17319723337446061757, "detailed_name": "void Foo::Foo()", "qual_name_offset": 5, @@ -39,15 +20,33 @@ Foo::Foo() {} "kind": 9, "storage": 1, "declarations": [], - "spell": "4:6-4:9|0|2|2", - "extent": "4:1-4:11|-1|1|0", - "declaring_type": 0, + "spell": "4:6-4:9|15041163540773201510|2|2", + "extent": "4:1-4:11|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["4:6-4:9|0|1|4"], + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-1:14|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [17319723337446061757], + "vars": [], + "instances": [], + "uses": ["4:6-4:9|0|1|4", "4:1-4:4|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index 9150cc488..a1f62b001 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -28,60 +28,23 @@ OUTPUT: make_functions.h { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 12993848456528750350, - "detailed_name": "Bar", - "qual_name_offset": 0, - "short_name": "Bar", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-1:14|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["7:17-7:20|-1|1|4", "8:15-8:18|-1|1|4"] - }, { - "id": 1, - "usr": 14935975554338052500, - "detailed_name": "Foobar", - "qual_name_offset": 0, - "short_name": "Foobar", - "kind": 5, - "declarations": ["5:3-5:9|-1|1|4", "6:3-6:9|-1|1|4", "7:3-7:9|-1|1|4", "8:3-8:9|-1|1|4"], - "spell": "3:7-3:13|-1|1|2", - "extent": "3:1-9:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0, 1, 2, 3], - "vars": [], - "instances": [], - "uses": ["5:3-5:9|1|2|4", "6:3-6:9|1|2|4", "7:3-7:9|1|2|4", "8:3-8:9|1|2|4"] - }], - "funcs": [{ - "id": 0, - "usr": 13131778807733950299, - "detailed_name": "void Foobar::Foobar()", + "usr2func": [{ + "usr": 3765833212244435302, + "detailed_name": "void Foobar::Foobar(int &&, Bar *, bool *)", "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, "declarations": [], - "spell": "5:3-5:9|1|2|2", - "extent": "5:3-5:14|1|2|0", - "declaring_type": 1, + "spell": "7:3-7:9|14935975554338052500|2|2", + "extent": "7:3-7:32|14935975554338052500|2|0", + "declaring_type": 14935975554338052500, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 1, "usr": 13028995015627606181, "detailed_name": "void Foobar::Foobar(int)", "qual_name_offset": 5, @@ -89,33 +52,31 @@ OUTPUT: make_functions.h "kind": 9, "storage": 1, "declarations": [], - "spell": "6:3-6:9|1|2|2", - "extent": "6:3-6:17|1|2|0", - "declaring_type": 1, + "spell": "6:3-6:9|14935975554338052500|2|2", + "extent": "6:3-6:17|14935975554338052500|2|0", + "declaring_type": 14935975554338052500, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 2, - "usr": 3765833212244435302, - "detailed_name": "void Foobar::Foobar(int &&, Bar *, bool *)", + "usr": 13131778807733950299, + "detailed_name": "void Foobar::Foobar()", "qual_name_offset": 5, "short_name": "Foobar", "kind": 9, "storage": 1, "declarations": [], - "spell": "7:3-7:9|1|2|2", - "extent": "7:3-7:32|1|2|0", - "declaring_type": 1, + "spell": "5:3-5:9|14935975554338052500|2|2", + "extent": "5:3-5:14|14935975554338052500|2|0", + "declaring_type": 14935975554338052500, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 3, "usr": 17321436359755983845, "detailed_name": "void Foobar::Foobar(int, Bar *, bool *)", "qual_name_offset": 5, @@ -123,125 +84,134 @@ OUTPUT: make_functions.h "kind": 9, "storage": 1, "declarations": [], - "spell": "8:3-8:9|1|2|2", - "extent": "8:3-8:30|1|2|0", - "declaring_type": 1, + "spell": "8:3-8:9|14935975554338052500|2|2", + "extent": "8:3-8:30|14935975554338052500|2|0", + "declaring_type": 14935975554338052500, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] -} -OUTPUT: make_functions.cc -{ - "includes": [{ - "line": 0, - "resolved_path": "&make_functions.h" - }], - "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 7902098450755788854, - "detailed_name": "T", + "usr2type": [{ + "usr": 12993848456528750350, + "detailed_name": "Bar", "qual_name_offset": 0, - "short_name": "T", - "kind": 26, + "short_name": "Bar", + "kind": 23, "declarations": [], - "spell": "3:20-3:21|0|3|2", - "extent": "3:11-3:21|0|3|0", + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-1:14|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["4:1-4:2|-1|1|4"] + "uses": ["7:17-7:20|0|1|4", "8:15-8:18|0|1|4"] }, { - "id": 1, - "usr": 12533159752419999454, - "detailed_name": "Args", + "usr": 14935975554338052500, + "detailed_name": "Foobar", "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, - "declarations": [], - "spell": "3:35-3:39|0|3|2", - "extent": "3:23-3:39|0|3|0", + "short_name": "Foobar", + "kind": 5, + "declarations": ["5:3-5:9|0|1|4", "6:3-6:9|0|1|4", "7:3-7:9|0|1|4", "8:3-8:9|0|1|4"], + "spell": "3:7-3:13|0|1|2", + "extent": "3:1-9:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [], + "funcs": [13131778807733950299, 13028995015627606181, 3765833212244435302, 17321436359755983845], "vars": [], "instances": [], - "uses": ["4:15-4:19|-1|1|4"] + "uses": ["5:3-5:9|14935975554338052500|2|4", "6:3-6:9|14935975554338052500|2|4", "7:3-7:9|14935975554338052500|2|4", "8:3-8:9|14935975554338052500|2|4"] + }], + "usr2var": [] +} +OUTPUT: make_functions.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&make_functions.h" + }], + "skipped_by_preprocessor": [], + "usr2func": [{ + "usr": 2532818908869373467, + "detailed_name": "T *maKE_NoRefs(Args... args)", + "qual_name_offset": 3, + "short_name": "maKE_NoRefs", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "9:4-9:15|0|1|2", + "extent": "9:1-11:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [3908732770590594660], + "uses": ["17:3-17:14|2816883305867289955|3|32"], + "callees": [] }, { - "id": 2, - "usr": 18441628706991062891, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, + "usr": 2816883305867289955, + "detailed_name": "void caller22()", + "qual_name_offset": 5, + "short_name": "caller22", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "8:20-8:21|1|3|2", - "extent": "8:11-8:21|1|3|0", + "spell": "13:6-13:14|0|1|2", + "extent": "13:1-18:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["9:1-9:2|-1|1|4"] + "uses": [], + "callees": ["14:3-14:13|15793662558620604611|3|32", "15:3-15:13|15793662558620604611|3|32", "16:3-16:13|15793662558620604611|3|32", "17:3-17:14|2532818908869373467|3|32"] }, { - "id": 3, - "usr": 9441341235704820385, - "detailed_name": "Args", + "usr": 3765833212244435302, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, + "short_name": "", + "kind": 0, + "storage": 0, "declarations": [], - "spell": "8:35-8:39|1|3|2", - "extent": "8:23-8:39|1|3|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["9:16-9:20|-1|1|4"] + "uses": ["16:3-16:13|0|1|288"], + "callees": [] }, { - "id": 4, - "usr": 14935975554338052500, + "usr": 13028995015627606181, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["14:14-14:20|-1|1|4", "15:14-15:20|-1|1|4", "16:14-16:20|-1|1|4", "17:15-17:21|-1|1|4"] + "uses": ["15:3-15:13|0|1|288"], + "callees": [] }, { - "id": 5, - "usr": 12993848456528750350, + "usr": 13131778807733950299, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["16:29-16:32|-1|1|4", "17:30-17:33|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "uses": ["14:3-14:13|0|1|288"], + "callees": [] + }, { "usr": 15793662558620604611, "detailed_name": "T *MakeUnique(Args &&... args)", "qual_name_offset": 3, @@ -249,123 +219,149 @@ OUTPUT: make_functions.cc "kind": 12, "storage": 1, "declarations": [], - "spell": "4:4-4:14|-1|1|2", - "extent": "4:1-6:2|-1|1|0", + "spell": "4:4-4:14|0|1|2", + "extent": "4:1-6:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0], - "uses": ["14:3-14:13|2|3|32", "15:3-15:13|2|3|32", "16:3-16:13|2|3|32"], + "vars": [8463700030555379526], + "uses": ["14:3-14:13|2816883305867289955|3|32", "15:3-15:13|2816883305867289955|3|32", "16:3-16:13|2816883305867289955|3|32"], "callees": [] }, { - "id": 1, - "usr": 2532818908869373467, - "detailed_name": "T *maKE_NoRefs(Args... args)", - "qual_name_offset": 3, - "short_name": "maKE_NoRefs", - "kind": 12, - "storage": 1, + "usr": 17321436359755983845, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, "declarations": [], - "spell": "9:4-9:15|-1|1|2", - "extent": "9:1-11:2|-1|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [1], - "uses": ["17:3-17:14|2|3|32"], + "vars": [], + "uses": ["17:3-17:14|0|1|288"], "callees": [] + }], + "usr2type": [{ + "usr": 3337128087216004141, + "detailed_name": "Args", + "qual_name_offset": 0, + "short_name": "Args", + "kind": 26, + "declarations": [], + "spell": "8:35-8:39|2532818908869373467|3|2", + "extent": "8:23-8:39|2532818908869373467|3|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["9:16-9:20|0|1|4"] }, { - "id": 2, - "usr": 2816883305867289955, - "detailed_name": "void caller22()", - "qual_name_offset": 5, - "short_name": "caller22", - "kind": 12, - "storage": 1, + "usr": 9281343527065946499, + "detailed_name": "T", + "qual_name_offset": 0, + "short_name": "T", + "kind": 26, "declarations": [], - "spell": "13:6-13:14|-1|1|2", - "extent": "13:1-18:2|-1|1|0", + "spell": "3:20-3:21|15793662558620604611|3|2", + "extent": "3:11-3:21|15793662558620604611|3|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": ["14:3-14:13|0|3|32", "15:3-15:13|0|3|32", "16:3-16:13|0|3|32", "17:3-17:14|1|3|32"] + "instances": [], + "uses": ["4:1-4:2|0|1|4"] }, { - "id": 3, - "usr": 13131778807733950299, - "detailed_name": "", + "usr": 10771590811355716928, + "detailed_name": "Args", "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, + "short_name": "Args", + "kind": 26, "declarations": [], + "spell": "3:35-3:39|15793662558620604611|3|2", + "extent": "3:23-3:39|15793662558620604611|3|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["14:3-14:13|-1|1|288"], - "callees": [] + "instances": [], + "uses": ["4:15-4:19|0|1|4"] }, { - "id": 4, - "usr": 13028995015627606181, - "detailed_name": "", + "usr": 11897454629873246477, + "detailed_name": "T", "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, + "short_name": "T", + "kind": 26, "declarations": [], + "spell": "8:20-8:21|2532818908869373467|3|2", + "extent": "8:11-8:21|2532818908869373467|3|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["15:3-15:13|-1|1|288"], - "callees": [] + "instances": [], + "uses": ["9:1-9:2|0|1|4"] }, { - "id": 5, - "usr": 3765833212244435302, + "usr": 12993848456528750350, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, - "storage": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["16:3-16:13|-1|1|288"], - "callees": [] + "instances": [], + "uses": ["16:29-16:32|0|1|4", "17:30-17:33|0|1|4"] }, { - "id": 6, - "usr": 17321436359755983845, + "usr": 14935975554338052500, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, - "storage": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["17:3-17:14|-1|1|288"], - "callees": [] + "instances": [], + "uses": ["14:14-14:20|0|1|4", "15:14-15:20|0|1|4", "16:14-16:20|0|1|4", "17:15-17:21|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 15288691366352169805, - "detailed_name": "Args &&... args", - "qual_name_offset": 11, + "usr2var": [{ + "usr": 3908732770590594660, + "detailed_name": "Args... args", + "qual_name_offset": 8, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|0|3|2", - "extent": "4:15-4:29|0|3|0", + "spell": "9:24-9:28|2532818908869373467|3|2", + "extent": "9:16-9:28|2532818908869373467|3|0", + "type": 0, "uses": [], "kind": 253, "storage": 1 }, { - "id": 1, - "usr": 12338908251430965107, - "detailed_name": "Args... args", - "qual_name_offset": 8, + "usr": 8463700030555379526, + "detailed_name": "Args &&... args", + "qual_name_offset": 11, "short_name": "args", "declarations": [], - "spell": "9:24-9:28|1|3|2", - "extent": "9:16-9:28|1|3|0", + "spell": "4:25-4:29|15793662558620604611|3|2", + "extent": "4:15-4:29|15793662558620604611|3|0", + "type": 0, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index e8c79d619..23d24d7dd 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -10,16 +10,17 @@ class Foo; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, - "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], - "spell": "3:7-3:10|-1|1|2", - "extent": "3:1-3:13|-1|1|0", + "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], + "spell": "3:7-3:10|0|1|2", + "extent": "3:1-3:13|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -28,7 +29,6 @@ class Foo; "instances": [], "uses": [] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index e51cbddcd..02495c025 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -7,50 +7,49 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], - "instances": [], + "vars": [], + "instances": [9736582033442720743], "uses": [] }, { - "id": 1, - "usr": 17, - "detailed_name": "", + "usr": 15041163540773201510, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [], - "instances": [0], + "vars": [9736582033442720743], + "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 9736582033442720743, "detailed_name": "int Foo::foo", "qual_name_offset": 4, "short_name": "foo", "declarations": [], - "spell": "2:7-2:10|0|2|2", - "extent": "2:3-2:10|0|2|0", - "type": 1, + "spell": "2:7-2:10|15041163540773201510|2|2", + "extent": "2:3-2:10|15041163540773201510|2|0", + "type": 17, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 6dcb0b312..7b4e00ec6 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -9,50 +9,49 @@ int Foo::foo; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], - "instances": [], - "uses": ["5:5-5:8|-1|1|4"] + "vars": [], + "instances": [8942920329766232482], + "uses": [] }, { - "id": 1, - "usr": 17, - "detailed_name": "", + "usr": 15041163540773201510, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [], - "instances": [0], - "uses": [] + "vars": [8942920329766232482], + "instances": [], + "uses": ["5:5-5:8|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 8942920329766232482, "detailed_name": "int Foo::foo", "qual_name_offset": 4, "short_name": "foo", - "declarations": ["2:14-2:17|0|2|1"], - "spell": "5:10-5:13|0|2|2", - "extent": "5:1-5:13|-1|1|0", - "type": 1, + "declarations": ["2:14-2:17|15041163540773201510|2|1"], + "spell": "5:10-5:13|15041163540773201510|2|2", + "extent": "5:1-5:13|0|1|0", + "type": 17, "uses": [], "kind": 8, "storage": 1 diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index 7c73e6f08..c687a9eb5 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -9,33 +9,24 @@ void foo(); { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:9|-1|1|1", - "param_spellings": [] - }, { - "spell": "2:6-2:9|-1|1|1", - "param_spellings": [] - }, { - "spell": "4:6-4:9|-1|1|1", - "param_spellings": [] - }], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-3:14|-1|1|0", + "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-3:14|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index 02287ca86..d16f8cef8 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -9,71 +9,60 @@ int foo(int a, int b) { return 0; } { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 2747674671862363334, + "detailed_name": "int foo(int a, int b)", + "qual_name_offset": 4, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], + "spell": "5:5-5:8|0|1|2", + "extent": "5:1-5:36|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [14555488990109936920, 10963664335057337329], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [14555488990109936920, 10963664335057337329], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 2747674671862363334, - "detailed_name": "int foo(int a, int b)", - "qual_name_offset": 4, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "1:5-1:8|-1|1|1", - "param_spellings": ["1:12-1:12", "1:17-1:17"] - }, { - "spell": "2:5-2:8|-1|1|1", - "param_spellings": ["2:13-2:15", "3:13-3:15"] - }, { - "spell": "4:5-4:8|-1|1|1", - "param_spellings": ["4:13-4:16", "4:22-4:25"] - }], - "spell": "5:5-5:8|-1|1|2", - "extent": "5:1-5:36|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 10480417713467708012, - "detailed_name": "int a", + "usr2var": [{ + "usr": 10963664335057337329, + "detailed_name": "int b", "qual_name_offset": 4, - "short_name": "a", + "short_name": "b", "declarations": [], - "spell": "5:13-5:14|0|3|2", - "extent": "5:9-5:14|0|3|0", - "type": 0, + "spell": "5:20-5:21|2747674671862363334|3|2", + "extent": "5:16-5:21|2747674671862363334|3|0", + "type": 17, "uses": [], "kind": 253, "storage": 1 }, { - "id": 1, - "usr": 18099600680625658464, - "detailed_name": "int b", + "usr": 14555488990109936920, + "detailed_name": "int a", "qual_name_offset": 4, - "short_name": "b", + "short_name": "a", "declarations": [], - "spell": "5:20-5:21|0|3|2", - "extent": "5:16-5:21|0|3|0", - "type": 0, + "spell": "5:13-5:14|2747674671862363334|3|2", + "extent": "5:9-5:14|2747674671862363334|3|0", + "type": 17, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 9ce1eb05e..038bd66a1 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -11,81 +11,69 @@ void Foo::def() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0, 1, 2], - "vars": [], - "instances": [], - "uses": ["7:6-7:9|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4012226004228259562, "detailed_name": "void Foo::declonly()", "qual_name_offset": 5, "short_name": "declonly", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:16|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "declarations": ["2:8-2:16|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 1, "usr": 10939323144126021546, "detailed_name": "void Foo::purevirtual()", "qual_name_offset": 5, "short_name": "purevirtual", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "3:16-3:27|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "declarations": ["3:16-3:27|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 2, "usr": 15416083548883122431, "detailed_name": "void Foo::def()", "qual_name_offset": 5, "short_name": "def", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "4:8-4:11|0|2|1", - "param_spellings": [] - }], - "spell": "7:11-7:14|0|2|2", - "extent": "7:1-7:19|-1|1|0", - "declaring_type": 0, + "declarations": ["4:8-4:11|15041163540773201510|2|1"], + "spell": "7:11-7:14|15041163540773201510|2|2", + "extent": "7:1-7:19|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [4012226004228259562, 10939323144126021546, 15416083548883122431], + "vars": [], + "instances": [], + "uses": ["7:6-7:9|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 9c0b8adcb..10bfbb881 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -9,14 +9,15 @@ enum class Foo : uint8_t { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 5, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -25,7 +26,6 @@ enum class Foo : uint8_t { "instances": [], "uses": [] }, { - "id": 1, "usr": 2010430204259339553, "detailed_name": "uint8_t", "qual_name_offset": 0, @@ -33,26 +33,26 @@ enum class Foo : uint8_t { "kind": 252, "hover": "typedef unsigned char uint8_t", "declarations": [], - "spell": "1:23-1:30|-1|1|2", - "extent": "1:1-1:30|-1|1|0", - "alias_of": 0, + "spell": "1:23-1:30|0|1|2", + "extent": "1:1-1:30|0|1|0", + "alias_of": 5, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:23-1:30|-1|1|4", "2:12-2:15|-1|1|4"] + "uses": ["1:23-1:30|0|1|4", "2:12-2:15|0|1|4"] }, { - "id": 2, "usr": 16985894625255407295, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "2:12-2:15|-1|1|2", - "extent": "2:1-5:2|-1|1|0", + "spell": "2:12-2:15|0|1|2", + "extent": "2:1-5:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -61,32 +61,29 @@ enum class Foo : uint8_t { "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 439339022761937396, "detailed_name": "Foo::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "3:3-3:4|2|2|2", - "extent": "3:3-3:4|2|2|0", - "type": 2, + "spell": "3:3-3:4|16985894625255407295|2|2", + "extent": "3:3-3:4|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], - "spell": "4:3-4:4|2|2|2", - "extent": "4:3-4:9|2|2|0", - "type": 2, + "spell": "4:3-4:4|16985894625255407295|2|2", + "extent": "4:3-4:9|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index d7a3ec929..7972f8509 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -8,16 +8,17 @@ enum Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -26,32 +27,29 @@ enum Foo { "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 439339022761937396, "detailed_name": "Foo::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|0|2|2", - "extent": "2:3-2:4|0|2|0", - "type": 0, + "spell": "2:3-2:4|16985894625255407295|2|2", + "extent": "2:3-2:4|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], - "spell": "3:3-3:4|0|2|2", - "extent": "3:3-3:9|0|2|0", - "type": 0, + "spell": "3:3-3:4|16985894625255407295|2|2", + "extent": "3:3-3:9|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 7f4a12c5e..2e4c774c1 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -15,16 +15,15 @@ enum class E : int32_t { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 16985894625255407295, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 10, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -33,13 +32,15 @@ enum class E : int32_t { "instances": [], "uses": [] }, { - "id": 1, - "usr": 17, - "detailed_name": "", + "usr": 2986879766914123941, + "detailed_name": "E", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "E", + "kind": 10, "declarations": [], + "spell": "8:12-8:13|0|1|2", + "extent": "8:1-11:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -48,7 +49,6 @@ enum class E : int32_t { "instances": [], "uses": [] }, { - "id": 2, "usr": 14939241684006947339, "detailed_name": "int32_t", "qual_name_offset": 0, @@ -56,26 +56,26 @@ enum class E : int32_t { "kind": 252, "hover": "typedef int int32_t", "declarations": [], - "spell": "6:13-6:20|-1|1|2", - "extent": "6:1-6:20|-1|1|0", - "alias_of": 1, + "spell": "6:13-6:20|0|1|2", + "extent": "6:1-6:20|0|1|0", + "alias_of": 17, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["6:13-6:20|-1|1|4", "8:12-8:13|-1|1|4"] + "uses": ["6:13-6:20|0|1|4", "8:12-8:13|0|1|4"] }, { - "id": 3, - "usr": 2986879766914123941, - "detailed_name": "E", + "usr": 16985894625255407295, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "E", + "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "8:12-8:13|-1|1|2", - "extent": "8:1-11:2|-1|1|0", + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -84,60 +84,55 @@ enum class E : int32_t { "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 439339022761937396, "detailed_name": "Foo::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|0|2|2", - "extent": "2:3-2:4|0|2|0", - "type": 0, + "spell": "2:3-2:4|16985894625255407295|2|2", + "extent": "2:3-2:4|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 1, "usr": 15962370213938840720, "detailed_name": "Foo::B", "qual_name_offset": 0, "short_name": "B", "hover": "Foo::B = 20", "declarations": [], - "spell": "3:3-3:4|0|2|2", - "extent": "3:3-3:9|0|2|0", - "type": 0, + "spell": "3:3-3:4|16985894625255407295|2|2", + "extent": "3:3-3:9|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 2, "usr": 16614320383091394267, "detailed_name": "E::E0", "qual_name_offset": 0, "short_name": "E0", "hover": "E::E0 = 0", "declarations": [], - "spell": "9:3-9:5|3|2|2", - "extent": "9:3-9:5|3|2|0", - "type": 3, + "spell": "9:3-9:5|2986879766914123941|2|2", + "extent": "9:3-9:5|2986879766914123941|2|0", + "type": 2986879766914123941, "uses": [], "kind": 22, "storage": 0 }, { - "id": 3, "usr": 16847439761518576294, "detailed_name": "E::E20", "qual_name_offset": 0, "short_name": "E20", "hover": "E::E20 = 20", "declarations": [], - "spell": "10:3-10:6|3|2|2", - "extent": "10:3-10:11|3|2|0", - "type": 3, + "spell": "10:3-10:6|2986879766914123941|2|2", + "extent": "10:3-10:11|2986879766914123941|2|0", + "type": 2986879766914123941, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index d18ace6ab..f8b956b7e 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -10,67 +10,64 @@ Foo x = Foo::A; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:12-1:15|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "spell": "1:12-1:15|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [2], - "uses": ["6:1-6:4|-1|1|4", "6:9-6:12|-1|1|4"] + "instances": [10677751717622394455], + "uses": ["6:1-6:4|0|1|4", "6:9-6:12|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 439339022761937396, "detailed_name": "Foo::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|0|2|2", - "extent": "2:3-2:4|0|2|0", - "type": 0, - "uses": ["6:14-6:15|-1|1|4"], + "spell": "2:3-2:4|16985894625255407295|2|2", + "extent": "2:3-2:4|16985894625255407295|2|0", + "type": 16985894625255407295, + "uses": ["6:14-6:15|0|1|4"], "kind": 22, "storage": 0 }, { - "id": 1, - "usr": 15962370213938840720, - "detailed_name": "Foo::B", - "qual_name_offset": 0, - "short_name": "B", - "hover": "Foo::B = 20", - "declarations": [], - "spell": "3:3-3:4|0|2|2", - "extent": "3:3-3:9|0|2|0", - "type": 0, - "uses": [], - "kind": 22, - "storage": 0 - }, { - "id": 2, "usr": 10677751717622394455, "detailed_name": "Foo x", "qual_name_offset": 4, "short_name": "x", "hover": "Foo x = Foo::A", "declarations": [], - "spell": "6:5-6:6|-1|1|2", - "extent": "6:1-6:15|-1|1|0", - "type": 0, + "spell": "6:5-6:6|0|1|2", + "extent": "6:1-6:15|0|1|0", + "type": 16985894625255407295, "uses": [], "kind": 13, "storage": 1 + }, { + "usr": 15962370213938840720, + "detailed_name": "Foo::B", + "qual_name_offset": 0, + "short_name": "B", + "hover": "Foo::B = 20", + "declarations": [], + "spell": "3:3-3:4|16985894625255407295|2|2", + "extent": "3:3-3:9|16985894625255407295|2|0", + "type": 16985894625255407295, + "uses": [], + "kind": 22, + "storage": 0 }] } */ diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 68e2e44a7..64beb5a1c 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -13,99 +13,97 @@ Foo b; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 6697181287623958829, "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|-1|1|2", - "extent": "1:1-1:10|-1|1|0", + "spell": "1:6-1:7|0|1|2", + "extent": "1:1-1:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["9:5-9:6|-1|1|4"] + "uses": ["9:5-9:6|0|1|4"] }, { - "id": 1, - "usr": 13892793056005362145, - "detailed_name": "B", + "usr": 10528472276654770367, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "B", - "kind": 10, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "2:6-2:7|-1|1|2", - "extent": "2:1-2:10|-1|1|0", + "spell": "5:8-5:11|0|1|2", + "extent": "5:1-7:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["10:5-10:6|-1|1|4"] + "instances": [12028309045033782423], + "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] }, { - "id": 2, - "usr": 10528472276654770367, - "detailed_name": "Foo", + "usr": 13892793056005362145, + "detailed_name": "B", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "B", + "kind": 10, "declarations": [], - "spell": "5:8-5:11|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "spell": "2:6-2:7|0|1|2", + "extent": "2:1-2:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], - "uses": ["9:1-9:4|-1|1|4", "10:1-10:4|-1|1|4"] + "instances": [], + "uses": ["10:5-10:6|0|1|4"] }, { - "id": 3, "usr": 13938528237873543349, "detailed_name": "Foo::Inner", "qual_name_offset": 0, "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|2|2|2", - "extent": "6:3-6:18|2|2|0", + "spell": "6:10-6:15|10528472276654770367|2|2", + "extent": "6:3-6:18|10528472276654770367|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["9:9-9:14|-1|1|4"] + "instances": [16721564935990383768], + "uses": ["9:9-9:14|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "Foo::Inner a", - "qual_name_offset": 14, - "short_name": "a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "Foo b", + "qual_name_offset": 7, + "short_name": "b", "declarations": [], - "spell": "9:15-9:16|-1|1|2", - "extent": "9:1-9:16|-1|1|0", - "type": 3, + "spell": "10:8-10:9|0|1|2", + "extent": "10:1-10:9|0|1|0", + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "Foo b", - "qual_name_offset": 7, - "short_name": "b", + "usr": 16721564935990383768, + "detailed_name": "Foo::Inner a", + "qual_name_offset": 14, + "short_name": "a", "declarations": [], - "spell": "10:8-10:9|-1|1|2", - "extent": "10:1-10:9|-1|1|0", - "type": 2, + "spell": "9:15-9:16|0|1|2", + "extent": "9:1-9:16|0|1|0", + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index 5f325e411..d0394c7ed 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -5,25 +5,22 @@ void foo(int a, int b); { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 2747674671862363334, "detailed_name": "void foo(int a, int b)", "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:9|-1|1|1", - "param_spellings": ["1:14-1:15", "1:21-1:22"] - }], + "declarations": ["1:6-1:9|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index cee467903..d914d1176 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -7,27 +7,24 @@ void foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:9|-1|1|1", - "param_spellings": [] - }], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-3:14|-1|1|0", + "declarations": ["1:6-1:9|0|1|1"], + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-3:14|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index ea8f26802..8a084daad 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -5,9 +5,7 @@ void foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, @@ -15,14 +13,16 @@ void foo() {} "kind": 12, "storage": 1, "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-1:14|-1|1|0", + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-1:14|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index 1833bb096..52959abc1 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -6,34 +6,35 @@ class Derived : public Parent {}; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 3866412049634585509, "detailed_name": "Parent", "qual_name_offset": 0, "short_name": "Parent", "kind": 5, - "declarations": ["2:24-2:30|-1|1|4"], - "spell": "1:7-1:13|-1|1|2", - "extent": "1:1-1:16|-1|1|0", + "declarations": ["2:24-2:30|0|1|4"], + "spell": "1:7-1:13|0|1|2", + "extent": "1:1-1:16|0|1|0", + "alias_of": 0, "bases": [], - "derived": [1], + "derived": [10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:30|-1|1|4"] + "uses": ["2:24-2:30|0|1|4"] }, { - "id": 1, "usr": 10963370434658308541, "detailed_name": "Derived", "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "2:7-2:14|-1|1|2", - "extent": "2:1-2:33|-1|1|0", - "bases": [0], + "spell": "2:7-2:14|0|1|2", + "extent": "2:1-2:33|0|1|0", + "alias_of": 0, + "bases": [3866412049634585509], "derived": [], "types": [], "funcs": [], @@ -41,7 +42,6 @@ class Derived : public Parent {}; "instances": [], "uses": [] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index f106d3c9f..da6331e6e 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -17,136 +17,135 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 11930058224338108382, - "detailed_name": "Base1", - "qual_name_offset": 0, - "short_name": "Base1", - "kind": 5, - "declarations": ["8:18-8:23|-1|1|4", "13:17-13:22|-1|1|4"], - "spell": "2:7-2:12|-1|1|2", - "extent": "2:1-2:15|-1|1|0", - "bases": [], - "derived": [2, 6], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["8:18-8:23|-1|1|4", "13:17-13:22|-1|1|4"] - }, { - "id": 1, - "usr": 11118288764693061434, - "detailed_name": "Base2", + "usr2func": [], + "usr2type": [{ + "usr": 9, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Base2", - "kind": 5, - "declarations": ["11:18-11:23|-1|1|4", "13:27-13:32|-1|1|4"], - "spell": "5:7-5:12|-1|1|2", - "extent": "5:1-5:15|-1|1|0", + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], - "derived": [4, 6], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["11:18-11:23|-1|1|4", "13:27-13:32|-1|1|4"] + "instances": [12990052348105569112], + "uses": [] }, { - "id": 2, "usr": 5863733211528032190, "detailed_name": "Derived1", "qual_name_offset": 0, "short_name": "Derived1", "kind": 5, - "declarations": ["13:43-13:51|-1|1|4"], - "spell": "8:7-8:15|-1|1|2", - "extent": "8:1-8:29|-1|1|0", - "bases": [0], - "derived": [6], + "declarations": ["13:43-13:51|0|1|4"], + "spell": "8:7-8:15|0|1|2", + "extent": "8:1-8:29|0|1|0", + "alias_of": 0, + "bases": [11930058224338108382], + "derived": [10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["13:43-13:51|-1|1|4"] + "uses": ["13:43-13:51|0|1|4"] }, { - "id": 3, - "usr": 9, - "detailed_name": "", + "usr": 7916588271848318236, + "detailed_name": "T", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "T", + "kind": 26, "declarations": [], + "spell": "10:19-10:20|0|1|2", + "extent": "10:10-10:20|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": [] + "instances": [], + "uses": ["11:24-11:25|0|1|4"] }, { - "id": 4, "usr": 10651399730831737929, "detailed_name": "Derived2", "qual_name_offset": 0, "short_name": "Derived2", "kind": 5, - "declarations": ["13:56-13:64|-1|1|4"], - "spell": "11:7-11:15|-1|1|2", - "extent": "11:1-11:29|-1|1|0", - "bases": [1], - "derived": [6], + "declarations": ["13:56-13:64|0|1|4"], + "spell": "11:7-11:15|0|1|2", + "extent": "11:1-11:29|0|1|0", + "alias_of": 0, + "bases": [11118288764693061434], + "derived": [10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["13:56-13:64|-1|1|4"] + "uses": ["13:56-13:64|0|1|4"] }, { - "id": 5, - "usr": 780719166805015998, - "detailed_name": "T", + "usr": 10963370434658308541, + "detailed_name": "Derived", "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "10:19-10:20|-1|1|2", - "extent": "10:10-10:20|-1|1|0", - "bases": [], + "short_name": "Derived", + "kind": 5, + "declarations": ["13:33-13:40|0|1|4", "13:65-13:72|0|1|4"], + "spell": "13:7-13:14|0|1|2", + "extent": "13:1-13:76|0|1|0", + "alias_of": 0, + "bases": [11930058224338108382, 11118288764693061434, 5863733211528032190, 10651399730831737929], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["11:24-11:25|-1|1|4"] + "uses": ["13:33-13:40|0|1|4", "13:65-13:72|0|1|4"] }, { - "id": 6, - "usr": 10963370434658308541, - "detailed_name": "Derived", + "usr": 11118288764693061434, + "detailed_name": "Base2", "qual_name_offset": 0, - "short_name": "Derived", + "short_name": "Base2", "kind": 5, - "declarations": ["13:33-13:40|-1|1|4", "13:65-13:72|-1|1|4"], - "spell": "13:7-13:14|-1|1|2", - "extent": "13:1-13:76|-1|1|0", - "bases": [0, 1, 2, 4], - "derived": [], + "declarations": ["11:18-11:23|0|1|4", "13:27-13:32|0|1|4"], + "spell": "5:7-5:12|0|1|2", + "extent": "5:1-5:15|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [10651399730831737929, 10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["13:33-13:40|-1|1|4", "13:65-13:72|-1|1|4"] + "uses": ["11:18-11:23|0|1|4", "13:27-13:32|0|1|4"] + }, { + "usr": 11930058224338108382, + "detailed_name": "Base1", + "qual_name_offset": 0, + "short_name": "Base1", + "kind": 5, + "declarations": ["8:18-8:23|0|1|4", "13:17-13:22|0|1|4"], + "spell": "2:7-2:12|0|1|2", + "extent": "2:1-2:15|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [5863733211528032190, 10963370434658308541], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["8:18-8:23|0|1|4", "13:17-13:22|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 3880651725784125791, + "usr2var": [{ + "usr": 12990052348105569112, "detailed_name": "unsigned int T", "qual_name_offset": 13, - "short_name": "T", + "short_name": "", "declarations": [], - "spell": "7:23-7:24|-1|1|2", - "extent": "7:10-7:24|-1|1|0", - "type": 3, - "uses": ["8:24-8:25|-1|1|4"], + "spell": "7:23-7:24|0|1|2", + "extent": "7:10-7:24|0|1|0", + "type": 9, + "uses": ["8:24-8:25|0|1|4"], "kind": 26, "storage": 0 }] diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index 01f3d8a70..84338ad61 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -8,76 +8,76 @@ class Derived : public MiddleA, public MiddleB {}; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 3897841498936210886, "detailed_name": "Root", "qual_name_offset": 0, "short_name": "Root", "kind": 5, - "declarations": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"], - "spell": "1:7-1:11|-1|1|2", - "extent": "1:1-1:14|-1|1|0", + "declarations": ["2:24-2:28|0|1|4", "3:24-3:28|0|1|4"], + "spell": "1:7-1:11|0|1|2", + "extent": "1:1-1:14|0|1|0", + "alias_of": 0, "bases": [], - "derived": [1, 2], + "derived": [11863524815063131483, 14022569716337624303], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"] + "uses": ["2:24-2:28|0|1|4", "3:24-3:28|0|1|4"] }, { - "id": 1, - "usr": 11863524815063131483, - "detailed_name": "MiddleA", + "usr": 10963370434658308541, + "detailed_name": "Derived", "qual_name_offset": 0, - "short_name": "MiddleA", + "short_name": "Derived", "kind": 5, - "declarations": ["4:24-4:31|-1|1|4"], - "spell": "2:7-2:14|-1|1|2", - "extent": "2:1-2:31|-1|1|0", - "bases": [0], - "derived": [3], + "declarations": [], + "spell": "4:7-4:14|0|1|2", + "extent": "4:1-4:50|0|1|0", + "alias_of": 0, + "bases": [11863524815063131483, 14022569716337624303], + "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["4:24-4:31|-1|1|4"] + "uses": [] }, { - "id": 2, - "usr": 14022569716337624303, - "detailed_name": "MiddleB", + "usr": 11863524815063131483, + "detailed_name": "MiddleA", "qual_name_offset": 0, - "short_name": "MiddleB", + "short_name": "MiddleA", "kind": 5, - "declarations": ["4:40-4:47|-1|1|4"], - "spell": "3:7-3:14|-1|1|2", - "extent": "3:1-3:31|-1|1|0", - "bases": [0], - "derived": [3], + "declarations": ["4:24-4:31|0|1|4"], + "spell": "2:7-2:14|0|1|2", + "extent": "2:1-2:31|0|1|0", + "alias_of": 0, + "bases": [3897841498936210886], + "derived": [10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["4:40-4:47|-1|1|4"] + "uses": ["4:24-4:31|0|1|4"] }, { - "id": 3, - "usr": 10963370434658308541, - "detailed_name": "Derived", + "usr": 14022569716337624303, + "detailed_name": "MiddleB", "qual_name_offset": 0, - "short_name": "Derived", + "short_name": "MiddleB", "kind": 5, - "declarations": [], - "spell": "4:7-4:14|-1|1|2", - "extent": "4:1-4:50|-1|1|0", - "bases": [1, 2], - "derived": [], + "declarations": ["4:40-4:47|0|1|4"], + "spell": "3:7-3:14|0|1|2", + "extent": "3:1-3:31|0|1|0", + "alias_of": 0, + "bases": [3897841498936210886], + "derived": [10963370434658308541], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["4:40-4:47|0|1|4"] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 90cfca91b..b0503ebd9 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -10,77 +10,72 @@ class Derived : public Root { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 6666242542855173890, + "detailed_name": "void Derived::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "5:8-5:11|10963370434658308541|2|2", + "extent": "5:3-5:25|10963370434658308541|2|0", + "declaring_type": 10963370434658308541, + "bases": [9948027785633571339], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 9948027785633571339, + "detailed_name": "void Root::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["2:16-2:19|3897841498936210886|2|1"], + "declaring_type": 3897841498936210886, + "bases": [], + "derived": [6666242542855173890], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 3897841498936210886, "detailed_name": "Root", "qual_name_offset": 0, "short_name": "Root", "kind": 5, - "declarations": ["4:24-4:28|-1|1|4"], - "spell": "1:7-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "declarations": ["4:24-4:28|0|1|4"], + "spell": "1:7-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], - "derived": [1], + "derived": [10963370434658308541], "types": [], - "funcs": [0], + "funcs": [9948027785633571339], "vars": [], "instances": [], - "uses": ["4:24-4:28|-1|1|4"] + "uses": ["4:24-4:28|0|1|4"] }, { - "id": 1, "usr": 10963370434658308541, "detailed_name": "Derived", "qual_name_offset": 0, "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "4:7-4:14|-1|1|2", - "extent": "4:1-6:2|-1|1|0", - "bases": [0], + "spell": "4:7-4:14|0|1|2", + "extent": "4:1-6:2|0|1|0", + "alias_of": 0, + "bases": [3897841498936210886], "derived": [], "types": [], - "funcs": [1], + "funcs": [6666242542855173890], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 9948027785633571339, - "detailed_name": "void Root::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "2:16-2:19|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, - "bases": [], - "derived": [1], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 1, - "usr": 6666242542855173890, - "detailed_name": "void Derived::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [], - "spell": "5:8-5:11|1|2|2", - "extent": "5:3-5:25|1|2|0", - "declaring_type": 1, - "bases": [0], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index d9f147c3a..e0bbfdf18 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -7,43 +7,39 @@ class IFoo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 3277829753446788562, + "detailed_name": "void IFoo::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["2:16-2:19|9949214233977131946|2|1"], + "declaring_type": 9949214233977131946, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 9949214233977131946, "detailed_name": "IFoo", "qual_name_offset": 0, "short_name": "IFoo", "kind": 5, "declarations": [], - "spell": "1:7-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "1:7-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [3277829753446788562], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 3277829753446788562, - "detailed_name": "void IFoo::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "2:16-2:19|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 254dfcf6b..2b4a6535c 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -13,110 +13,107 @@ struct Derived : Base0, Base1 { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 11628904180681204356, - "detailed_name": "Base0", - "qual_name_offset": 0, - "short_name": "Base0", - "kind": 23, - "declarations": ["2:12-2:17|-1|1|4", "7:18-7:23|-1|1|4"], - "spell": "1:8-1:13|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [2], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": ["7:18-7:23|-1|1|4"] - }, { - "id": 1, - "usr": 15826803741381445676, - "detailed_name": "Base1", - "qual_name_offset": 0, - "short_name": "Base1", - "kind": 23, - "declarations": ["5:12-5:17|-1|1|4", "7:25-7:30|-1|1|4"], - "spell": "4:8-4:13|-1|1|2", - "extent": "4:1-6:2|-1|1|0", - "bases": [], - "derived": [2], - "types": [], - "funcs": [1], - "vars": [], - "instances": [], - "uses": ["7:25-7:30|-1|1|4"] - }, { - "id": 2, - "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, - "short_name": "Derived", - "kind": 23, - "declarations": ["8:4-8:11|-1|1|4"], - "spell": "7:8-7:15|-1|1|2", - "extent": "7:1-9:2|-1|1|0", - "bases": [0, 1], - "derived": [], - "types": [], - "funcs": [2], - "vars": [], - "instances": [], - "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 16347272523198263017, - "detailed_name": "void Base0::~Base0() noexcept", + "usr2func": [{ + "usr": 8401779086123965305, + "detailed_name": "void Base1::~Base1() noexcept", "qual_name_offset": 5, - "short_name": "~Base0", + "short_name": "~Base1", "kind": 6, "storage": 1, "declarations": [], - "spell": "2:11-2:17|0|2|2", - "extent": "2:3-2:23|0|2|0", - "declaring_type": 0, + "spell": "5:11-5:17|15826803741381445676|2|2", + "extent": "5:3-5:23|15826803741381445676|2|0", + "declaring_type": 15826803741381445676, "bases": [], - "derived": [2], + "derived": [13164726294460837993], "vars": [], "uses": [], "callees": [] }, { - "id": 1, - "usr": 8401779086123965305, - "detailed_name": "void Base1::~Base1() noexcept", + "usr": 13164726294460837993, + "detailed_name": "void Derived::~Derived() noexcept", "qual_name_offset": 5, - "short_name": "~Base1", + "short_name": "~Derived", "kind": 6, "storage": 1, "declarations": [], - "spell": "5:11-5:17|1|2|2", - "extent": "5:3-5:23|1|2|0", - "declaring_type": 1, - "bases": [], - "derived": [2], + "spell": "8:3-8:11|10963370434658308541|2|2", + "extent": "8:3-8:26|10963370434658308541|2|0", + "declaring_type": 10963370434658308541, + "bases": [16347272523198263017, 8401779086123965305], + "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 2, - "usr": 13164726294460837993, - "detailed_name": "void Derived::~Derived() noexcept", + "usr": 16347272523198263017, + "detailed_name": "void Base0::~Base0() noexcept", "qual_name_offset": 5, - "short_name": "~Derived", + "short_name": "~Base0", "kind": 6, "storage": 1, "declarations": [], - "spell": "8:3-8:11|2|2|2", - "extent": "8:3-8:26|2|2|0", - "declaring_type": 2, - "bases": [0, 1], - "derived": [], + "spell": "2:11-2:17|11628904180681204356|2|2", + "extent": "2:3-2:23|11628904180681204356|2|0", + "declaring_type": 11628904180681204356, + "bases": [], + "derived": [13164726294460837993], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 10963370434658308541, + "detailed_name": "Derived", + "qual_name_offset": 0, + "short_name": "Derived", + "kind": 23, + "declarations": ["8:4-8:11|0|1|4"], + "spell": "7:8-7:15|0|1|2", + "extent": "7:1-9:2|0|1|0", + "alias_of": 0, + "bases": [11628904180681204356, 15826803741381445676], + "derived": [], + "types": [], + "funcs": [13164726294460837993], + "vars": [], + "instances": [], + "uses": [] + }, { + "usr": 11628904180681204356, + "detailed_name": "Base0", + "qual_name_offset": 0, + "short_name": "Base0", + "kind": 23, + "declarations": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|4"], + "spell": "1:8-1:13|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [10963370434658308541], + "types": [], + "funcs": [16347272523198263017], + "vars": [], + "instances": [], + "uses": ["7:18-7:23|0|1|4"] + }, { + "usr": 15826803741381445676, + "detailed_name": "Base1", + "qual_name_offset": 0, + "short_name": "Base1", + "kind": 23, + "declarations": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|4"], + "spell": "4:8-4:13|0|1|2", + "extent": "4:1-6:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [10963370434658308541], + "types": [], + "funcs": [8401779086123965305], + "vars": [], + "instances": [], + "uses": ["7:25-7:30|0|1|4"] + }], + "usr2var": [] } */ \ No newline at end of file diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index c06408f32..b718b9625 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -16,105 +16,102 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-12:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [12666114896600231317, 2981279427664991319], + "uses": [], + "callees": ["9:14-9:15|17926497908620168464|3|32", "10:14-10:15|17926497908620168464|3|32", "11:14-11:15|17926497908620168464|3|32"] + }, { + "usr": 17926497908620168464, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [0, 2], - "uses": [] - }, { - "id": 1, - "usr": 1287417953265234030, + "uses": ["9:14-9:15|4259594751088586730|3|32", "10:14-10:15|4259594751088586730|3|32", "11:14-11:15|4259594751088586730|3|32"], + "callees": [] + }], + "usr2type": [{ + "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], + "instances": [12666114896600231317, 12879188959314906706], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-12:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"] }, { - "id": 1, - "usr": 1328781044864682611, + "usr": 14635009347499519042, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, - "storage": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["9:14-9:15|0|3|32", "10:14-10:15|0|3|32", "11:14-11:15|0|3|32"], - "callees": [] + "instances": [2981279427664991319], + "uses": [] }], - "vars": [{ - "id": 0, - "usr": 17270098654620601683, - "detailed_name": "int x", - "qual_name_offset": 4, - "short_name": "x", + "usr2var": [{ + "usr": 2981279427664991319, + "detailed_name": "lambda dosomething", + "qual_name_offset": 7, + "short_name": "dosomething", "declarations": [], - "spell": "2:7-2:8|0|3|2", - "extent": "2:3-2:8|0|3|0", - "type": 0, - "uses": ["5:7-5:8|-1|1|4", "4:24-4:25|0|3|4"], + "spell": "4:8-4:19|4259594751088586730|3|2", + "extent": "4:3-7:4|4259594751088586730|3|0", + "type": 14635009347499519042, + "uses": ["9:3-9:14|4259594751088586730|3|4", "10:3-10:14|4259594751088586730|3|4", "11:3-11:14|4259594751088586730|3|4"], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 16806544259835773270, - "detailed_name": "lambda dosomething", - "qual_name_offset": 7, - "short_name": "dosomething", + "usr": 12666114896600231317, + "detailed_name": "int x", + "qual_name_offset": 4, + "short_name": "x", "declarations": [], - "spell": "4:8-4:19|0|3|2", - "extent": "4:3-7:4|0|3|0", - "type": 1, - "uses": ["9:3-9:14|0|3|4", "10:3-10:14|0|3|4", "11:3-11:14|0|3|4"], + "spell": "2:7-2:8|4259594751088586730|3|2", + "extent": "2:3-2:8|4259594751088586730|3|0", + "type": 17, + "uses": ["5:7-5:8|0|1|4", "4:24-4:25|4259594751088586730|3|4"], "kind": 13, "storage": 1 }, { - "id": 2, - "usr": 2034725908368218782, + "usr": 12879188959314906706, "detailed_name": "int y", "qual_name_offset": 4, - "short_name": "y", + "short_name": "", "declarations": [], - "spell": "4:31-4:32|0|3|2", - "extent": "4:27-4:32|0|3|0", - "type": 0, - "uses": ["6:7-6:8|0|3|4"], + "spell": "4:31-4:32|4259594751088586730|3|2", + "extent": "4:27-4:32|4259594751088586730|3|0", + "type": 17, + "uses": ["6:7-6:8|4259594751088586730|3|4"], "kind": 253, "storage": 1 }] diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index ae3e23c27..72a7611b4 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -16,24 +16,23 @@ FOO(make1(), make2); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "usr2func": [{ + "usr": 9720930732776154610, + "detailed_name": "int a()", + "qual_name_offset": 4, + "short_name": "a", + "kind": 12, + "storage": 1, + "declarations": ["12:1-12:20|0|1|1"], + "spell": "12:1-12:20|0|1|2", + "extent": "12:1-12:20|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [0], - "uses": [] - }], - "funcs": [{ - "id": 0, + "uses": [], + "callees": ["12:5-12:10|14400399977994209582|3|32"] + }, { "usr": 14400399977994209582, "detailed_name": "int make1()", "qual_name_offset": 4, @@ -41,58 +40,55 @@ FOO(make1(), make2); "kind": 12, "storage": 1, "declarations": [], - "spell": "6:5-6:10|-1|1|2", - "extent": "6:1-8:2|-1|1|0", + "spell": "6:5-6:10|0|1|2", + "extent": "6:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|1|3|32"], + "uses": ["12:5-12:10|9720930732776154610|3|32"], "callees": [] - }, { - "id": 1, - "usr": 9720930732776154610, - "detailed_name": "int a()", - "qual_name_offset": 4, - "short_name": "a", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "12:1-12:20|-1|1|1", - "param_spellings": [] - }], - "spell": "12:1-12:20|-1|1|2", - "extent": "12:1-12:20|-1|1|0", + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": ["12:5-12:10|0|3|32"] + "instances": [2878407290385495202], + "uses": [] }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 2878407290385495202, "detailed_name": "const int make2", "qual_name_offset": 10, "short_name": "make2", "hover": "const int make2 = 5", "declarations": [], - "spell": "9:11-9:16|-1|1|2", - "extent": "9:1-9:20|-1|1|0", - "type": 0, - "uses": ["12:14-12:19|1|3|4"], + "spell": "9:11-9:16|0|1|2", + "extent": "9:1-9:20|0|1|0", + "type": 17, + "uses": ["12:14-12:19|9720930732776154610|3|4"], "kind": 13, "storage": 1 }, { - "id": 1, "usr": 4261071340275951718, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO(aaa, bbb)\n int a();\n int a() { return aaa + bbb; }", "declarations": [], - "spell": "1:9-1:12|-1|1|2", - "extent": "1:9-3:32|-1|1|0", - "uses": ["12:1-12:4|-1|1|4"], + "spell": "1:9-1:12|0|1|2", + "extent": "1:9-3:32|0|1|0", + "type": 0, + "uses": ["12:1-12:4|0|1|4"], "kind": 255, "storage": 0 }] diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 4fb7a6e71..c513bd106 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -12,97 +12,95 @@ int x = A; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "usr2func": [{ + "usr": 13788753348312146871, + "detailed_name": "void Foo::Foo(Foo &&)", + "qual_name_offset": 5, "short_name": "Foo", - "kind": 23, - "declarations": ["5:12-5:15|-1|1|4"], - "spell": "4:8-4:11|-1|1|2", - "extent": "4:1-6:2|-1|1|0", + "kind": 9, + "storage": 1, + "declarations": [], + "spell": "5:12-5:15|15041163540773201510|2|2", + "extent": "5:12-5:16|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], - "types": [], - "funcs": [0], "vars": [], - "instances": [], - "uses": ["5:12-5:15|0|2|4"] - }, { - "id": 1, + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [10677751717622394455], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 13788753348312146871, - "detailed_name": "void Foo::Foo(Foo &&)", - "qual_name_offset": 5, + }, { + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, "short_name": "Foo", - "kind": 9, - "storage": 1, - "declarations": [], - "spell": "5:12-5:15|0|2|2", - "extent": "5:12-5:16|0|2|0", - "declaring_type": 0, + "kind": 23, + "declarations": ["5:12-5:15|0|1|4"], + "spell": "4:8-4:11|0|1|2", + "extent": "4:1-6:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [13788753348312146871], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["5:12-5:15|15041163540773201510|2|4"] }], - "vars": [{ - "id": 0, - "usr": 10677751717622394455, - "detailed_name": "int x", - "qual_name_offset": 4, - "short_name": "x", - "hover": "int x = A", + "usr2var": [{ + "usr": 2056319845419860263, + "detailed_name": "DISALLOW", + "qual_name_offset": 0, + "short_name": "DISALLOW", + "hover": "#define DISALLOW(type) type(type&&) = delete;", "declarations": [], - "spell": "8:5-8:6|-1|1|2", - "extent": "8:1-8:10|-1|1|0", - "type": 1, - "uses": [], - "kind": 13, - "storage": 1 + "spell": "2:9-2:17|0|1|2", + "extent": "2:9-2:46|0|1|0", + "type": 0, + "uses": ["5:3-5:11|0|1|4"], + "kind": 255, + "storage": 0 }, { - "id": 1, "usr": 7651988378939587454, "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", "hover": "#define A 5", "declarations": [], - "spell": "1:9-1:10|-1|1|2", - "extent": "1:9-1:12|-1|1|0", - "uses": ["8:9-8:10|-1|1|4"], + "spell": "1:9-1:10|0|1|2", + "extent": "1:9-1:12|0|1|0", + "type": 0, + "uses": ["8:9-8:10|0|1|4"], "kind": 255, "storage": 0 }, { - "id": 2, - "usr": 14946041066794678724, - "detailed_name": "DISALLOW", - "qual_name_offset": 0, - "short_name": "DISALLOW", - "hover": "#define DISALLOW(type) type(type&&) = delete;", + "usr": 10677751717622394455, + "detailed_name": "int x", + "qual_name_offset": 4, + "short_name": "x", + "hover": "int x = A", "declarations": [], - "spell": "2:9-2:17|-1|1|2", - "extent": "2:9-2:46|-1|1|0", - "uses": ["5:3-5:11|-1|1|4"], - "kind": 255, - "storage": 0 + "spell": "8:5-8:6|0|1|2", + "extent": "8:1-8:10|0|1|0", + "type": 17, + "uses": [], + "kind": 13, + "storage": 1 }] } */ diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index 54f5cec85..f576f2828 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -11,43 +11,39 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 17922201480358737771, + "detailed_name": "void Foo::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["2:8-2:11|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [17922201480358737771], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 17922201480358737771, - "detailed_name": "void Foo::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "2:8-2:11|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 5ee733c24..402089941 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -9,45 +9,41 @@ void Foo::foo() const {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": ["5:6-5:9|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 6446764306530590711, "detailed_name": "void Foo::foo() const", "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:11|0|2|1", - "param_spellings": [] - }], - "spell": "5:11-5:14|0|2|2", - "extent": "5:1-5:25|-1|1|0", - "declaring_type": 0, + "declarations": ["2:8-2:11|15041163540773201510|2|1"], + "spell": "5:11-5:14|15041163540773201510|2|2", + "extent": "5:1-5:25|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [6446764306530590711], + "vars": [], + "instances": [], + "uses": ["5:6-5:9|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index 8dcd54489..e621ec2d9 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -7,26 +7,7 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": [] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", "qual_name_offset": 5, @@ -34,15 +15,33 @@ class Foo { "kind": 6, "storage": 1, "declarations": [], - "spell": "2:8-2:11|0|2|2", - "extent": "2:3-2:16|0|2|0", - "declaring_type": 0, + "spell": "2:8-2:11|15041163540773201510|2|2", + "extent": "2:3-2:16|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [17922201480358737771], + "vars": [], + "instances": [], + "uses": [] + }], + "usr2var": [] } */ diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 44a27cfde..0787f9db2 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -10,14 +10,15 @@ OUTPUT: funky_enum.h { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -26,46 +27,42 @@ OUTPUT: funky_enum.h "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 439339022761937396, "detailed_name": "Foo::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "4:1-4:2|0|2|2", - "extent": "4:1-4:2|0|2|0", - "type": 0, + "spell": "4:1-4:2|16985894625255407295|2|2", + "extent": "4:1-4:2|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 1, - "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "usr": 8524995777615948802, + "detailed_name": "Foo::C", "qual_name_offset": 0, - "short_name": "B", - "hover": "Foo::B = 1", + "short_name": "C", + "hover": "Foo::C = 2", "declarations": [], - "spell": "5:1-5:2|0|2|2", - "extent": "5:1-5:2|0|2|0", - "type": 0, + "spell": "6:1-6:2|16985894625255407295|2|2", + "extent": "6:1-6:2|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 }, { - "id": 2, - "usr": 8524995777615948802, - "detailed_name": "Foo::C", + "usr": 15962370213938840720, + "detailed_name": "Foo::B", "qual_name_offset": 0, - "short_name": "C", - "hover": "Foo::C = 2", + "short_name": "B", + "hover": "Foo::B = 1", "declarations": [], - "spell": "6:1-6:2|0|2|2", - "extent": "6:1-6:2|0|2|0", - "type": 0, + "spell": "5:1-5:2|16985894625255407295|2|2", + "extent": "5:1-5:2|16985894625255407295|2|0", + "type": 16985894625255407295, "uses": [], "kind": 22, "storage": 0 @@ -78,16 +75,17 @@ OUTPUT: funky_enum.cc "resolved_path": "&funky_enum.h" }], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -96,7 +94,6 @@ OUTPUT: funky_enum.cc "instances": [], "uses": [] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ \ No newline at end of file diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index d35cd4496..070c85645 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -9,42 +9,56 @@ OUTPUT: header.h { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 8420119006782424779, - "detailed_name": "Base", + "usr2func": [{ + "usr": 11650481237659640387, + "detailed_name": "void Foo1()", + "qual_name_offset": 5, + "short_name": "Foo1", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "10:6-10:10|0|1|2", + "extent": "10:1-10:15|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Base", - "kind": 23, - "declarations": ["5:26-5:30|-1|1|4"], - "spell": "3:8-3:12|-1|1|2", - "extent": "3:1-3:15|-1|1|0", + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], - "derived": [1], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["5:26-5:30|-1|1|4"] + "instances": [2638219001294786365, 8395885290297540138], + "uses": [] }, { - "id": 1, - "usr": 16750616846959666305, - "detailed_name": "SameFileDerived", + "usr": 529393482671181129, + "detailed_name": "Foo2", "qual_name_offset": 0, - "short_name": "SameFileDerived", - "kind": 23, + "short_name": "Foo2", + "kind": 5, "declarations": [], - "spell": "5:8-5:23|-1|1|2", - "extent": "5:1-5:33|-1|1|0", - "bases": [0], + "spell": "13:8-13:12|0|1|2", + "extent": "13:1-13:15|0|1|0", + "alias_of": 0, + "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["7:14-7:29|-1|1|4"] + "uses": [] }, { - "id": 2, "usr": 619345544228965342, "detailed_name": "Foo0", "qual_name_offset": 0, @@ -52,26 +66,26 @@ OUTPUT: header.h "kind": 252, "hover": "using Foo0 = SameFileDerived", "declarations": [], - "spell": "7:7-7:11|-1|1|2", - "extent": "7:1-7:29|-1|1|0", - "alias_of": 1, + "spell": "7:7-7:11|0|1|2", + "extent": "7:1-7:29|0|1|0", + "alias_of": 16750616846959666305, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["7:7-7:11|-1|1|4"] + "uses": ["7:7-7:11|0|1|4"] }, { - "id": 3, - "usr": 529393482671181129, - "detailed_name": "Foo2", + "usr": 4481210672785600703, + "detailed_name": "Foo3", "qual_name_offset": 0, - "short_name": "Foo2", - "kind": 5, + "short_name": "Foo3", + "kind": 10, "declarations": [], - "spell": "13:8-13:12|-1|1|2", - "extent": "13:1-13:15|-1|1|0", + "spell": "15:6-15:10|0|1|2", + "extent": "15:1-15:22|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -80,123 +94,103 @@ OUTPUT: header.h "instances": [], "uses": [] }, { - "id": 4, - "usr": 4481210672785600703, - "detailed_name": "Foo3", + "usr": 8420119006782424779, + "detailed_name": "Base", "qual_name_offset": 0, - "short_name": "Foo3", - "kind": 10, - "declarations": [], - "spell": "15:6-15:10|-1|1|2", - "extent": "15:1-15:22|-1|1|0", + "short_name": "Base", + "kind": 23, + "declarations": ["5:26-5:30|0|1|4"], + "spell": "3:8-3:12|0|1|2", + "extent": "3:1-3:15|0|1|0", + "alias_of": 0, "bases": [], - "derived": [], + "derived": [16750616846959666305], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["5:26-5:30|0|1|4"] }, { - "id": 5, - "usr": 17, - "detailed_name": "", + "usr": 16750616846959666305, + "detailed_name": "SameFileDerived", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "SameFileDerived", + "kind": 23, "declarations": [], - "bases": [], + "spell": "5:8-5:23|0|1|2", + "extent": "5:1-5:33|0|1|0", + "alias_of": 0, + "bases": [8420119006782424779], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [3, 4], - "uses": [] + "instances": [], + "uses": ["7:14-7:29|0|1|4"] }], - "funcs": [{ - "id": 0, - "usr": 11650481237659640387, - "detailed_name": "void Foo1()", - "qual_name_offset": 5, - "short_name": "Foo1", - "kind": 12, - "storage": 1, + "usr2var": [{ + "usr": 2638219001294786365, + "detailed_name": "int Foo4", + "qual_name_offset": 4, + "short_name": "Foo4", "declarations": [], - "spell": "10:6-10:10|-1|1|2", - "extent": "10:1-10:15|-1|1|0", - "bases": [], - "derived": [], - "vars": [], + "spell": "17:5-17:9|0|1|2", + "extent": "17:1-17:9|0|1|0", + "type": 17, "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, + "kind": 13, + "storage": 1 + }, { "usr": 6141718166919284735, "detailed_name": "Foo3::A", "qual_name_offset": 0, "short_name": "A", "hover": "Foo3::A = 0", "declarations": [], - "spell": "15:13-15:14|4|2|2", - "extent": "15:13-15:14|4|2|0", - "type": 4, - "uses": [], - "kind": 22, - "storage": 0 - }, { - "id": 1, - "usr": 17716334512218775320, - "detailed_name": "Foo3::B", - "qual_name_offset": 0, - "short_name": "B", - "hover": "Foo3::B = 1", - "declarations": [], - "spell": "15:16-15:17|4|2|2", - "extent": "15:16-15:17|4|2|0", - "type": 4, + "spell": "15:13-15:14|4481210672785600703|2|2", + "extent": "15:13-15:14|4481210672785600703|2|0", + "type": 4481210672785600703, "uses": [], "kind": 22, "storage": 0 }, { - "id": 2, "usr": 7285646116511901840, "detailed_name": "Foo3::C", "qual_name_offset": 0, "short_name": "C", "hover": "Foo3::C = 2", "declarations": [], - "spell": "15:19-15:20|4|2|2", - "extent": "15:19-15:20|4|2|0", - "type": 4, + "spell": "15:19-15:20|4481210672785600703|2|2", + "extent": "15:19-15:20|4481210672785600703|2|0", + "type": 4481210672785600703, "uses": [], "kind": 22, "storage": 0 }, { - "id": 3, - "usr": 2638219001294786365, - "detailed_name": "int Foo4", - "qual_name_offset": 4, - "short_name": "Foo4", - "declarations": [], - "spell": "17:5-17:9|-1|1|2", - "extent": "17:1-17:9|-1|1|0", - "type": 5, - "uses": [], - "kind": 13, - "storage": 1 - }, { - "id": 4, "usr": 8395885290297540138, "detailed_name": "int Foo5", "qual_name_offset": 4, "short_name": "Foo5", "declarations": [], - "spell": "18:12-18:16|-1|1|2", - "extent": "18:1-18:16|-1|1|0", - "type": 5, + "spell": "18:12-18:16|0|1|2", + "extent": "18:1-18:16|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 3 + }, { + "usr": 17716334512218775320, + "detailed_name": "Foo3::B", + "qual_name_offset": 0, + "short_name": "B", + "hover": "Foo3::B = 1", + "declarations": [], + "spell": "15:16-15:17|4481210672785600703|2|2", + "extent": "15:16-15:17|4481210672785600703|2|0", + "type": 4481210672785600703, + "uses": [], + "kind": 22, + "storage": 0 }] } OUTPUT: impl.cc @@ -206,9 +200,7 @@ OUTPUT: impl.cc "resolved_path": "&header.h" }], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 5817708529036841195, "detailed_name": "void Impl()", "qual_name_offset": 5, @@ -216,15 +208,15 @@ OUTPUT: impl.cc "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:10|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:10|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:7|1|3|32"] + "callees": ["4:3-4:7|11650481237659640387|3|32"] }, { - "id": 1, "usr": 11650481237659640387, "detailed_name": "", "qual_name_offset": 0, @@ -232,12 +224,14 @@ OUTPUT: impl.cc "kind": 0, "storage": 0, "declarations": [], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:7|0|3|32"], + "uses": ["4:3-4:7|5817708529036841195|3|32"], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 1c67f9414..44e49cc63 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -9,26 +9,23 @@ OUTPUT: simple_header.h { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 16236105532929924676, "detailed_name": "void header()", "qual_name_offset": 5, "short_name": "header", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "3:6-3:12|-1|1|1", - "param_spellings": [] - }], + "declarations": ["3:6-3:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } OUTPUT: simple_impl.cc { @@ -37,9 +34,7 @@ OUTPUT: simple_impl.cc "resolved_path": "&simple_header.h" }], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 3373269392705484958, "detailed_name": "void impl()", "qual_name_offset": 5, @@ -47,15 +42,15 @@ OUTPUT: simple_impl.cc "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:10|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:10|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:9|1|3|32"] + "callees": ["4:3-4:9|16236105532929924676|3|32"] }, { - "id": 1, "usr": 16236105532929924676, "detailed_name": "", "qual_name_offset": 0, @@ -63,12 +58,14 @@ OUTPUT: simple_impl.cc "kind": 0, "storage": 0, "declarations": [], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:9|0|3|32"], + "uses": ["4:3-4:9|3373269392705484958|3|32"], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index c5cfebcc1..88d473795 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -7,86 +7,81 @@ OUTPUT: static.h { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 14576076421851654759, + "detailed_name": "void Buffer::CreateSharedBuffer()", + "qual_name_offset": 5, + "short_name": "CreateSharedBuffer", + "kind": 254, + "storage": 3, + "declarations": ["4:15-4:33|9411323049603567600|2|1"], + "declaring_type": 9411323049603567600, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 9411323049603567600, "detailed_name": "Buffer", "qual_name_offset": 0, "short_name": "Buffer", "kind": 23, "declarations": [], - "spell": "3:8-3:14|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:8-3:14|0|1|2", + "extent": "3:1-5:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [14576076421851654759], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, + "usr2var": [] +} +OUTPUT: static.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&static.h" + }], + "skipped_by_preprocessor": [], + "usr2func": [{ "usr": 14576076421851654759, "detailed_name": "void Buffer::CreateSharedBuffer()", "qual_name_offset": 5, "short_name": "CreateSharedBuffer", "kind": 254, - "storage": 3, - "declarations": [{ - "spell": "4:15-4:33|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "storage": 1, + "declarations": [], + "spell": "3:14-3:32|9411323049603567600|2|2", + "extent": "3:1-3:37|0|1|0", + "declaring_type": 9411323049603567600, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] -} -OUTPUT: static.cc -{ - "includes": [{ - "line": 0, - "resolved_path": "&static.h" - }], - "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2type": [{ "usr": 9411323049603567600, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [14576076421851654759], "vars": [], "instances": [], - "uses": ["3:6-3:12|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 14576076421851654759, - "detailed_name": "void Buffer::CreateSharedBuffer()", - "qual_name_offset": 5, - "short_name": "CreateSharedBuffer", - "kind": 254, - "storage": 1, - "declarations": [], - "spell": "3:14-3:32|0|2|2", - "extent": "3:1-3:37|-1|1|0", - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": ["3:6-3:12|0|1|4"] }], - "vars": [] + "usr2var": [] } */ \ No newline at end of file diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 878cb81a2..bc7668e1b 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -7,41 +7,37 @@ void foo(); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 5010253035933134245, + "detailed_name": "void (anon ns)::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": ["2:6-2:9|7144845543074395457|2|1"], + "declaring_type": 7144845543074395457, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 7144845543074395457, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [5010253035933134245], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 5010253035933134245, - "detailed_name": "void (anon ns)::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "2:6-2:9|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 18f81f7ca..a9adedeee 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -7,58 +7,54 @@ void foo(int a, int b); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 18343102288837190527, + "detailed_name": "void hello::foo(int a, int b)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": ["2:6-2:9|2029211996748007610|2|1"], + "declaring_type": 2029211996748007610, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "hello", "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], - "spell": "1:11-1:16|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:16|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], - "funcs": [0], + "funcs": [18343102288837190527], "vars": [], "instances": [], - "uses": ["1:11-1:16|-1|1|4"] + "uses": ["1:11-1:16|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [2029211996748007610], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 18343102288837190527, - "detailed_name": "void hello::foo(int a, int b)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "2:6-2:9|0|2|1", - "param_spellings": ["2:14-2:15", "2:21-2:22"] - }], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index 1ae23ab38..7430cbdf8 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -7,57 +7,56 @@ void foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 243328841292951622, + "detailed_name": "void hello::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "2:6-2:9|2029211996748007610|2|2", + "extent": "2:1-2:14|2029211996748007610|2|0", + "declaring_type": 2029211996748007610, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "hello", "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], - "spell": "1:11-1:16|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:16|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], - "funcs": [0], + "funcs": [243328841292951622], "vars": [], "instances": [], - "uses": ["1:11-1:16|-1|1|4"] + "uses": ["1:11-1:16|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [2029211996748007610], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 243328841292951622, - "detailed_name": "void hello::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "2:6-2:9|0|2|2", - "extent": "2:1-2:14|0|2|0", - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index d66e1ab37..be6dd3a47 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -9,75 +9,71 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["3:8-3:11|4508214972876735896|2|1"], + "declaring_type": 4508214972876735896, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "hello", "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], - "spell": "1:11-1:16|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:16|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|-1|1|4"] + "uses": ["1:11-1:16|0|1|4"] }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", + "usr": 4508214972876735896, + "detailed_name": "hello::Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], + "spell": "2:7-2:10|2029211996748007610|2|2", + "extent": "2:1-4:2|2029211996748007610|2|0", + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [], "types": [], - "funcs": [], + "funcs": [10487325150128053272], "vars": [], "instances": [], "uses": [] }, { - "id": 2, - "usr": 4508214972876735896, - "detailed_name": "hello::Foo", + "usr": 13838176792705659279, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "2:7-2:10|0|2|2", - "extent": "2:1-4:2|0|2|0", + "alias_of": 0, "bases": [], - "derived": [], + "derived": [2029211996748007610], "types": [], - "funcs": [0], + "funcs": [], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 10487325150128053272, - "detailed_name": "void hello::Foo::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "3:8-3:11|2|2|1", - "param_spellings": [] - }], - "declaring_type": 2, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 2149a0377..2b532db00 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -11,77 +11,73 @@ void Foo::foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["3:8-3:11|4508214972876735896|2|1"], + "spell": "6:11-6:14|4508214972876735896|2|2", + "extent": "6:1-6:19|2029211996748007610|2|0", + "declaring_type": 4508214972876735896, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "hello", "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], - "spell": "1:11-1:16|-1|1|2", - "extent": "1:1-7:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:16|0|1|2", + "extent": "1:1-7:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|-1|1|4"] - }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [0], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] + "uses": ["1:11-1:16|0|1|4"] }, { - "id": 2, "usr": 4508214972876735896, "detailed_name": "hello::Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|0|2|2", - "extent": "2:1-4:2|0|2|0", + "spell": "2:7-2:10|2029211996748007610|2|2", + "extent": "2:1-4:2|2029211996748007610|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [10487325150128053272], "vars": [], "instances": [], - "uses": ["6:6-6:9|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 10487325150128053272, - "detailed_name": "void hello::Foo::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "3:8-3:11|2|2|1", - "param_spellings": [] - }], - "spell": "6:11-6:14|2|2|2", - "extent": "6:1-6:19|0|2|0", - "declaring_type": 2, + "uses": ["6:6-6:9|0|1|4"] + }, { + "usr": 13838176792705659279, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], - "derived": [], + "derived": [2029211996748007610], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": [] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index d38f8f8cf..b531b512a 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -9,74 +9,73 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 10487325150128053272, + "detailed_name": "void hello::Foo::foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": [], + "spell": "3:8-3:11|4508214972876735896|2|2", + "extent": "3:3-3:16|4508214972876735896|2|0", + "declaring_type": 4508214972876735896, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "hello", "qual_name_offset": 0, "short_name": "hello", "kind": 3, "declarations": [], - "spell": "1:11-1:16|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:16|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|-1|1|4"] - }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [0], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] + "uses": ["1:11-1:16|0|1|4"] }, { - "id": 2, "usr": 4508214972876735896, "detailed_name": "hello::Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|0|2|2", - "extent": "2:1-4:2|0|2|0", + "spell": "2:7-2:10|2029211996748007610|2|2", + "extent": "2:1-4:2|2029211996748007610|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [10487325150128053272], "vars": [], "instances": [], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 10487325150128053272, - "detailed_name": "void hello::Foo::foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 6, - "storage": 1, + }, { + "usr": 13838176792705659279, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "3:8-3:11|2|2|2", - "extent": "3:3-3:16|2|2|0", - "declaring_type": 2, + "alias_of": 0, "bases": [], - "derived": [], + "derived": [2029211996748007610], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": [] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 15cf5c652..8a7e8ef68 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -18,164 +18,161 @@ void func() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 926793467007732869, - "detailed_name": "foo", - "qual_name_offset": 0, - "short_name": "foo", - "kind": 3, + "usr2func": [{ + "usr": 10818727483146447186, + "detailed_name": "void func()", + "qual_name_offset": 5, + "short_name": "func", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:11-1:14|-1|1|2", - "extent": "1:1-7:2|-1|1|0", - "bases": [1], - "derived": [2], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["1:11-1:14|-1|1|4", "9:17-9:20|-1|1|4", "12:11-12:14|0|3|4"] - }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", + "spell": "11:6-11:10|0|1|2", + "extent": "11:1-14:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [6030927277961448585, 7657277353101371136], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [15042442838933090518, 6030927277961448585, 7657277353101371136], "uses": [] }, { - "id": 2, - "usr": 17805385787823406700, - "detailed_name": "foo::bar", + "usr": 926793467007732869, + "detailed_name": "foo", "qual_name_offset": 0, - "short_name": "bar", + "short_name": "foo", "kind": 3, "declarations": [], - "spell": "2:15-2:18|0|2|2", - "extent": "2:5-6:6|0|2|0", - "bases": [0], - "derived": [3], + "spell": "1:11-1:14|0|1|2", + "extent": "1:1-7:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], + "derived": [17805385787823406700], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["2:15-2:18|0|2|4", "9:22-9:25|-1|1|4", "12:16-12:19|0|3|4"] + "uses": ["1:11-1:14|0|1|4", "9:17-9:20|0|1|4", "12:11-12:14|10818727483146447186|3|4"] }, { - "id": 3, - "usr": 14450849931009540802, - "detailed_name": "foo::bar::baz", + "usr": 11879713791858506216, + "detailed_name": "fbz", "qual_name_offset": 0, - "short_name": "baz", - "kind": 3, + "short_name": "fbz", + "kind": 0, "declarations": [], - "spell": "3:20-3:23|2|2|2", - "extent": "3:10-5:11|2|2|0", - "bases": [2], + "spell": "9:11-9:14|0|1|2", + "extent": "9:1-9:30|0|1|0", + "alias_of": 0, + "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], + "vars": [], "instances": [], - "uses": ["3:20-3:23|2|2|4", "9:27-9:30|-1|1|4", "12:21-12:24|0|3|4"] + "uses": ["13:11-13:14|10818727483146447186|3|4"] }, { - "id": 4, - "usr": 17, + "usr": 13838176792705659279, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [], + "derived": [926793467007732869], "types": [], "funcs": [], "vars": [], - "instances": [0, 1, 2], + "instances": [], "uses": [] }, { - "id": 5, - "usr": 11879713791858506216, - "detailed_name": "fbz", + "usr": 14450849931009540802, + "detailed_name": "foo::bar::baz", "qual_name_offset": 0, - "short_name": "fbz", - "kind": 0, + "short_name": "baz", + "kind": 3, "declarations": [], - "spell": "9:11-9:14|-1|1|2", - "extent": "9:1-9:30|-1|1|0", - "bases": [], + "spell": "3:20-3:23|17805385787823406700|2|2", + "extent": "3:10-5:11|17805385787823406700|2|0", + "alias_of": 0, + "bases": [17805385787823406700], "derived": [], "types": [], "funcs": [], - "vars": [], + "vars": [15042442838933090518], "instances": [], - "uses": ["13:11-13:14|0|3|4"] - }], - "funcs": [{ - "id": 0, - "usr": 10818727483146447186, - "detailed_name": "void func()", - "qual_name_offset": 5, - "short_name": "func", - "kind": 12, - "storage": 1, + "uses": ["3:20-3:23|17805385787823406700|2|4", "9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] + }, { + "usr": 17805385787823406700, + "detailed_name": "foo::bar", + "qual_name_offset": 0, + "short_name": "bar", + "kind": 3, "declarations": [], - "spell": "11:6-11:10|-1|1|2", - "extent": "11:1-14:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [1, 2], - "uses": [], - "callees": [] + "spell": "2:15-2:18|926793467007732869|2|2", + "extent": "2:5-6:6|926793467007732869|2|0", + "alias_of": 0, + "bases": [926793467007732869], + "derived": [14450849931009540802], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:15-2:18|926793467007732869|2|4", "9:22-9:25|0|1|4", "12:16-12:19|10818727483146447186|3|4"] }], - "vars": [{ - "id": 0, - "usr": 15042442838933090518, - "detailed_name": "int foo::bar::baz::qux", - "qual_name_offset": 4, - "short_name": "qux", - "hover": "int foo::bar::baz::qux = 42", - "declarations": [], - "spell": "4:18-4:21|3|2|2", - "extent": "4:14-4:26|3|2|0", - "type": 4, - "uses": ["12:26-12:29|-1|1|4", "13:16-13:19|-1|1|4"], - "kind": 13, - "storage": 1 - }, { - "id": 1, - "usr": 107714981785063096, + "usr2var": [{ + "usr": 6030927277961448585, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = foo::bar::baz::qux", "declarations": [], - "spell": "12:7-12:8|0|3|2", - "extent": "12:3-12:29|0|3|0", - "type": 4, + "spell": "12:7-12:8|10818727483146447186|3|2", + "extent": "12:3-12:29|10818727483146447186|3|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 2, - "usr": 1200087780658383286, + "usr": 7657277353101371136, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", "hover": "int b = fbz::qux", "declarations": [], - "spell": "13:7-13:8|0|3|2", - "extent": "13:3-13:19|0|3|0", - "type": 4, + "spell": "13:7-13:8|10818727483146447186|3|2", + "extent": "13:3-13:19|10818727483146447186|3|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 + }, { + "usr": 15042442838933090518, + "detailed_name": "int foo::bar::baz::qux", + "qual_name_offset": 4, + "short_name": "qux", + "hover": "int foo::bar::baz::qux = 42", + "declarations": [], + "spell": "4:18-4:21|14450849931009540802|2|2", + "extent": "4:14-4:26|14450849931009540802|2|0", + "type": 17, + "uses": ["12:26-12:29|0|1|4", "13:16-13:19|0|1|4"], + "kind": 13, + "storage": 1 }] } */ diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 5636a6f43..3ffedd6d5 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -14,114 +14,111 @@ void Runner() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, - "short_name": "ns", - "kind": 3, + "usr2func": [{ + "usr": 631910859630953711, + "detailed_name": "void Runner()", + "qual_name_offset": 5, + "short_name": "Runner", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:11-1:13|-1|1|2", - "extent": "1:1-4:2|-1|1|0", - "bases": [1], + "spell": "6:6-6:12|0|1|2", + "extent": "6:1-10:2|0|1|0", + "declaring_type": 0, + "bases": [], "derived": [], - "types": [], - "funcs": [0], - "vars": [0], - "instances": [], - "uses": ["1:11-1:13|-1|1|4", "7:3-7:5|1|3|4", "7:14-7:16|1|3|4", "8:19-8:21|1|3|4"] + "vars": [], + "uses": [], + "callees": ["7:7-7:13|17328473273923617489|3|32", "9:3-9:9|17328473273923617489|3|32"] }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", + "usr": 17328473273923617489, + "detailed_name": "void ns::Accept(int a)", + "qual_name_offset": 5, + "short_name": "Accept", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:8-3:14|11072669167287398027|2|2", + "extent": "3:3-3:24|11072669167287398027|2|0", + "declaring_type": 11072669167287398027, + "bases": [], + "derived": [], + "vars": [3649375698083002347], + "uses": ["7:7-7:13|631910859630953711|3|32", "9:3-9:9|631910859630953711|3|32"], + "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [12898699035586282159, 3649375698083002347], "uses": [] }, { - "id": 2, - "usr": 17, + "usr": 11072669167287398027, + "detailed_name": "ns", + "qual_name_offset": 0, + "short_name": "ns", + "kind": 3, + "declarations": [], + "spell": "1:11-1:13|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], + "derived": [], + "types": [], + "funcs": [17328473273923617489], + "vars": [12898699035586282159], + "instances": [], + "uses": ["1:11-1:13|0|1|4", "7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] + }, { + "usr": 13838176792705659279, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 17328473273923617489, - "detailed_name": "void ns::Accept(int a)", - "qual_name_offset": 5, - "short_name": "Accept", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "3:8-3:14|0|2|2", - "extent": "3:3-3:24|0|2|0", - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [1], - "uses": ["7:7-7:13|1|3|32", "9:3-9:9|1|3|32"], - "callees": [] - }, { - "id": 1, - "usr": 631910859630953711, - "detailed_name": "void Runner()", - "qual_name_offset": 5, - "short_name": "Runner", - "kind": 12, - "storage": 1, + "usr2var": [{ + "usr": 3649375698083002347, + "detailed_name": "int a", + "qual_name_offset": 4, + "short_name": "a", "declarations": [], - "spell": "6:6-6:12|-1|1|2", - "extent": "6:1-10:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [], + "spell": "3:19-3:20|17328473273923617489|3|2", + "extent": "3:15-3:20|17328473273923617489|3|0", + "type": 17, "uses": [], - "callees": ["7:7-7:13|0|3|32", "9:3-9:9|0|3|32"] - }], - "vars": [{ - "id": 0, + "kind": 253, + "storage": 1 + }, { "usr": 12898699035586282159, "detailed_name": "int ns::Foo", "qual_name_offset": 4, "short_name": "Foo", "declarations": [], - "spell": "2:7-2:10|0|2|2", - "extent": "2:3-2:10|0|2|0", - "type": 2, - "uses": ["7:18-7:21|1|3|4", "9:10-9:13|1|3|4"], + "spell": "2:7-2:10|11072669167287398027|2|2", + "extent": "2:3-2:10|11072669167287398027|2|0", + "type": 17, + "uses": ["7:18-7:21|631910859630953711|3|4", "9:10-9:13|631910859630953711|3|4"], "kind": 13, "storage": 1 - }, { - "id": 1, - "usr": 7976909968919750794, - "detailed_name": "int a", - "qual_name_offset": 4, - "short_name": "a", - "declarations": [], - "spell": "3:19-3:20|0|3|2", - "extent": "3:15-3:20|0|3|0", - "type": 2, - "uses": [], - "kind": 253, - "storage": 1 }] } */ diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 0624270b3..e44fa5bdc 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -11,95 +11,83 @@ Foo &operator += (const Foo&, const int&); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-5:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0, 1, 2], - "vars": [], - "instances": [], - "uses": ["7:1-7:4|-1|1|4", "7:25-7:28|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 7874436189163837815, - "detailed_name": "void Foo::operator()(int)", + "usr2func": [{ + "usr": 3545323327609582678, + "detailed_name": "void Foo::operator()(bool)", "qual_name_offset": 5, "short_name": "operator()", "kind": 6, "storage": 1, - "declarations": [], - "spell": "2:8-2:18|0|2|2", - "extent": "2:3-2:27|0|2|0", - "declaring_type": 0, + "declarations": ["3:8-3:18|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 1, - "usr": 3545323327609582678, - "detailed_name": "void Foo::operator()(bool)", - "qual_name_offset": 5, + "usr": 3986818119971932909, + "detailed_name": "int Foo::operator()(int a, int b)", + "qual_name_offset": 4, "short_name": "operator()", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "3:8-3:18|0|2|1", - "param_spellings": ["3:23-3:23"] - }], - "declaring_type": 0, + "declarations": ["4:7-4:17|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 2, - "usr": 3986818119971932909, - "detailed_name": "int Foo::operator()(int a, int b)", - "qual_name_offset": 4, + "usr": 7874436189163837815, + "detailed_name": "void Foo::operator()(int)", + "qual_name_offset": 5, "short_name": "operator()", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "4:7-4:17|0|2|1", - "param_spellings": ["4:22-4:23", "4:29-4:30"] - }], - "declaring_type": 0, + "declarations": [], + "spell": "2:8-2:18|15041163540773201510|2|2", + "extent": "2:3-2:27|15041163540773201510|2|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 3, "usr": 8288368475529136092, "detailed_name": "Foo &operator+=(const Foo &, const int &)", "qual_name_offset": 5, "short_name": "operator+=", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "7:6-7:17|-1|1|1", - "param_spellings": ["7:29-7:29", "7:41-7:41"] - }], + "declarations": ["7:6-7:17|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [7874436189163837815, 3545323327609582678, 3986818119971932909], + "vars": [], + "instances": [], + "uses": ["7:1-7:4|0|1|4", "7:25-7:28|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 7782eea6b..62f99811f 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -11,190 +11,184 @@ OUTPUT: static_function_in_type.h { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 17019747379608639279, + "detailed_name": "void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 5, + "short_name": "Register", + "kind": 254, + "storage": 3, + "declarations": ["6:15-6:23|17262466801709381811|2|1"], + "declaring_type": 17262466801709381811, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 1972401196751872203, + "detailed_name": "ns::Manager", + "qual_name_offset": 0, + "short_name": "Manager", + "kind": 5, + "declarations": ["3:7-3:14|11072669167287398027|2|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["6:24-6:31|0|1|4"] + }, { "usr": 11072669167287398027, "detailed_name": "ns", "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], - "spell": "1:11-1:13|-1|1|2", - "extent": "1:1-9:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:13|0|1|2", + "extent": "1:1-9:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:13|-1|1|4"] + "uses": ["1:11-1:13|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }, { - "id": 2, - "usr": 1972401196751872203, - "detailed_name": "ns::Manager", - "qual_name_offset": 0, - "short_name": "Manager", - "kind": 5, - "declarations": ["3:7-3:14|0|2|1"], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["6:24-6:31|-1|1|4"] - }, { - "id": 3, "usr": 17262466801709381811, "detailed_name": "ns::Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|0|2|2", - "extent": "5:1-7:2|0|2|0", + "spell": "5:8-5:11|11072669167287398027|2|2", + "extent": "5:1-7:2|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [17019747379608639279], "vars": [], "instances": [], "uses": [] }], - "funcs": [{ - "id": 0, + "usr2var": [] +} +OUTPUT: static_function_in_type.cc +{ + "includes": [{ + "line": 0, + "resolved_path": "&static_function_in_type.h" + }], + "skipped_by_preprocessor": [], + "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "void ns::Foo::Register(ns::Manager *)", + "detailed_name": "void ns::Foo::Register(ns::Manager *m)", "qual_name_offset": 5, "short_name": "Register", "kind": 254, - "storage": 3, - "declarations": [{ - "spell": "6:15-6:23|3|2|1", - "param_spellings": ["6:32-6:32"] - }], - "declaring_type": 3, + "storage": 1, + "declarations": [], + "spell": "5:11-5:19|17262466801709381811|2|2", + "extent": "5:1-6:2|11072669167287398027|2|0", + "declaring_type": 17262466801709381811, "bases": [], "derived": [], - "vars": [], + "vars": [13569879755236306838], "uses": [], "callees": [] }], - "vars": [] -} -OUTPUT: static_function_in_type.cc -{ - "includes": [{ - "line": 0, - "resolved_path": "&static_function_in_type.h" - }], - "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2type": [{ + "usr": 1972401196751872203, + "detailed_name": "ns::Manager", + "qual_name_offset": 0, + "short_name": "Manager", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [13569879755236306838], + "uses": ["5:20-5:27|0|1|4"] + }, { "usr": 11072669167287398027, "detailed_name": "ns", "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], - "spell": "3:11-3:13|-1|1|2", - "extent": "3:1-7:2|-1|1|0", - "bases": [1], + "spell": "3:11-3:13|0|1|2", + "extent": "3:1-7:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["3:11-3:13|-1|1|4"] + "uses": ["3:11-3:13|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }, { - "id": 2, "usr": 17262466801709381811, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [17019747379608639279], "vars": [], "instances": [], - "uses": ["5:6-5:9|-1|1|4"] - }, { - "id": 3, - "usr": 1972401196751872203, - "detailed_name": "ns::Manager", - "qual_name_offset": 0, - "short_name": "Manager", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": ["5:20-5:27|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 17019747379608639279, - "detailed_name": "void ns::Foo::Register(ns::Manager *m)", - "qual_name_offset": 5, - "short_name": "Register", - "kind": 254, - "storage": 1, - "declarations": [], - "spell": "5:11-5:19|2|2|2", - "extent": "5:1-6:2|0|2|0", - "declaring_type": 2, - "bases": [], - "derived": [], - "vars": [0], - "uses": [], - "callees": [] + "uses": ["5:6-5:9|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 9285345059965948351, + "usr2var": [{ + "usr": 13569879755236306838, "detailed_name": "ns::Manager *m", "qual_name_offset": 13, "short_name": "m", "declarations": [], - "spell": "5:29-5:30|0|3|2", - "extent": "5:20-5:30|0|3|0", - "type": 3, + "spell": "5:29-5:30|17019747379608639279|3|2", + "extent": "5:20-5:30|17019747379608639279|3|0", + "type": 1972401196751872203, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 33a82ca34..5a123d894 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -8,18 +8,18 @@ { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 13076155634261037336, + "usr2func": [], + "usr2type": [], + "usr2var": [{ + "usr": 11674328179498211370, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO", "declarations": [], - "spell": "2:9-2:12|-1|1|2", - "extent": "2:9-2:12|-1|1|0", + "spell": "2:9-2:12|0|1|2", + "extent": "2:9-2:12|0|1|0", + "type": 0, "uses": [], "kind": 255, "storage": 0 diff --git a/index_tests/preprocessor/skipped.cc b/index_tests/preprocessor/skipped.cc index 41cb3c341..c4345e170 100644 --- a/index_tests/preprocessor/skipped.cc +++ b/index_tests/preprocessor/skipped.cc @@ -18,8 +18,8 @@ void hello(); { "includes": [], "skipped_by_preprocessor": ["2:1-4:7", "6:1-10:7", "12:1-14:7"], - "types": [], - "funcs": [], - "vars": [] + "usr2func": [], + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index d1da2699e..c1f4deaa0 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -12,62 +12,58 @@ void Foo::Bar(Template&) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17107291254533526269, - "detailed_name": "Template", - "qual_name_offset": 0, - "short_name": "Template", - "kind": 5, - "declarations": [], - "spell": "2:7-2:15|-1|1|2", - "extent": "2:1-2:18|-1|1|0", + "usr2func": [{ + "usr": 8412238651648388423, + "detailed_name": "void Foo::Bar(Template &)", + "qual_name_offset": 5, + "short_name": "Bar", + "kind": 6, + "storage": 1, + "declarations": ["5:8-5:11|15041163540773201510|2|1"], + "spell": "8:11-8:14|15041163540773201510|2|2", + "extent": "8:1-8:36|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["5:12-5:20|-1|1|4", "8:15-8:23|-1|1|4"] - }, { - "id": 1, + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "4:8-4:11|-1|1|2", - "extent": "4:1-6:2|-1|1|0", + "spell": "4:8-4:11|0|1|2", + "extent": "4:1-6:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [8412238651648388423], "vars": [], "instances": [], - "uses": ["8:6-8:9|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 8412238651648388423, - "detailed_name": "void Foo::Bar(Template &)", - "qual_name_offset": 5, - "short_name": "Bar", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "5:8-5:11|1|2|1", - "param_spellings": ["5:29-5:29"] - }], - "spell": "8:11-8:14|1|2|2", - "extent": "8:1-8:36|-1|1|0", - "declaring_type": 1, + "uses": ["8:6-8:9|0|1|4"] + }, { + "usr": 17107291254533526269, + "detailed_name": "Template", + "qual_name_offset": 0, + "short_name": "Template", + "kind": 5, + "declarations": [], + "spell": "2:7-2:15|0|1|2", + "extent": "2:1-2:18|0|1|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["5:12-5:20|0|1|4", "8:15-8:23|0|1|4"] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index c268b2903..845721cb8 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -19,143 +19,140 @@ namespace ns { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, - "short_name": "ns", - "kind": 3, - "declarations": [], - "spell": "1:11-1:13|-1|1|2", - "extent": "1:1-15:2|-1|1|0", - "bases": [1], - "derived": [], - "types": [], - "funcs": [], - "vars": [1, 2], - "instances": [], - "uses": ["1:11-1:13|-1|1|4"] - }, { - "id": 1, - "usr": 13838176792705659279, - "detailed_name": "", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [12898699035586282159, 9008550860229740818], "uses": [] }, { - "id": 2, "usr": 1532099849728741556, "detailed_name": "ns::VarType", "qual_name_offset": 0, "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "2:8-2:15|0|2|2", - "extent": "2:3-2:18|0|2|0", + "spell": "2:8-2:15|11072669167287398027|2|2", + "extent": "2:3-2:18|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["6:22-6:29|-1|1|4", "6:44-6:51|-1|1|4", "10:18-10:25|-1|1|4"] + "instances": [4731849186641714451], + "uses": ["6:22-6:29|0|1|4", "6:44-6:51|0|1|4", "10:18-10:25|0|1|4"] }, { - "id": 3, - "usr": 12688716854043726585, - "detailed_name": "ns::Holder", + "usr": 2205716167465743256, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Holder", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "5:10-5:16|0|2|2", - "extent": "5:3-7:4|0|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], + "vars": [], "instances": [], - "uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"] + "uses": ["10:33-10:34|0|1|4"] }, { - "id": 4, - "usr": 14511917000226829276, - "detailed_name": "", + "usr": 11072669167287398027, + "detailed_name": "ns", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "ns", + "kind": 3, "declarations": [], + "spell": "1:11-1:13|0|1|2", + "extent": "1:1-15:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], + "derived": [], + "types": [], + "funcs": [], + "vars": [12898699035586282159, 9008550860229740818], + "instances": [], + "uses": ["1:11-1:13|0|1|4"] + }, { + "usr": 12688716854043726585, + "detailed_name": "ns::Holder", + "qual_name_offset": 0, + "short_name": "Holder", + "kind": 5, + "declarations": [], + "spell": "5:10-5:16|11072669167287398027|2|2", + "extent": "5:3-7:4|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [], + "vars": [4731849186641714451], "instances": [], - "uses": ["10:33-10:34|-1|1|4"] + "uses": ["10:26-10:32|0|1|4", "13:13-13:19|0|1|4", "14:14-14:20|0|1|4"] }, { - "id": 5, - "usr": 17, + "usr": 13838176792705659279, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], - "instances": [1, 2], + "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 4731849186641714451, "detailed_name": "const ns::VarType ns::Holder::static_var", "qual_name_offset": 18, "short_name": "static_var", "hover": "const ns::VarType ns::Holder::static_var = (VarType)0x0", - "declarations": ["6:30-6:40|3|2|1"], - "spell": "10:37-10:47|3|2|2", - "extent": "9:3-10:47|0|2|0", - "type": 2, - "uses": ["13:26-13:36|-1|1|4", "14:27-14:37|-1|1|4"], + "declarations": ["6:30-6:40|12688716854043726585|2|1"], + "spell": "10:37-10:47|12688716854043726585|2|2", + "extent": "9:3-10:47|11072669167287398027|2|0", + "type": 1532099849728741556, + "uses": ["13:26-13:36|0|1|4", "14:27-14:37|0|1|4"], "kind": 8, "storage": 1 }, { - "id": 1, - "usr": 12898699035586282159, - "detailed_name": "int ns::Foo", + "usr": 9008550860229740818, + "detailed_name": "int ns::Foo2", "qual_name_offset": 4, - "short_name": "Foo", - "hover": "int ns::Foo = Holder::static_var", + "short_name": "Foo2", + "hover": "int ns::Foo2 = Holder::static_var", "declarations": [], - "spell": "13:7-13:10|0|2|2", - "extent": "13:3-13:36|0|2|0", - "type": 5, + "spell": "14:7-14:11|11072669167287398027|2|2", + "extent": "14:3-14:37|11072669167287398027|2|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 2, - "usr": 9008550860229740818, - "detailed_name": "int ns::Foo2", + "usr": 12898699035586282159, + "detailed_name": "int ns::Foo", "qual_name_offset": 4, - "short_name": "Foo2", - "hover": "int ns::Foo2 = Holder::static_var", + "short_name": "Foo", + "hover": "int ns::Foo = Holder::static_var", "declarations": [], - "spell": "14:7-14:11|0|2|2", - "extent": "14:3-14:37|0|2|0", - "type": 5, + "spell": "13:7-13:10|11072669167287398027|2|2", + "extent": "13:3-13:36|11072669167287398027|2|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index f3bed2b21..43c19f790 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -25,85 +25,81 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 6875364467121018690, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:9|0|1|2", + "extent": "8:1-8:11|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 8905286151237717330, + "detailed_name": "void C::bar()", + "qual_name_offset": 5, + "short_name": "bar", + "kind": 6, + "storage": 1, + "declarations": ["4:8-4:11|8402783583255987702|2|1"], + "declaring_type": 8402783583255987702, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 8402783583255987702, "detailed_name": "C", "qual_name_offset": 0, "short_name": "C", "kind": 5, "declarations": [], - "spell": "2:8-2:9|-1|1|2", - "extent": "2:1-5:2|-1|1|0", + "spell": "2:8-2:9|0|1|2", + "extent": "2:1-5:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], - "vars": [0], + "funcs": [8905286151237717330], + "vars": [5866801090710377175], "instances": [], "uses": [] }, { - "id": 1, "usr": 14750650276757822712, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", "kind": 26, "declarations": [], - "spell": "1:17-1:18|-1|1|2", - "extent": "1:11-1:18|-1|1|0", + "spell": "1:17-1:18|0|1|2", + "extent": "1:11-1:18|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["3:3-3:4|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 8905286151237717330, - "detailed_name": "void C::bar()", - "qual_name_offset": 5, - "short_name": "bar", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "4:8-4:11|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 1, - "usr": 6875364467121018690, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "8:6-8:9|-1|1|2", - "extent": "8:1-8:11|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": ["3:3-3:4|0|1|4"] }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 5866801090710377175, "detailed_name": "T C::x", "qual_name_offset": 2, "short_name": "x", "declarations": [], - "spell": "3:5-3:6|0|2|2", - "extent": "3:3-3:6|0|2|0", + "spell": "3:5-3:6|8402783583255987702|2|2", + "extent": "3:3-3:6|8402783583255987702|2|0", + "type": 0, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index da7af9dd0..3880a11db 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -16,114 +16,111 @@ namespace ns { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 8221803074608342407, + "detailed_name": "int ns::Foo::foo()", + "qual_name_offset": 4, + "short_name": "foo", + "kind": 254, + "storage": 3, + "declarations": [], + "spell": "5:16-5:19|14042997404480181958|2|2", + "extent": "5:5-7:6|14042997404480181958|2|0", + "declaring_type": 14042997404480181958, + "bases": [], + "derived": [], + "vars": [], + "uses": ["10:21-10:24|11072669167287398027|2|32", "11:22-11:25|11072669167287398027|2|32"], + "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [15768138241775955040, 3182917058194750998], + "uses": [] + }, { "usr": 11072669167287398027, "detailed_name": "ns", "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], - "spell": "1:11-1:13|-1|1|2", - "extent": "1:1-12:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:13|0|1|2", + "extent": "1:1-12:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], - "vars": [0, 1], + "vars": [15768138241775955040, 3182917058194750998], "instances": [], - "uses": ["1:11-1:13|-1|1|4"] + "uses": ["1:11-1:13|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }, { - "id": 2, "usr": 14042997404480181958, "detailed_name": "ns::Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "3:10-3:13|0|2|2", - "extent": "3:3-8:4|0|2|0", + "spell": "3:10-3:13|11072669167287398027|2|2", + "extent": "3:3-8:4|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [0], + "funcs": [8221803074608342407], "vars": [], "instances": [], - "uses": ["10:11-10:14|-1|1|4", "11:11-11:14|-1|1|4"] - }, { - "id": 3, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 8221803074608342407, - "detailed_name": "int ns::Foo::foo()", - "qual_name_offset": 4, - "short_name": "foo", - "kind": 254, - "storage": 3, - "declarations": [], - "spell": "5:16-5:19|2|2|2", - "extent": "5:5-7:6|2|2|0", - "declaring_type": 2, - "bases": [], - "derived": [], - "vars": [], - "uses": ["10:21-10:24|0|2|32", "11:22-11:25|0|2|32"], - "callees": [] + "uses": ["10:11-10:14|0|1|4", "11:11-11:14|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 15768138241775955040, - "detailed_name": "int ns::a", + "usr2var": [{ + "usr": 3182917058194750998, + "detailed_name": "int ns::b", "qual_name_offset": 4, - "short_name": "a", - "hover": "int ns::a = Foo::foo()", + "short_name": "b", + "hover": "int ns::b = Foo::foo()", "declarations": [], - "spell": "10:7-10:8|0|2|2", - "extent": "10:3-10:33|0|2|0", - "type": 3, + "spell": "11:7-11:8|11072669167287398027|2|2", + "extent": "11:3-11:35|11072669167287398027|2|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 3182917058194750998, - "detailed_name": "int ns::b", + "usr": 15768138241775955040, + "detailed_name": "int ns::a", "qual_name_offset": 4, - "short_name": "b", - "hover": "int ns::b = Foo::foo()", + "short_name": "a", + "hover": "int ns::a = Foo::foo()", "declarations": [], - "spell": "11:7-11:8|0|2|2", - "extent": "11:3-11:35|0|2|0", - "type": 3, + "spell": "10:7-10:8|11072669167287398027|2|2", + "extent": "10:3-10:33|11072669167287398027|2|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index c1a8ae9d6..4c00e09ab 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -11,80 +11,78 @@ namespace ns { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 11072669167287398027, "detailed_name": "ns", "qual_name_offset": 0, "short_name": "ns", "kind": 3, "declarations": [], - "spell": "1:11-1:13|-1|1|2", - "extent": "1:1-7:2|-1|1|0", - "bases": [1], + "spell": "1:11-1:13|0|1|2", + "extent": "1:1-7:2|0|1|0", + "alias_of": 0, + "bases": [13838176792705659279], "derived": [], "types": [], "funcs": [], - "vars": [0, 1], + "vars": [15768138241775955040, 3182917058194750998], "instances": [], - "uses": ["1:11-1:13|-1|1|4"] + "uses": ["1:11-1:13|0|1|4"] }, { - "id": 1, "usr": 13838176792705659279, - "detailed_name": "", + "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], - "derived": [0], + "derived": [11072669167287398027], "types": [], "funcs": [], "vars": [], "instances": [], "uses": [] }, { - "id": 2, "usr": 14042997404480181958, "detailed_name": "ns::Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "3:9-3:12|0|2|2", - "extent": "3:3-3:15|0|2|0", + "spell": "3:9-3:12|11072669167287398027|2|2", + "extent": "3:3-3:15|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], - "uses": ["5:3-5:6|-1|1|4", "6:3-6:6|-1|1|4"] + "instances": [15768138241775955040, 3182917058194750998], + "uses": ["5:3-5:6|0|1|4", "6:3-6:6|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 15768138241775955040, - "detailed_name": "Foo ns::a", - "qual_name_offset": 9, - "short_name": "a", + "usr2var": [{ + "usr": 3182917058194750998, + "detailed_name": "Foo ns::b", + "qual_name_offset": 10, + "short_name": "b", "declarations": [], - "spell": "5:12-5:13|0|2|2", - "extent": "5:3-5:13|0|2|0", - "type": 2, + "spell": "6:13-6:14|11072669167287398027|2|2", + "extent": "6:3-6:14|11072669167287398027|2|0", + "type": 14042997404480181958, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 3182917058194750998, - "detailed_name": "Foo ns::b", - "qual_name_offset": 10, - "short_name": "b", + "usr": 15768138241775955040, + "detailed_name": "Foo ns::a", + "qual_name_offset": 9, + "short_name": "a", "declarations": [], - "spell": "6:13-6:14|0|2|2", - "extent": "6:3-6:14|0|2|0", - "type": 2, + "spell": "5:12-5:13|11072669167287398027|2|2", + "extent": "5:3-5:13|11072669167287398027|2|0", + "type": 14042997404480181958, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 0d667a2d6..e788e7b64 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -47,416 +47,397 @@ void foo(float Value); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15019211479263750068, - "detailed_name": "function", + "usr2func": [{ + "usr": 6113470698424012876, + "detailed_name": "void vector::clear()", + "qual_name_offset": 5, + "short_name": "clear", + "kind": 6, + "storage": 1, + "declarations": ["27:8-27:13|1663022413889915338|2|1"], + "declaring_type": 1663022413889915338, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 17498190318698490707, + "detailed_name": "void foo(T Value)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": ["43:6-43:9|0|1|1"], + "spell": "39:6-39:9|0|1|2", + "extent": "39:1-39:21|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [17826688417349629938], + "uses": [], + "callees": [] + }, { + "usr": 18107614608385228556, + "detailed_name": "void vector::clear()", + "qual_name_offset": 5, + "short_name": "clear", + "kind": 6, + "storage": 1, + "declarations": ["13:8-13:13|7440942986741176606|2|1"], + "declaring_type": 7440942986741176606, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "function", - "kind": 5, - "declarations": ["2:7-2:15|-1|1|1", "5:7-5:15|-1|1|4"], - "spell": "2:7-2:15|-1|1|2", - "extent": "1:1-2:15|-1|1|0", + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], - "derived": [1], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["7:1-7:9|-1|1|4"] + "instances": [13914496963221806870], + "uses": [] }, { - "id": 1, "usr": 218068462278884837, "detailed_name": "function", "qual_name_offset": 0, "short_name": "function", "kind": 5, "declarations": [], - "spell": "5:7-5:15|-1|1|2", - "extent": "4:1-5:30|-1|1|0", - "bases": [0], + "spell": "5:7-5:15|0|1|2", + "extent": "4:1-5:30|0|1|0", + "alias_of": 0, + "bases": [15019211479263750068], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["7:1-7:9|-1|1|4"] + "instances": [2933643612409209903], + "uses": ["7:1-7:9|0|1|4"] }, { - "id": 2, - "usr": 10862637711685426953, - "detailed_name": "T", + "usr": 1663022413889915338, + "detailed_name": "vector", "qual_name_offset": 0, - "short_name": "T", - "kind": 26, + "short_name": "vector", + "kind": 5, "declarations": [], - "spell": "4:19-4:20|-1|1|2", - "extent": "4:10-4:20|-1|1|0", - "bases": [], + "spell": "26:7-26:13|0|1|2", + "extent": "25:1-28:2|0|1|0", + "alias_of": 0, + "bases": [7440942986741176606], "derived": [], "types": [], - "funcs": [], + "funcs": [6113470698424012876], "vars": [], "instances": [], - "uses": ["5:16-5:17|-1|1|4"] + "uses": [] }, { - "id": 3, - "usr": 756188769017350739, - "detailed_name": "Args", + "usr": 5760043510674081814, + "detailed_name": "Z1", "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, + "short_name": "Z1", + "kind": 23, "declarations": [], - "spell": "4:34-4:38|-1|1|2", - "extent": "4:22-4:38|-1|1|0", + "spell": "19:8-19:10|0|1|2", + "extent": "19:1-19:13|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["5:18-5:22|-1|1|4"] + "uses": ["32:8-32:10|0|1|4"] }, { - "id": 4, - "usr": 15695704394170757108, - "detailed_name": "allocator", + "usr": 7143192229126273961, + "detailed_name": "Args", "qual_name_offset": 0, - "short_name": "allocator", - "kind": 5, - "declarations": ["9:28-9:37|-1|1|1", "11:39-11:48|-1|1|4"], + "short_name": "Args", + "kind": 26, + "declarations": [], + "spell": "4:34-4:38|0|1|2", + "extent": "4:22-4:38|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["5:18-5:22|0|1|4"] }, { - "id": 5, "usr": 7440942986741176606, "detailed_name": "vector", "qual_name_offset": 0, "short_name": "vector", "kind": 5, - "declarations": ["17:7-17:13|-1|1|4", "26:7-26:13|-1|1|4"], - "spell": "12:7-12:13|-1|1|2", - "extent": "12:1-14:2|-1|1|0", + "declarations": ["17:7-17:13|0|1|4", "26:7-26:13|0|1|4"], + "spell": "12:7-12:13|0|1|2", + "extent": "12:1-14:2|0|1|0", + "alias_of": 0, "bases": [], - "derived": [6, 10], + "derived": [16155717907537731864, 1663022413889915338], "types": [], - "funcs": [0], + "funcs": [18107614608385228556], "vars": [], - "instances": [1, 3, 4], - "uses": ["30:1-30:7|-1|1|4", "31:1-31:7|-1|1|4", "32:1-32:7|-1|1|4", "33:1-33:7|-1|1|4"] + "instances": [5792869548777559988, 3566687051827176322, 15931696253641284761], + "uses": ["30:1-30:7|0|1|4", "31:1-31:7|0|1|4", "32:1-32:7|0|1|4", "33:1-33:7|0|1|4"] }, { - "id": 6, - "usr": 16155717907537731864, - "detailed_name": "vector", + "usr": 8880262253425334092, + "detailed_name": "T", "qual_name_offset": 0, - "short_name": "vector", - "kind": 5, + "short_name": "T", + "kind": 26, "declarations": [], - "spell": "17:7-17:13|-1|1|2", - "extent": "16:1-17:20|-1|1|0", - "bases": [5], + "spell": "16:19-16:20|0|1|2", + "extent": "16:10-16:20|0|1|0", + "alias_of": 0, + "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [2], - "uses": ["31:1-31:7|-1|1|4"] + "instances": [], + "uses": ["17:14-17:15|0|1|4"] }, { - "id": 7, - "usr": 3421332160420436276, - "detailed_name": "T", + "usr": 9201299975592934124, + "detailed_name": "Enum", "qual_name_offset": 0, - "short_name": "T", - "kind": 26, + "short_name": "Enum", + "kind": 10, "declarations": [], - "spell": "16:19-16:20|-1|1|2", - "extent": "16:10-16:20|-1|1|0", + "spell": "35:6-35:10|0|1|2", + "extent": "35:1-37:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["17:14-17:15|-1|1|4"] + "uses": [] }, { - "id": 8, - "usr": 5760043510674081814, - "detailed_name": "Z1", + "usr": 9673599782548740467, + "detailed_name": "T", "qual_name_offset": 0, - "short_name": "Z1", - "kind": 23, + "short_name": "T", + "kind": 26, "declarations": [], - "spell": "19:8-19:10|-1|1|2", - "extent": "19:1-19:13|-1|1|0", + "spell": "4:19-4:20|0|1|2", + "extent": "4:10-4:20|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["32:8-32:10|-1|1|4"] + "uses": ["5:16-5:17|0|1|4"] }, { - "id": 9, "usr": 10124869160135436852, "detailed_name": "Z2", "qual_name_offset": 0, "short_name": "Z2", "kind": 23, - "declarations": ["26:14-26:16|-1|1|4"], - "spell": "23:8-23:10|-1|1|2", - "extent": "23:1-23:13|-1|1|0", + "declarations": ["26:14-26:16|0|1|4"], + "spell": "23:8-23:10|0|1|2", + "extent": "23:1-23:13|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["33:8-33:10|-1|1|4"] + "uses": ["33:8-33:10|0|1|4"] }, { - "id": 10, - "usr": 1663022413889915338, - "detailed_name": "vector", + "usr": 14111105212951082474, + "detailed_name": "T", "qual_name_offset": 0, - "short_name": "vector", - "kind": 5, + "short_name": "T", + "kind": 26, "declarations": [], - "spell": "26:7-26:13|-1|1|2", - "extent": "25:1-28:2|-1|1|0", - "bases": [5], + "spell": "38:20-38:21|17498190318698490707|3|2", + "extent": "38:11-38:21|17498190318698490707|3|0", + "alias_of": 0, + "bases": [], "derived": [], "types": [], - "funcs": [1], + "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["39:10-39:11|0|1|4"] }, { - "id": 11, - "usr": 9201299975592934124, - "detailed_name": "Enum", + "usr": 15019211479263750068, + "detailed_name": "function", "qual_name_offset": 0, - "short_name": "Enum", - "kind": 10, - "declarations": [], - "spell": "35:6-35:10|-1|1|2", - "extent": "35:1-37:2|-1|1|0", + "short_name": "function", + "kind": 5, + "declarations": ["2:7-2:15|0|1|1", "5:7-5:15|0|1|4"], + "spell": "2:7-2:15|0|1|2", + "extent": "1:1-2:15|0|1|0", + "alias_of": 0, "bases": [], - "derived": [], + "derived": [218068462278884837], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["7:1-7:9|0|1|4"] }, { - "id": 12, - "usr": 2461355892344618654, - "detailed_name": "T", + "usr": 15695704394170757108, + "detailed_name": "allocator", "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "38:20-38:21|2|3|2", - "extent": "38:11-38:21|2|3|0", + "short_name": "allocator", + "kind": 5, + "declarations": ["9:28-9:37|0|1|1", "11:39-11:48|0|1|4"], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["39:10-39:11|-1|1|4"] + "uses": [] }, { - "id": 13, - "usr": 17, - "detailed_name": "", + "usr": 16155717907537731864, + "detailed_name": "vector", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "vector", + "kind": 5, "declarations": [], - "bases": [], + "spell": "17:7-17:13|0|1|2", + "extent": "16:1-17:20|0|1|0", + "alias_of": 0, + "bases": [7440942986741176606], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [8], - "uses": [] + "instances": [86949563628772958], + "uses": ["31:1-31:7|0|1|4"] }], - "funcs": [{ - "id": 0, - "usr": 18107614608385228556, - "detailed_name": "void vector::clear()", - "qual_name_offset": 5, - "short_name": "clear", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "13:8-13:13|5|2|1", - "param_spellings": [] - }], - "declaring_type": 5, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 1, - "usr": 6113470698424012876, - "detailed_name": "void vector::clear()", - "qual_name_offset": 5, - "short_name": "clear", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "27:8-27:13|10|2|1", - "param_spellings": [] - }], - "declaring_type": 10, - "bases": [], - "derived": [], - "vars": [], + "usr2var": [{ + "usr": 86949563628772958, + "detailed_name": "vector vip", + "qual_name_offset": 14, + "short_name": "vip", + "declarations": [], + "spell": "31:14-31:17|0|1|2", + "extent": "31:1-31:17|0|1|0", + "type": 16155717907537731864, "uses": [], - "callees": [] + "kind": 13, + "storage": 1 }, { - "id": 2, - "usr": 17498190318698490707, - "detailed_name": "void foo(T Value)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "43:6-43:9|-1|1|1", - "param_spellings": ["43:44-43:49"] - }], - "spell": "39:6-39:9|-1|1|2", - "extent": "39:1-39:21|-1|1|0", - "bases": [], - "derived": [], - "vars": [7], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, "usr": 2933643612409209903, "detailed_name": "function f", "qual_name_offset": 21, "short_name": "f", "declarations": [], - "spell": "7:21-7:22|-1|1|2", - "extent": "7:1-7:22|-1|1|0", - "type": 1, + "spell": "7:21-7:22|0|1|2", + "extent": "7:1-7:22|0|1|0", + "type": 218068462278884837, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 5792869548777559988, - "detailed_name": "vector vc", - "qual_name_offset": 13, - "short_name": "vc", + "usr": 3566687051827176322, + "detailed_name": "vector vz1", + "qual_name_offset": 11, + "short_name": "vz1", "declarations": [], - "spell": "30:14-30:16|-1|1|2", - "extent": "30:1-30:16|-1|1|0", - "type": 5, + "spell": "32:12-32:15|0|1|2", + "extent": "32:1-32:15|0|1|0", + "type": 7440942986741176606, "uses": [], "kind": 13, "storage": 1 }, { - "id": 2, - "usr": 86949563628772958, - "detailed_name": "vector vip", - "qual_name_offset": 14, - "short_name": "vip", + "usr": 4917621020431490070, + "detailed_name": "Enum::Enum1", + "qual_name_offset": 0, + "short_name": "Enum1", + "hover": "Enum::Enum1 = 1", "declarations": [], - "spell": "31:14-31:17|-1|1|2", - "extent": "31:1-31:17|-1|1|0", - "type": 6, + "spell": "36:10-36:15|9201299975592934124|2|2", + "extent": "36:10-36:15|9201299975592934124|2|0", + "type": 9201299975592934124, "uses": [], - "kind": 13, - "storage": 1 + "kind": 22, + "storage": 0 }, { - "id": 3, - "usr": 3566687051827176322, - "detailed_name": "vector vz1", - "qual_name_offset": 11, - "short_name": "vz1", + "usr": 5792869548777559988, + "detailed_name": "vector vc", + "qual_name_offset": 13, + "short_name": "vc", "declarations": [], - "spell": "32:12-32:15|-1|1|2", - "extent": "32:1-32:15|-1|1|0", - "type": 5, + "spell": "30:14-30:16|0|1|2", + "extent": "30:1-30:16|0|1|0", + "type": 7440942986741176606, "uses": [], "kind": 13, "storage": 1 }, { - "id": 4, - "usr": 15931696253641284761, - "detailed_name": "vector vz2", - "qual_name_offset": 11, - "short_name": "vz2", + "usr": 13914496963221806870, + "detailed_name": "const int kOnst", + "qual_name_offset": 10, + "short_name": "kOnst", + "hover": "const int kOnst = 7", "declarations": [], - "spell": "33:12-33:15|-1|1|2", - "extent": "33:1-33:15|-1|1|0", - "type": 5, - "uses": [], + "spell": "41:18-41:23|0|1|2", + "extent": "41:1-41:27|0|1|0", + "type": 17, + "uses": ["43:27-43:32|0|1|4"], "kind": 13, - "storage": 1 + "storage": 3 }, { - "id": 5, "usr": 15477793821005285152, "detailed_name": "Enum::Enum0", "qual_name_offset": 0, "short_name": "Enum0", "hover": "Enum::Enum0 = 0", "declarations": [], - "spell": "36:3-36:8|11|2|2", - "extent": "36:3-36:8|11|2|0", - "type": 11, - "uses": ["43:20-43:25|-1|1|4"], + "spell": "36:3-36:8|9201299975592934124|2|2", + "extent": "36:3-36:8|9201299975592934124|2|0", + "type": 9201299975592934124, + "uses": ["43:20-43:25|0|1|4"], "kind": 22, "storage": 0 }, { - "id": 6, - "usr": 4917621020431490070, - "detailed_name": "Enum::Enum1", - "qual_name_offset": 0, - "short_name": "Enum1", - "hover": "Enum::Enum1 = 1", + "usr": 15931696253641284761, + "detailed_name": "vector vz2", + "qual_name_offset": 11, + "short_name": "vz2", "declarations": [], - "spell": "36:10-36:15|11|2|2", - "extent": "36:10-36:15|11|2|0", - "type": 11, + "spell": "33:12-33:15|0|1|2", + "extent": "33:1-33:15|0|1|0", + "type": 7440942986741176606, "uses": [], - "kind": 22, - "storage": 0 + "kind": 13, + "storage": 1 }, { - "id": 7, - "usr": 10307767688451422448, + "usr": 17826688417349629938, "detailed_name": "T Value", "qual_name_offset": 2, "short_name": "Value", "declarations": [], - "spell": "39:12-39:17|2|3|2", - "extent": "39:10-39:17|2|3|0", + "spell": "39:12-39:17|17498190318698490707|3|2", + "extent": "39:10-39:17|17498190318698490707|3|0", + "type": 0, "uses": [], "kind": 253, "storage": 1 - }, { - "id": 8, - "usr": 13914496963221806870, - "detailed_name": "const int kOnst", - "qual_name_offset": 10, - "short_name": "kOnst", - "hover": "const int kOnst = 7", - "declarations": [], - "spell": "41:18-41:23|-1|1|2", - "extent": "41:1-41:27|-1|1|0", - "type": 13, - "uses": ["43:27-43:32|-1|1|4"], - "kind": 13, - "storage": 3 }] } */ diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 9f00bd05a..934063120 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -22,63 +22,41 @@ void Template::Foo() {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17107291254533526269, - "detailed_name": "Template", - "qual_name_offset": 0, - "short_name": "Template", - "kind": 5, - "declarations": [], - "spell": "2:7-2:15|-1|1|2", - "extent": "2:1-4:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": ["7:6-7:14|-1|1|4", "10:6-10:14|-1|1|4"] - }, { - "id": 1, - "usr": 17649312483543982122, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 11994188353303124840, "detailed_name": "void Template::Foo()", "qual_name_offset": 5, "short_name": "Foo", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "3:8-3:11|0|2|1", - "param_spellings": [] - }, { - "spell": "10:22-10:25|-1|1|1", - "param_spellings": [] - }], - "spell": "7:19-7:22|0|2|2", - "extent": "6:1-7:24|-1|1|0", - "declaring_type": 0, + "declarations": ["3:8-3:11|17107291254533526269|2|1", "10:22-10:25|0|1|1"], + "spell": "7:19-7:22|17107291254533526269|2|2", + "extent": "6:1-7:24|0|1|0", + "declaring_type": 17107291254533526269, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 17107291254533526269, + "detailed_name": "Template", + "qual_name_offset": 0, + "short_name": "Template", + "kind": 5, + "declarations": [], + "spell": "2:7-2:15|0|1|2", + "extent": "2:1-4:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [11994188353303124840], + "vars": [], + "instances": [], + "uses": ["7:6-7:14|0|1|4", "10:6-10:14|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index e4b9bdf56..3a7637b5d 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -13,82 +13,79 @@ int b = Foo::foo(); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "usr2func": [{ + "usr": 8340731781048851399, + "detailed_name": "int Foo::foo()", + "qual_name_offset": 4, + "short_name": "foo", + "kind": 254, + "storage": 3, "declarations": [], - "spell": "2:8-2:11|-1|1|2", - "extent": "2:1-6:2|-1|1|0", + "spell": "3:14-3:17|10528472276654770367|2|2", + "extent": "3:3-5:4|10528472276654770367|2|0", + "declaring_type": 10528472276654770367, "bases": [], "derived": [], - "types": [], - "funcs": [0], "vars": [], - "instances": [], - "uses": ["8:9-8:12|-1|1|4", "9:9-9:12|-1|1|4"] - }, { - "id": 1, + "uses": ["8:19-8:22|0|1|32", "9:20-9:23|0|1|32"], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [16721564935990383768, 12028309045033782423], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 8340731781048851399, - "detailed_name": "int Foo::foo()", - "qual_name_offset": 4, - "short_name": "foo", - "kind": 254, - "storage": 3, + }, { + "usr": 10528472276654770367, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "3:14-3:17|0|2|2", - "extent": "3:3-5:4|0|2|0", - "declaring_type": 0, + "spell": "2:8-2:11|0|1|2", + "extent": "2:1-6:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [8340731781048851399], "vars": [], - "uses": ["8:19-8:22|-1|1|32", "9:20-9:23|-1|1|32"], - "callees": [] + "instances": [], + "uses": ["8:9-8:12|0|1|4", "9:9-9:12|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "int a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "int b", "qual_name_offset": 4, - "short_name": "a", - "hover": "int a = Foo::foo()", + "short_name": "b", + "hover": "int b = Foo::foo()", "declarations": [], - "spell": "8:5-8:6|-1|1|2", - "extent": "8:1-8:24|-1|1|0", - "type": 1, + "spell": "9:5-9:6|0|1|2", + "extent": "9:1-9:25|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "int b", + "usr": 16721564935990383768, + "detailed_name": "int a", "qual_name_offset": 4, - "short_name": "b", - "hover": "int b = Foo::foo()", + "short_name": "a", + "hover": "int a = Foo::foo()", "declarations": [], - "spell": "9:5-9:6|-1|1|2", - "extent": "9:1-9:25|-1|1|0", - "type": 1, + "spell": "8:5-8:6|0|1|2", + "extent": "8:1-8:24|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 04c36e50d..81cf3b315 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -14,82 +14,79 @@ int b = Foo::foo(); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "usr2func": [{ + "usr": 9034026360701857235, + "detailed_name": "int Foo::foo()", + "qual_name_offset": 4, + "short_name": "foo", + "kind": 254, + "storage": 3, "declarations": [], - "spell": "2:8-2:11|-1|1|2", - "extent": "2:1-7:2|-1|1|0", + "spell": "4:14-4:17|10528472276654770367|2|2", + "extent": "4:3-6:4|10528472276654770367|2|0", + "declaring_type": 10528472276654770367, "bases": [], "derived": [], - "types": [], - "funcs": [0], "vars": [], - "instances": [], - "uses": ["9:9-9:12|-1|1|4", "10:9-10:12|-1|1|4"] - }, { - "id": 1, + "uses": ["9:19-9:22|0|1|32", "10:20-10:23|0|1|32"], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [16721564935990383768, 12028309045033782423], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 9034026360701857235, - "detailed_name": "int Foo::foo()", - "qual_name_offset": 4, - "short_name": "foo", - "kind": 254, - "storage": 3, + }, { + "usr": 10528472276654770367, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "4:14-4:17|0|2|2", - "extent": "4:3-6:4|0|2|0", - "declaring_type": 0, + "spell": "2:8-2:11|0|1|2", + "extent": "2:1-7:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [9034026360701857235], "vars": [], - "uses": ["9:19-9:22|-1|1|32", "10:20-10:23|-1|1|32"], - "callees": [] + "instances": [], + "uses": ["9:9-9:12|0|1|4", "10:9-10:12|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "int a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "int b", "qual_name_offset": 4, - "short_name": "a", - "hover": "int a = Foo::foo()", + "short_name": "b", + "hover": "int b = Foo::foo()", "declarations": [], - "spell": "9:5-9:6|-1|1|2", - "extent": "9:1-9:31|-1|1|0", - "type": 1, + "spell": "10:5-10:6|0|1|2", + "extent": "10:1-10:33|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "int b", + "usr": 16721564935990383768, + "detailed_name": "int a", "qual_name_offset": 4, - "short_name": "b", - "hover": "int b = Foo::foo()", + "short_name": "a", + "hover": "int a = Foo::foo()", "declarations": [], - "spell": "10:5-10:6|-1|1|2", - "extent": "10:1-10:33|-1|1|0", - "type": 1, + "spell": "9:5-9:6|0|1|2", + "extent": "9:1-9:31|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 063f755b8..fadf4c99f 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -32,99 +32,97 @@ VarDecl b { "includes": [], "skipped_by_preprocessor": ["12:1-28:7"], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 6697181287623958829, "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|-1|1|2", - "extent": "1:1-1:10|-1|1|0", + "spell": "1:6-1:7|0|1|2", + "extent": "1:1-1:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["9:5-9:6|-1|1|4"] + "uses": ["9:5-9:6|0|1|4"] }, { - "id": 1, - "usr": 13892793056005362145, - "detailed_name": "B", + "usr": 10528472276654770367, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "B", - "kind": 10, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "2:6-2:7|-1|1|2", - "extent": "2:1-2:10|-1|1|0", + "spell": "5:8-5:11|0|1|2", + "extent": "5:1-7:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["10:5-10:6|-1|1|4"] + "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] }, { - "id": 2, - "usr": 10528472276654770367, - "detailed_name": "Foo", + "usr": 13892793056005362145, + "detailed_name": "B", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "B", + "kind": 10, "declarations": [], - "spell": "5:8-5:11|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "spell": "2:6-2:7|0|1|2", + "extent": "2:1-2:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["9:1-9:4|-1|1|4", "10:1-10:4|-1|1|4"] + "uses": ["10:5-10:6|0|1|4"] }, { - "id": 3, "usr": 13938528237873543349, "detailed_name": "Foo::Inner", "qual_name_offset": 0, "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|2|2|2", - "extent": "6:3-6:18|2|2|0", + "spell": "6:10-6:15|10528472276654770367|2|2", + "extent": "6:3-6:18|10528472276654770367|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], - "uses": ["9:9-9:14|-1|1|4", "10:9-10:14|-1|1|4"] + "instances": [16721564935990383768, 12028309045033782423], + "uses": ["9:9-9:14|0|1|4", "10:9-10:14|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "Foo::Inner a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "Foo::Inner b", "qual_name_offset": 14, - "short_name": "a", + "short_name": "b", "declarations": [], - "spell": "9:15-9:16|-1|1|2", - "extent": "9:1-9:16|-1|1|0", - "type": 3, + "spell": "10:15-10:16|0|1|2", + "extent": "10:1-10:16|0|1|0", + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "Foo::Inner b", + "usr": 16721564935990383768, + "detailed_name": "Foo::Inner a", "qual_name_offset": 14, - "short_name": "b", + "short_name": "a", "declarations": [], - "spell": "10:15-10:16|-1|1|2", - "extent": "10:1-10:16|-1|1|0", - "type": 3, + "spell": "9:15-9:16|0|1|2", + "extent": "9:1-9:16|0|1|0", + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index f18538787..b1a2e8fb6 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -11,77 +11,74 @@ int b = Foo::var; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 10528472276654770367, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "2:8-2:11|-1|1|2", - "extent": "2:1-4:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["6:9-6:12|-1|1|4", "7:9-7:12|-1|1|4"] + "instances": [13545144895171991916, 16721564935990383768, 12028309045033782423], + "uses": [] }, { - "id": 1, - "usr": 17, - "detailed_name": "", + "usr": 10528472276654770367, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], + "spell": "2:8-2:11|0|1|2", + "extent": "2:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1, 2], - "uses": [] + "instances": [], + "uses": ["6:9-6:12|0|1|4", "7:9-7:12|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "int b", + "qual_name_offset": 4, + "short_name": "b", + "hover": "int b = Foo::var", + "declarations": [], + "spell": "7:5-7:6|0|1|2", + "extent": "7:1-7:23|0|1|0", + "type": 17, + "uses": [], + "kind": 13, + "storage": 1 + }, { "usr": 13545144895171991916, "detailed_name": "const int Foo::var", "qual_name_offset": 10, "short_name": "var", "hover": "const int Foo::var = 3", - "declarations": ["3:24-3:27|0|2|1"], - "type": 1, - "uses": ["6:19-6:22|-1|1|4", "7:20-7:23|-1|1|4"], + "declarations": ["3:24-3:27|10528472276654770367|2|1"], + "type": 17, + "uses": ["6:19-6:22|0|1|4", "7:20-7:23|0|1|4"], "kind": 8, "storage": 3 }, { - "id": 1, "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::var", "declarations": [], - "spell": "6:5-6:6|-1|1|2", - "extent": "6:1-6:22|-1|1|0", - "type": 1, - "uses": [], - "kind": 13, - "storage": 1 - }, { - "id": 2, - "usr": 12028309045033782423, - "detailed_name": "int b", - "qual_name_offset": 4, - "short_name": "b", - "hover": "int b = Foo::var", - "declarations": [], - "spell": "7:5-7:6|-1|1|2", - "extent": "7:1-7:23|-1|1|0", - "type": 1, + "spell": "6:5-6:6|0|1|2", + "extent": "6:1-6:22|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index 9a60681c8..e34b7505a 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -14,64 +14,62 @@ int b = foo(); { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 326583651986177228, + "detailed_name": "int foo()", + "qual_name_offset": 4, + "short_name": "foo", + "kind": 12, + "storage": 3, + "declarations": [], + "spell": "2:12-2:15|0|1|2", + "extent": "2:1-4:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["6:9-6:12|0|1|32", "7:9-7:12|0|1|32"], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [16721564935990383768, 12028309045033782423], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 326583651986177228, - "detailed_name": "int foo()", - "qual_name_offset": 4, - "short_name": "foo", - "kind": 12, - "storage": 3, - "declarations": [], - "spell": "2:12-2:15|-1|1|2", - "extent": "2:1-4:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": ["6:9-6:12|-1|1|32", "7:9-7:12|-1|1|32"], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "int a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "int b", "qual_name_offset": 4, - "short_name": "a", - "hover": "int a = foo()", + "short_name": "b", + "hover": "int b = foo()", "declarations": [], - "spell": "6:5-6:6|-1|1|2", - "extent": "6:1-6:19|-1|1|0", - "type": 0, + "spell": "7:5-7:6|0|1|2", + "extent": "7:1-7:20|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "int b", + "usr": 16721564935990383768, + "detailed_name": "int a", "qual_name_offset": 4, - "short_name": "b", - "hover": "int b = foo()", + "short_name": "a", + "hover": "int a = foo()", "declarations": [], - "spell": "7:5-7:6|-1|1|2", - "extent": "7:1-7:20|-1|1|0", - "type": 0, + "spell": "6:5-6:6|0|1|2", + "extent": "6:1-6:19|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 8a53c1cc9..6693cd064 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -9,48 +9,46 @@ Foo b; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 10528472276654770367, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|-1|1|2", - "extent": "2:1-2:13|-1|1|0", + "spell": "2:7-2:10|0|1|2", + "extent": "2:1-2:13|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], - "uses": ["4:1-4:4|-1|1|4", "5:1-5:4|-1|1|4"] + "instances": [16721564935990383768, 12028309045033782423], + "uses": ["4:1-4:4|0|1|4", "5:1-5:4|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 16721564935990383768, - "detailed_name": "Foo a", - "qual_name_offset": 9, - "short_name": "a", + "usr2var": [{ + "usr": 12028309045033782423, + "detailed_name": "Foo b", + "qual_name_offset": 10, + "short_name": "b", "declarations": [], - "spell": "4:10-4:11|-1|1|2", - "extent": "4:1-4:11|-1|1|0", - "type": 0, + "spell": "5:11-5:12|0|1|2", + "extent": "5:1-5:12|0|1|0", + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 12028309045033782423, - "detailed_name": "Foo b", - "qual_name_offset": 10, - "short_name": "b", + "usr": 16721564935990383768, + "detailed_name": "Foo a", + "qual_name_offset": 9, + "short_name": "a", "declarations": [], - "spell": "5:11-5:12|-1|1|2", - "extent": "5:1-5:12|-1|1|0", - "type": 0, + "spell": "4:10-4:11|0|1|2", + "extent": "4:1-4:11|0|1|0", + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index fd4bd404c..cd4ffa79e 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -35,94 +35,92 @@ UnexposedDecl var { "includes": [], "skipped_by_preprocessor": ["12:1-28:7"], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 6697181287623958829, "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|-1|1|2", - "extent": "1:1-1:10|-1|1|0", + "spell": "1:6-1:7|0|1|2", + "extent": "1:1-1:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], - "uses": ["7:1-7:2|-1|1|4", "7:11-7:12|-1|1|4"] + "instances": [16721564935990383768], + "uses": ["7:1-7:2|0|1|4", "7:11-7:12|0|1|4"] }, { - "id": 1, - "usr": 13892793056005362145, - "detailed_name": "B", + "usr": 11919899838872947844, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "B", - "kind": 10, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "2:6-2:7|-1|1|2", - "extent": "2:1-2:10|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [2], - "uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"] + "instances": [], + "uses": ["5:1-5:2|0|1|4", "5:9-5:10|0|1|4"] }, { - "id": 2, - "usr": 8864163146308556810, - "detailed_name": "", + "usr": 13892793056005362145, + "detailed_name": "B", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "B", + "kind": 10, "declarations": [], + "spell": "2:6-2:7|0|1|2", + "extent": "2:1-2:10|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["5:1-5:2|-1|1|4", "5:9-5:10|-1|1|4"] + "instances": [12028309045033782423], + "uses": ["8:1-8:2|0|1|4", "8:11-8:12|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 8096973118640070624, "detailed_name": "T var", "qual_name_offset": 2, "short_name": "var", "declarations": [], - "spell": "5:3-5:6|-1|1|2", - "extent": "5:1-5:12|-1|1|0", - "uses": ["7:7-7:10|-1|1|4", "8:7-8:10|-1|1|4"], + "spell": "5:3-5:6|0|1|2", + "extent": "5:1-5:12|0|1|0", + "type": 0, + "uses": ["7:7-7:10|0|1|4", "8:7-8:10|0|1|4"], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 16721564935990383768, - "detailed_name": "A a", + "usr": 12028309045033782423, + "detailed_name": "B b", "qual_name_offset": 2, - "short_name": "a", - "hover": "A a = var", + "short_name": "b", + "hover": "B b = var", "declarations": [], - "spell": "7:3-7:4|-1|1|2", - "extent": "7:1-7:13|-1|1|0", - "type": 0, + "spell": "8:3-8:4|0|1|2", + "extent": "8:1-8:13|0|1|0", + "type": 13892793056005362145, "uses": [], "kind": 13, "storage": 1 }, { - "id": 2, - "usr": 12028309045033782423, - "detailed_name": "B b", + "usr": 16721564935990383768, + "detailed_name": "A a", "qual_name_offset": 2, - "short_name": "b", - "hover": "B b = var", + "short_name": "a", + "hover": "A a = var", "declarations": [], - "spell": "8:3-8:4|-1|1|2", - "extent": "8:1-8:13|-1|1|0", - "type": 1, + "spell": "7:3-7:4|0|1|2", + "extent": "7:1-7:13|0|1|0", + "type": 6697181287623958829, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 32b4ea6f1..362b11a47 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -8,106 +8,102 @@ union vector3 { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17937907487590875128, - "detailed_name": "vector3", + "usr2func": [], + "usr2type": [{ + "usr": 21, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "vector3", - "kind": 23, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:7-1:14|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [3], - "instances": [], + "vars": [], + "instances": [3348817847649945564, 4821094820988543895, 15292551660437765731, 1963212417280098348], "uses": [] }, { - "id": 1, "usr": 1428566502523368801, "detailed_name": "vector3::(anon struct)", "qual_name_offset": 0, "short_name": "(anon struct)", "kind": 23, "declarations": [], - "spell": "2:3-2:9|0|2|2", - "extent": "2:3-2:28|0|2|0", + "spell": "2:3-2:9|17937907487590875128|2|2", + "extent": "2:3-2:28|17937907487590875128|2|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0, 1, 2], + "vars": [3348817847649945564, 4821094820988543895, 15292551660437765731], "instances": [], "uses": [] }, { - "id": 2, - "usr": 21, - "detailed_name": "", + "usr": 17937907487590875128, + "detailed_name": "vector3", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "vector3", + "kind": 23, "declarations": [], + "spell": "1:7-1:14|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [], - "instances": [0, 1, 2, 3], + "vars": [1963212417280098348], + "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ + "usr": 1963212417280098348, + "detailed_name": "float [3] vector3::v", + "qual_name_offset": 10, + "short_name": "v", + "declarations": [], + "spell": "3:9-3:10|17937907487590875128|2|2", + "extent": "3:3-3:13|17937907487590875128|2|0", + "type": 21, + "uses": [], + "kind": 8, + "storage": 0 + }, { "usr": 3348817847649945564, "detailed_name": "float vector3::(anon struct)::x", "qual_name_offset": 6, "short_name": "x", "declarations": [], - "spell": "2:18-2:19|1|2|2", - "extent": "2:12-2:19|1|2|0", - "type": 2, + "spell": "2:18-2:19|1428566502523368801|2|2", + "extent": "2:12-2:19|1428566502523368801|2|0", + "type": 21, "uses": [], "kind": 8, "storage": 0 }, { - "id": 1, "usr": 4821094820988543895, "detailed_name": "float vector3::(anon struct)::y", "qual_name_offset": 6, "short_name": "y", "declarations": [], - "spell": "2:21-2:22|1|2|2", - "extent": "2:12-2:22|1|2|0", - "type": 2, + "spell": "2:21-2:22|1428566502523368801|2|2", + "extent": "2:12-2:22|1428566502523368801|2|0", + "type": 21, "uses": [], "kind": 8, "storage": 0 }, { - "id": 2, "usr": 15292551660437765731, "detailed_name": "float vector3::(anon struct)::z", "qual_name_offset": 6, "short_name": "z", "declarations": [], - "spell": "2:24-2:25|1|2|2", - "extent": "2:12-2:25|1|2|0", - "type": 2, - "uses": [], - "kind": 8, - "storage": 0 - }, { - "id": 3, - "usr": 1963212417280098348, - "detailed_name": "float [3] vector3::v", - "qual_name_offset": 10, - "short_name": "v", - "declarations": [], - "spell": "3:9-3:10|0|2|2", - "extent": "3:3-3:13|0|2|0", - "type": 2, + "spell": "2:24-2:25|1428566502523368801|2|2", + "extent": "2:12-2:25|1428566502523368801|2|0", + "type": 21, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index 90a30b68d..a7e8c5201 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -6,23 +6,22 @@ static func g; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "usr2func": [{ + "usr": 8105378401105136463, + "detailed_name": "func g", + "qual_name_offset": 5, + "short_name": "g", + "kind": 12, + "storage": 3, + "declarations": ["2:13-2:14|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": [] - }, { - "id": 1, + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 10383876566159302459, "detailed_name": "func", "qual_name_offset": 0, @@ -30,35 +29,32 @@ static func g; "kind": 252, "hover": "typedef int (func)(const int *a, const int *b)", "declarations": [], - "spell": "1:14-1:18|-1|1|2", - "extent": "1:1-1:47|-1|1|0", - "alias_of": 0, + "spell": "1:14-1:18|0|1|2", + "extent": "1:1-1:47|0|1|0", + "alias_of": 13838176792705659279, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:14-1:18|-1|1|4", "2:8-2:12|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 8105378401105136463, - "detailed_name": "func g", - "qual_name_offset": 5, - "short_name": "g", - "kind": 12, - "storage": 3, - "declarations": [{ - "spell": "2:13-2:14|-1|1|1", - "param_spellings": ["2:13-2:13", "2:13-2:13"] - }], + "uses": ["1:14-1:18|0|1|4", "2:8-2:12|0|1|4"] + }, { + "usr": 13838176792705659279, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": [] }], - "vars": [] + "usr2var": [] } */ \ No newline at end of file diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 519ddfdab..ad1c9e7e0 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -8,78 +8,76 @@ union Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 8501689086387244262, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 3, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0, 1], - "instances": [], + "vars": [], + "instances": [8804696910588009104], "uses": [] }, { - "id": 1, "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [9529311430721959843], "uses": [] }, { - "id": 2, - "usr": 3, - "detailed_name": "", + "usr": 8501689086387244262, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [], - "instances": [1], + "vars": [9529311430721959843, 8804696910588009104], + "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, - "usr": 9529311430721959843, - "detailed_name": "int Foo::a", - "qual_name_offset": 4, - "short_name": "a", + "usr2var": [{ + "usr": 8804696910588009104, + "detailed_name": "bool Foo::b", + "qual_name_offset": 5, + "short_name": "b", "declarations": [], - "spell": "2:7-2:8|0|2|2", - "extent": "2:3-2:8|0|2|0", - "type": 1, + "spell": "3:8-3:9|8501689086387244262|2|2", + "extent": "3:3-3:9|8501689086387244262|2|0", + "type": 3, "uses": [], "kind": 8, "storage": 0 }, { - "id": 1, - "usr": 8804696910588009104, - "detailed_name": "bool Foo::b", - "qual_name_offset": 5, - "short_name": "b", + "usr": 9529311430721959843, + "detailed_name": "int Foo::a", + "qual_name_offset": 4, + "short_name": "a", "declarations": [], - "spell": "3:8-3:9|0|2|2", - "extent": "3:3-3:9|0|2|0", - "type": 2, + "spell": "2:7-2:8|8501689086387244262|2|2", + "extent": "2:3-2:8|8501689086387244262|2|0", + "type": 17, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index a91b4e370..3de937b68 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -16,112 +16,109 @@ void act(Foo*) { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 8501689086387244262, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 13982179977217945200, + "detailed_name": "void act(Foo *)", + "qual_name_offset": 5, + "short_name": "act", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-4:2|-1|1|0", + "spell": "8:6-8:9|0|1|2", + "extent": "8:1-10:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [0, 1], - "instances": [2], - "uses": ["6:1-6:4|-1|1|4", "8:10-8:13|-1|1|4"] - }, { - "id": 1, - "usr": 17, + "vars": [], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 3, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [8804696910588009104], "uses": [] }, { - "id": 2, - "usr": 3, + "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], + "instances": [9529311430721959843], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 13982179977217945200, - "detailed_name": "void act(Foo *)", - "qual_name_offset": 5, - "short_name": "act", - "kind": 12, - "storage": 1, + }, { + "usr": 8501689086387244262, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "8:6-8:9|-1|1|2", - "extent": "8:1-10:2|-1|1|0", + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-4:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "types": [], + "funcs": [], + "vars": [9529311430721959843, 8804696910588009104], + "instances": [2933643612409209903], + "uses": ["6:1-6:4|0|1|4", "8:10-8:13|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 9529311430721959843, - "detailed_name": "int Foo::a", + "usr2var": [{ + "usr": 2933643612409209903, + "detailed_name": "Foo f", "qual_name_offset": 4, - "short_name": "a", - "hover": "int Foo::a : 5", + "short_name": "f", "declarations": [], - "spell": "2:7-2:8|0|2|2", - "extent": "2:3-2:12|0|2|0", - "type": 1, - "uses": ["9:5-9:6|0|3|4"], - "kind": 8, - "storage": 0 + "spell": "6:5-6:6|0|1|2", + "extent": "6:1-6:6|0|1|0", + "type": 8501689086387244262, + "uses": ["9:3-9:4|13982179977217945200|3|4"], + "kind": 13, + "storage": 1 }, { - "id": 1, "usr": 8804696910588009104, "detailed_name": "bool Foo::b", "qual_name_offset": 5, "short_name": "b", "hover": "bool Foo::b : 3", "declarations": [], - "spell": "3:8-3:9|0|2|2", - "extent": "3:3-3:13|0|2|0", - "type": 2, + "spell": "3:8-3:9|8501689086387244262|2|2", + "extent": "3:3-3:13|8501689086387244262|2|0", + "type": 3, "uses": [], "kind": 8, "storage": 0 }, { - "id": 2, - "usr": 2933643612409209903, - "detailed_name": "Foo f", + "usr": 9529311430721959843, + "detailed_name": "int Foo::a", "qual_name_offset": 4, - "short_name": "f", + "short_name": "a", + "hover": "int Foo::a : 5", "declarations": [], - "spell": "6:5-6:6|-1|1|2", - "extent": "6:1-6:6|-1|1|0", - "type": 0, - "uses": ["9:3-9:4|0|3|4"], - "kind": 13, - "storage": 1 + "spell": "2:7-2:8|8501689086387244262|2|2", + "extent": "2:3-2:12|8501689086387244262|2|0", + "type": 17, + "uses": ["9:5-9:6|13982179977217945200|3|4"], + "kind": 8, + "storage": 0 }] } */ diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 81aedbd40..67221d072 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -13,26 +13,7 @@ Foo::Foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["4:3-4:6|-1|1|4", "7:6-7:9|-1|1|4"], - "spell": "3:8-3:11|-1|1|2", - "extent": "3:1-5:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [1], - "vars": [], - "instances": [], - "uses": ["4:3-4:6|0|2|4", "7:6-7:9|-1|1|4", "7:1-7:4|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", "qual_name_offset": 5, @@ -40,34 +21,49 @@ Foo::Foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "1:6-1:12|-1|1|2", - "extent": "1:1-1:17|-1|1|0", + "spell": "1:6-1:12|0|1|2", + "extent": "1:1-1:17|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|1|3|32"], + "uses": ["8:3-8:9|3385168158331140247|3|32"], "callees": [] }, { - "id": 1, "usr": 3385168158331140247, "detailed_name": "void Foo::Foo()", "qual_name_offset": 5, "short_name": "Foo", "kind": 9, "storage": 1, - "declarations": [{ - "spell": "4:3-4:6|0|2|1", - "param_spellings": [] - }], - "spell": "7:6-7:9|0|2|2", - "extent": "7:1-9:2|-1|1|0", - "declaring_type": 0, + "declarations": ["4:3-4:6|15041163540773201510|2|1"], + "spell": "7:6-7:9|15041163540773201510|2|2", + "extent": "7:1-9:2|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["8:3-8:9|0|3|32"] + "callees": ["8:3-8:9|468307235068920063|3|32"] + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["4:3-4:6|0|1|4", "7:6-7:9|0|1|4"], + "spell": "3:8-3:11|0|1|2", + "extent": "3:1-5:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [3385168158331140247], + "vars": [], + "instances": [], + "uses": ["4:3-4:6|15041163540773201510|2|4", "7:6-7:9|0|1|4", "7:1-7:4|0|1|4"] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 6514adae3..4388e551b 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -11,26 +11,21 @@ void caller() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 3787803219955606747, "detailed_name": "bool called(bool a, bool b)", "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "3:6-3:12|-1|1|1", - "param_spellings": ["3:18-3:19", "3:26-3:27"] - }], + "declarations": ["3:6-3:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|1|3|32"], + "uses": ["6:14-6:20|11404881820527069090|3|32"], "callees": [] }, { - "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, @@ -38,25 +33,27 @@ void caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "5:6-5:12|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "spell": "5:6-5:12|0|1|2", + "extent": "5:1-7:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["6:14-6:20|0|3|32"] + "callees": ["6:14-6:20|3787803219955606747|3|32"] }], - "vars": [{ - "id": 0, + "usr2type": [], + "usr2var": [{ "usr": 1290746656694198202, "detailed_name": "MACRO_CALL", "qual_name_offset": 0, "short_name": "MACRO_CALL", "hover": "#define MACRO_CALL(e) e", "declarations": [], - "spell": "1:9-1:19|-1|1|2", - "extent": "1:9-1:24|-1|1|0", - "uses": ["6:3-6:13|-1|1|4"], + "spell": "1:9-1:19|0|1|2", + "extent": "1:9-1:24|0|1|0", + "type": 0, + "uses": ["6:3-6:13|0|1|4"], "kind": 255, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 1840fb154..6647723de 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -16,57 +16,54 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:12|-1|1|1", - "param_spellings": [] - }], + "declarations": ["1:6-1:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|1|3|32"], + "uses": ["5:3-5:9|10177235824697315808|3|32"], "callees": [] }, { - "id": 1, - "usr": 10177235824697315808, - "detailed_name": "void caller()", + "usr": 4259594751088586730, + "detailed_name": "void foo()", "qual_name_offset": 5, - "short_name": "caller", + "short_name": "foo", "kind": 12, "storage": 1, "declarations": [], - "spell": "4:6-4:12|-1|1|2", - "extent": "4:1-6:2|-1|1|0", + "spell": "8:6-8:9|0|1|2", + "extent": "8:1-10:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["9:3-9:9|2|3|32"], - "callees": ["5:3-5:9|0|3|32"] + "uses": [], + "callees": ["9:3-9:9|10177235824697315808|3|32"] }, { - "id": 2, - "usr": 4259594751088586730, - "detailed_name": "void foo()", + "usr": 10177235824697315808, + "detailed_name": "void caller()", "qual_name_offset": 5, - "short_name": "foo", + "short_name": "caller", "kind": 12, "storage": 1, "declarations": [], - "spell": "8:6-8:9|-1|1|2", - "extent": "8:1-10:2|-1|1|0", + "spell": "4:6-4:12|0|1|2", + "extent": "4:1-6:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": [], - "callees": ["9:3-9:9|1|3|32"] + "uses": ["9:3-9:9|4259594751088586730|3|32"], + "callees": ["5:3-5:9|468307235068920063|3|32"] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ \ No newline at end of file diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index b2f55947c..86a143645 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -13,60 +13,37 @@ Wrapper caller() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13611487872560323389, - "detailed_name": "Wrapper", - "qual_name_offset": 0, - "short_name": "Wrapper", - "kind": 23, - "declarations": ["2:3-2:10|-1|1|4"], - "spell": "1:8-1:15|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "usr2func": [{ + "usr": 468307235068920063, + "detailed_name": "int called()", + "qual_name_offset": 4, + "short_name": "called", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "5:5-5:11|0|1|2", + "extent": "5:1-5:27|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [0], "vars": [], - "instances": [], - "uses": ["2:3-2:10|0|2|4", "7:1-7:8|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "uses": ["8:10-8:16|11404881820527069090|3|32"], + "callees": [] + }, { "usr": 10544127002917214589, "detailed_name": "void Wrapper::Wrapper(int i)", "qual_name_offset": 5, "short_name": "Wrapper", "kind": 9, "storage": 1, - "declarations": [{ - "spell": "2:3-2:10|0|2|1", - "param_spellings": ["2:15-2:16"] - }], - "declaring_type": 0, + "declarations": ["2:3-2:10|13611487872560323389|2|1"], + "declaring_type": 13611487872560323389, "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:18|2|3|288"], + "uses": ["8:10-8:18|11404881820527069090|3|288"], "callees": [] }, { - "id": 1, - "usr": 468307235068920063, - "detailed_name": "int called()", - "qual_name_offset": 4, - "short_name": "called", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "5:5-5:11|-1|1|2", - "extent": "5:1-5:27|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": ["8:10-8:16|2|3|32"], - "callees": [] - }, { - "id": 2, "usr": 11404881820527069090, "detailed_name": "Wrapper caller()", "qual_name_offset": 8, @@ -74,14 +51,33 @@ Wrapper caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "7:9-7:15|-1|1|2", - "extent": "7:1-9:2|-1|1|0", + "spell": "7:9-7:15|0|1|2", + "extent": "7:1-9:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["8:10-8:18|0|3|288", "8:10-8:16|1|3|32"] + "callees": ["8:10-8:18|10544127002917214589|3|288", "8:10-8:16|468307235068920063|3|32"] + }], + "usr2type": [{ + "usr": 13611487872560323389, + "detailed_name": "Wrapper", + "qual_name_offset": 0, + "short_name": "Wrapper", + "kind": 23, + "declarations": ["2:3-2:10|0|1|4"], + "spell": "1:8-1:15|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [10544127002917214589], + "vars": [], + "instances": [], + "uses": ["2:3-2:10|13611487872560323389|2|4", "7:1-7:8|0|1|4"] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 8851f96e3..88c6ff24f 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -12,25 +12,7 @@ void user() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, - "usr": 12924914488846929470, - "detailed_name": "void consume(void (*)())", - "qual_name_offset": 5, - "short_name": "consume", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:13|-1|1|2", - "extent": "1:1-1:28|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": ["7:3-7:10|2|3|32"], - "callees": [] - }, { - "id": 1, + "usr2func": [{ "usr": 5264867802674151787, "detailed_name": "void used()", "qual_name_offset": 5, @@ -38,15 +20,15 @@ void user() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:10|-1|1|2", - "extent": "3:1-3:15|-1|1|0", + "spell": "3:6-3:10|0|1|2", + "extent": "3:1-3:15|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|2|3|32", "7:12-7:16|2|3|32"], + "uses": ["6:18-6:22|9376923949268137283|3|32", "7:12-7:16|9376923949268137283|3|32"], "callees": [] }, { - "id": 2, "usr": 9376923949268137283, "detailed_name": "void user()", "qual_name_offset": 5, @@ -54,23 +36,41 @@ void user() { "kind": 12, "storage": 1, "declarations": [], - "spell": "5:6-5:10|-1|1|2", - "extent": "5:1-8:2|-1|1|0", + "spell": "5:6-5:10|0|1|2", + "extent": "5:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0], + "vars": [16088407831770615719], "uses": [], - "callees": ["6:18-6:22|1|3|32", "6:18-6:22|1|3|32", "7:3-7:10|0|3|32", "7:12-7:16|1|3|32"] + "callees": ["6:18-6:22|5264867802674151787|3|32", "6:18-6:22|5264867802674151787|3|32", "7:3-7:10|12924914488846929470|3|32", "7:12-7:16|5264867802674151787|3|32"] + }, { + "usr": 12924914488846929470, + "detailed_name": "void consume(void (*)())", + "qual_name_offset": 5, + "short_name": "consume", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:13|0|1|2", + "extent": "1:1-1:28|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["7:3-7:10|9376923949268137283|3|32"], + "callees": [] }], - "vars": [{ - "id": 0, - "usr": 13681544683892648258, + "usr2type": [], + "usr2var": [{ + "usr": 16088407831770615719, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", "declarations": [], - "spell": "6:10-6:11|2|3|2", - "extent": "6:3-6:22|2|3|0", + "spell": "6:10-6:11|9376923949268137283|3|2", + "extent": "6:3-6:22|9376923949268137283|3|0", + "type": 0, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 3babaf658..bc8e72b1c 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -12,68 +12,64 @@ void user() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 9376923949268137283, + "detailed_name": "void user()", + "qual_name_offset": 5, + "short_name": "user", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "5:6-5:10|0|1|2", + "extent": "5:1-7:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [], - "uses": ["6:13-6:16|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "vars": [4636142131003982569], + "uses": [], + "callees": ["6:18-6:22|18417145003926999463|3|32", "6:18-6:22|18417145003926999463|3|32"] + }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", "qual_name_offset": 5, "short_name": "Used", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:12|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "declarations": ["2:8-2:12|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|1|3|32"], + "uses": ["6:18-6:22|9376923949268137283|3|32"], "callees": [] - }, { - "id": 1, - "usr": 9376923949268137283, - "detailed_name": "void user()", - "qual_name_offset": 5, - "short_name": "user", - "kind": 12, - "storage": 1, + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "5:6-5:10|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [0], - "uses": [], - "callees": ["6:18-6:22|0|3|32", "6:18-6:22|0|3|32"] + "types": [], + "funcs": [18417145003926999463], + "vars": [], + "instances": [], + "uses": ["6:13-6:16|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 8436636043513449412, + "usr2var": [{ + "usr": 4636142131003982569, "detailed_name": "void (Foo::*)() x", "qual_name_offset": 16, "short_name": "x", "declarations": [], - "spell": "6:8-6:9|1|3|2", - "extent": "6:3-6:22|1|3|0", + "spell": "6:8-6:9|9376923949268137283|3|2", + "extent": "6:3-6:22|9376923949268137283|3|0", + "type": 0, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 2181c4f48..747b159e0 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -8,9 +8,7 @@ void caller() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", "qual_name_offset": 5, @@ -18,15 +16,15 @@ void caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "1:6-1:12|-1|1|2", - "extent": "1:1-1:17|-1|1|0", + "spell": "1:6-1:12|0|1|2", + "extent": "1:1-1:17|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["3:3-3:9|1|3|32"], + "uses": ["3:3-3:9|11404881820527069090|3|32"], "callees": [] }, { - "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, @@ -34,14 +32,16 @@ void caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "2:6-2:12|-1|1|2", - "extent": "2:1-4:2|-1|1|0", + "spell": "2:6-2:12|0|1|2", + "extent": "2:1-4:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["3:3-3:9|0|3|32"] + "callees": ["3:3-3:9|468307235068920063|3|32"] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index d2d33b007..4dd1244fd 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -12,71 +12,66 @@ void user() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 9376923949268137283, + "detailed_name": "void user()", + "qual_name_offset": 5, + "short_name": "user", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "5:6-5:10|0|1|2", + "extent": "5:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [0], - "uses": ["6:3-6:6|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "vars": [14045150712868309451], + "uses": [], + "callees": ["7:6-7:10|18417145003926999463|3|32"] + }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", "qual_name_offset": 5, "short_name": "Used", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:12|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "declarations": ["2:8-2:12|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:10|1|3|32"], + "uses": ["7:6-7:10|9376923949268137283|3|32"], "callees": [] - }, { - "id": 1, - "usr": 9376923949268137283, - "detailed_name": "void user()", - "qual_name_offset": 5, - "short_name": "user", - "kind": 12, - "storage": 1, + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "5:6-5:10|-1|1|2", - "extent": "5:1-8:2|-1|1|0", + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [0], - "uses": [], - "callees": ["7:6-7:10|0|3|32"] + "types": [], + "funcs": [18417145003926999463], + "vars": [], + "instances": [14045150712868309451], + "uses": ["6:3-6:6|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 3014406561587537195, + "usr2var": [{ + "usr": 14045150712868309451, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], - "spell": "6:8-6:9|1|3|2", - "extent": "6:3-6:19|1|3|0", - "type": 0, - "uses": ["7:3-7:4|1|3|4"], + "spell": "6:8-6:9|9376923949268137283|3|2", + "extent": "6:3-6:19|9376923949268137283|3|0", + "type": 15041163540773201510, + "uses": ["7:3-7:4|9376923949268137283|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index eb0821335..2c5c3db30 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -11,67 +11,66 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "usr2func": [{ + "usr": 9630503130605430498, + "detailed_name": "int helper()", + "qual_name_offset": 4, + "short_name": "helper", + "kind": 12, + "storage": 3, "declarations": [], - "spell": "5:7-5:10|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "spell": "1:12-1:18|0|1|2", + "extent": "1:1-3:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [0], - "instances": [], - "uses": [] - }, { - "id": 1, + "vars": [], + "uses": ["6:11-6:17|15041163540773201510|2|32"], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [4220150017963593039], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 9630503130605430498, - "detailed_name": "int helper()", - "qual_name_offset": 4, - "short_name": "helper", - "kind": 12, - "storage": 3, + }, { + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "1:12-1:18|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "5:7-5:10|0|1|2", + "extent": "5:1-7:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [], - "uses": ["6:11-6:17|0|2|32"], - "callees": [] + "types": [], + "funcs": [], + "vars": [4220150017963593039], + "instances": [], + "uses": [] }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 4220150017963593039, "detailed_name": "int Foo::x", "qual_name_offset": 4, "short_name": "x", "hover": "int Foo::x = helper()", "declarations": [], - "spell": "6:7-6:8|0|2|2", - "extent": "6:3-6:19|0|2|0", - "type": 1, + "spell": "6:7-6:8|15041163540773201510|2|2", + "extent": "6:3-6:19|15041163540773201510|2|0", + "type": 17, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 8ee0bcde7..1fbbbb1a3 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -8,26 +8,21 @@ void usage() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:9|-1|1|1", - "param_spellings": [] - }], + "declarations": ["1:6-1:9|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:6|1|3|32"], + "uses": ["4:3-4:6|6767773193109753523|3|32"], "callees": [] }, { - "id": 1, "usr": 6767773193109753523, "detailed_name": "void usage()", "qual_name_offset": 5, @@ -35,14 +30,16 @@ void usage() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:11|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:11|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:6|0|3|32"] + "callees": ["4:3-4:6|4259594751088586730|3|32"] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 0c5b0bbbb..fa3de2133 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -11,71 +11,66 @@ void usage() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 6767773193109753523, + "detailed_name": "void usage()", + "qual_name_offset": 5, + "short_name": "usage", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "5:6-5:11|0|1|2", + "extent": "5:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [0], - "uses": ["6:3-6:6|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "vars": [16229832321010999607], + "uses": [], + "callees": ["7:6-7:9|17922201480358737771|3|32"] + }, { "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:11|0|2|1", - "param_spellings": [] - }], - "declaring_type": 0, + "declarations": ["2:8-2:11|15041163540773201510|2|1"], + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:9|1|3|32"], + "uses": ["7:6-7:9|6767773193109753523|3|32"], "callees": [] - }, { - "id": 1, - "usr": 6767773193109753523, - "detailed_name": "void usage()", - "qual_name_offset": 5, - "short_name": "usage", - "kind": 12, - "storage": 1, + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "5:6-5:11|-1|1|2", - "extent": "5:1-8:2|-1|1|0", + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [0], - "uses": [], - "callees": ["7:6-7:9|0|3|32"] + "types": [], + "funcs": [17922201480358737771], + "vars": [], + "instances": [16229832321010999607], + "uses": ["6:3-6:6|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 12410753116854389823, + "usr2var": [{ + "usr": 16229832321010999607, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], - "spell": "6:8-6:9|1|3|2", - "extent": "6:3-6:19|1|3|0", - "type": 0, - "uses": ["7:3-7:4|1|3|4"], + "spell": "6:8-6:9|6767773193109753523|3|2", + "extent": "6:3-6:19|6767773193109753523|3|0", + "type": 15041163540773201510, + "uses": ["7:3-7:4|6767773193109753523|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 610873991..84330c569 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -11,58 +11,55 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13420564603121289209, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:19-1:20|0|3|2", - "extent": "1:10-1:20|0|3|0", + "spell": "4:6-4:9|0|1|2", + "extent": "4:1-7:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["2:13-2:14|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "uses": [], + "callees": ["5:3-5:9|10585861037135727329|3|32", "6:3-6:9|10585861037135727329|3|32"] + }, { "usr": 10585861037135727329, "detailed_name": "void accept(T)", "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "2:6-2:12|-1|1|1", - "param_spellings": ["2:14-2:14"] - }], + "declarations": ["2:6-2:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|1|3|32", "6:3-6:9|1|3|32"], + "uses": ["5:3-5:9|4259594751088586730|3|32", "6:3-6:9|4259594751088586730|3|32"], "callees": [] - }, { - "id": 1, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, + }], + "usr2type": [{ + "usr": 13420564603121289209, + "detailed_name": "T", + "qual_name_offset": 0, + "short_name": "T", + "kind": 26, "declarations": [], - "spell": "4:6-4:9|-1|1|2", - "extent": "4:1-7:2|-1|1|0", + "spell": "1:19-1:20|10585861037135727329|3|2", + "extent": "1:10-1:20|10585861037135727329|3|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": ["5:3-5:9|0|3|32", "6:3-6:9|0|3|32"] + "instances": [], + "uses": ["2:13-2:14|0|1|4"] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index e7cdd887d..6c9a99ba7 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -15,97 +15,94 @@ unique_ptr* return_type() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 16359708726068806331, + "detailed_name": "unique_ptr *return_type()", + "qual_name_offset": 15, + "short_name": "return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "9:16-9:27|0|1|2", + "extent": "9:1-12:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [3364438781074774169], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 3286534761799572592, "detailed_name": "unique_ptr", "qual_name_offset": 0, "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|-1|1|2", - "extent": "2:1-2:20|-1|1|0", + "spell": "2:7-2:17|0|1|2", + "extent": "2:1-2:20|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1, 2], - "uses": ["6:8-6:18|-1|1|4", "7:8-7:18|-1|1|4", "9:1-9:11|-1|1|4", "10:3-10:13|-1|1|4"] + "instances": [12857919739649552168, 18075066956054788088, 3364438781074774169], + "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|0|1|4"] }, { - "id": 1, "usr": 4750332761459066907, "detailed_name": "S", "qual_name_offset": 0, "short_name": "S", "kind": 23, "declarations": [], - "spell": "4:8-4:9|-1|1|2", - "extent": "4:1-4:12|-1|1|0", + "spell": "4:8-4:9|0|1|2", + "extent": "4:1-4:12|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["7:19-7:20|-1|1|4", "9:12-9:13|-1|1|4", "10:14-10:15|-1|1|4"] + "uses": ["7:19-7:20|0|1|4", "9:12-9:13|0|1|4", "10:14-10:15|0|1|4"] }], - "funcs": [{ - "id": 0, - "usr": 16359708726068806331, - "detailed_name": "unique_ptr *return_type()", + "usr2var": [{ + "usr": 3364438781074774169, + "detailed_name": "unique_ptr *local", "qual_name_offset": 15, - "short_name": "return_type", - "kind": 12, - "storage": 1, + "short_name": "local", "declarations": [], - "spell": "9:16-9:27|-1|1|2", - "extent": "9:1-12:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [2], + "spell": "10:18-10:23|16359708726068806331|3|2", + "extent": "10:3-10:23|16359708726068806331|3|0", + "type": 3286534761799572592, "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, + "kind": 13, + "storage": 1 + }, { "usr": 12857919739649552168, "detailed_name": "unique_ptr f0", "qual_name_offset": 17, "short_name": "f0", "declarations": [], - "spell": "6:25-6:27|-1|1|2", - "extent": "6:1-6:27|-1|1|0", - "type": 0, + "spell": "6:25-6:27|0|1|2", + "extent": "6:1-6:27|0|1|0", + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 3 }, { - "id": 1, "usr": 18075066956054788088, "detailed_name": "unique_ptr f1", "qual_name_offset": 14, "short_name": "f1", "declarations": [], - "spell": "7:22-7:24|-1|1|2", - "extent": "7:1-7:24|-1|1|0", - "type": 0, + "spell": "7:22-7:24|0|1|2", + "extent": "7:1-7:24|0|1|0", + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 3 - }, { - "id": 2, - "usr": 2462000803278878465, - "detailed_name": "unique_ptr *local", - "qual_name_offset": 15, - "short_name": "local", - "declarations": [], - "spell": "10:18-10:23|0|3|2", - "extent": "10:3-10:23|0|3|0", - "type": 0, - "uses": [], - "kind": 13, - "storage": 1 }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index f5614cc8e..fe9d3d94b 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -83,162 +83,156 @@ unique_ptr* Foo::foo() { return nullptr; } { "includes": [], "skipped_by_preprocessor": ["7:1-14:7", "17:1-32:7", "35:1-39:7", "42:1-52:7", "57:1-63:7", "68:1-78:7"], - "types": [{ - "id": 0, - "usr": 14209198335088845323, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, - "short_name": "unique_ptr", - "kind": 5, - "declarations": ["2:7-2:17|-1|1|1"], + "usr2func": [{ + "usr": 1246637699196435450, + "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", + "qual_name_offset": 36, + "short_name": "as_return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "33:37-33:51|0|1|2", + "extent": "33:1-33:92|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [0, 1], - "uses": ["15:8-15:18|-1|1|4", "15:19-15:29|-1|1|4", "33:1-33:11|-1|1|4", "33:12-33:22|-1|1|4", "33:52-33:62|-1|1|4", "54:3-54:13|-1|1|4", "54:14-54:24|-1|1|4", "65:3-65:13|-1|1|4", "79:1-79:11|-1|1|4"] + "uses": [], + "callees": [] }, { - "id": 1, + "usr": 13067214284561914253, + "detailed_name": "void no_return_type(int)", + "qual_name_offset": 5, + "short_name": "no_return_type", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "40:6-40:20|0|1|2", + "extent": "40:1-40:28|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 17922201480358737771, + "detailed_name": "unique_ptr *Foo::foo()", + "qual_name_offset": 20, + "short_name": "foo", + "kind": 6, + "storage": 1, + "declarations": ["65:23-65:26|15041163540773201510|2|1"], + "spell": "79:26-79:29|15041163540773201510|2|2", + "extent": "79:1-79:51|0|1|0", + "declaring_type": 15041163540773201510, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 18320186404467436976, + "detailed_name": "void empty()", + "qual_name_offset": 5, + "short_name": "empty", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "53:6-53:11|0|1|2", + "extent": "53:1-55:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [500112618220246], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 4310164820010458371, "detailed_name": "S1", "qual_name_offset": 0, "short_name": "S1", "kind": 23, - "declarations": ["4:8-4:10|-1|1|1"], + "declarations": ["4:8-4:10|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["15:30-15:32|-1|1|4", "33:23-33:25|-1|1|4", "33:63-33:65|-1|1|4", "54:25-54:27|-1|1|4", "65:14-65:16|-1|1|4", "79:12-79:14|-1|1|4"] + "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|0|1|4", "65:14-65:16|0|1|4", "79:12-79:14|0|1|4"] }, { - "id": 2, "usr": 12728490517004312484, "detailed_name": "S2", "qual_name_offset": 0, "short_name": "S2", "kind": 23, - "declarations": ["5:8-5:10|-1|1|1"], + "declarations": ["5:8-5:10|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["15:34-15:36|-1|1|4", "15:39-15:41|-1|1|4", "33:27-33:29|-1|1|4", "33:32-33:34|-1|1|4", "33:67-33:69|-1|1|4", "54:29-54:31|-1|1|4", "54:34-54:36|-1|1|4", "65:18-65:20|-1|1|4", "79:16-79:18|-1|1|4"] + "uses": ["15:34-15:36|0|1|4", "15:39-15:41|0|1|4", "33:27-33:29|0|1|4", "33:32-33:34|0|1|4", "33:67-33:69|0|1|4", "54:29-54:31|0|1|4", "54:34-54:36|0|1|4", "65:18-65:20|0|1|4", "79:16-79:18|0|1|4"] + }, { + "usr": 14209198335088845323, + "detailed_name": "unique_ptr", + "qual_name_offset": 0, + "short_name": "unique_ptr", + "kind": 5, + "declarations": ["2:7-2:17|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2933643612409209903, 500112618220246], + "uses": ["15:8-15:18|0|1|4", "15:19-15:29|0|1|4", "33:1-33:11|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:3-54:13|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] }, { - "id": 3, "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "64:7-64:10|-1|1|2", - "extent": "64:1-66:2|-1|1|0", + "spell": "64:7-64:10|0|1|2", + "extent": "64:1-66:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], - "funcs": [3], + "funcs": [17922201480358737771], "vars": [], "instances": [], - "uses": ["79:21-79:24|-1|1|4"] + "uses": ["79:21-79:24|0|1|4"] }], - "funcs": [{ - "id": 0, - "usr": 1246637699196435450, - "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", + "usr2var": [{ + "usr": 500112618220246, + "detailed_name": "unique_ptr, S2> *local", "qual_name_offset": 36, - "short_name": "as_return_type", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "33:37-33:51|-1|1|2", - "extent": "33:1-33:92|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 1, - "usr": 13067214284561914253, - "detailed_name": "void no_return_type(int)", - "qual_name_offset": 5, - "short_name": "no_return_type", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "40:6-40:20|-1|1|2", - "extent": "40:1-40:28|-1|1|0", - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 2, - "usr": 18320186404467436976, - "detailed_name": "void empty()", - "qual_name_offset": 5, - "short_name": "empty", - "kind": 12, - "storage": 1, + "short_name": "local", "declarations": [], - "spell": "53:6-53:11|-1|1|2", - "extent": "53:1-55:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [1], + "spell": "54:39-54:44|18320186404467436976|3|2", + "extent": "54:3-54:44|18320186404467436976|3|0", + "type": 14209198335088845323, "uses": [], - "callees": [] + "kind": 13, + "storage": 1 }, { - "id": 3, - "usr": 17922201480358737771, - "detailed_name": "unique_ptr *Foo::foo()", - "qual_name_offset": 20, - "short_name": "foo", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "65:23-65:26|3|2|1", - "param_spellings": [] - }], - "spell": "79:26-79:29|3|2|2", - "extent": "79:1-79:51|-1|1|0", - "declaring_type": 3, - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, "usr": 2933643612409209903, "detailed_name": "unique_ptr, S2> f", "qual_name_offset": 35, "short_name": "f", - "declarations": ["15:43-15:44|-1|1|1"], - "type": 0, + "declarations": ["15:43-15:44|0|1|1"], + "type": 14209198335088845323, "uses": [], "kind": 13, "storage": 2 - }, { - "id": 1, - "usr": 11547294959889394856, - "detailed_name": "unique_ptr, S2> *local", - "qual_name_offset": 36, - "short_name": "local", - "declarations": [], - "spell": "54:39-54:44|2|3|2", - "extent": "54:3-54:44|2|3|0", - "type": 0, - "uses": [], - "kind": 13, - "storage": 1 }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 3401f59a3..d06a630a0 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -10,50 +10,49 @@ static unique_ptr foo; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 3286534761799572592, "detailed_name": "unique_ptr", "qual_name_offset": 0, "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|-1|1|2", - "extent": "2:1-2:20|-1|1|0", + "spell": "2:7-2:17|0|1|2", + "extent": "2:1-2:20|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["6:8-6:18|-1|1|4"] + "instances": [3398408600781120939], + "uses": ["6:8-6:18|0|1|4"] }, { - "id": 1, "usr": 4750332761459066907, "detailed_name": "S", "qual_name_offset": 0, "short_name": "S", "kind": 23, - "declarations": ["4:8-4:9|-1|1|1"], + "declarations": ["4:8-4:9|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["6:19-6:20|-1|1|4"] + "uses": ["6:19-6:20|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 3398408600781120939, "detailed_name": "unique_ptr foo", "qual_name_offset": 14, "short_name": "foo", "declarations": [], - "spell": "6:22-6:25|-1|1|2", - "extent": "6:1-6:25|-1|1|0", - "type": 0, + "spell": "6:22-6:25|0|1|2", + "extent": "6:1-6:25|0|1|0", + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 3 diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index 5bb504200..7ca6501b8 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -6,33 +6,32 @@ extern T t; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 5673439900521455039, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", "kind": 23, "declarations": [], - "spell": "1:8-1:9|-1|1|2", - "extent": "1:1-1:12|-1|1|0", + "spell": "1:8-1:9|0|1|2", + "extent": "1:1-1:12|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["3:8-3:9|-1|1|4"] + "instances": [1346710425945444872], + "uses": ["3:8-3:9|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 1346710425945444872, "detailed_name": "T t", "qual_name_offset": 2, "short_name": "t", - "declarations": ["3:10-3:11|-1|1|1"], - "type": 0, + "declarations": ["3:10-3:11|0|1|1"], + "type": 5673439900521455039, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 195f5afa6..d5814ff92 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -11,80 +11,78 @@ struct Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13749354388332789217, - "detailed_name": "ForwardType", + "usr2func": [], + "usr2type": [{ + "usr": 8508299082070213750, + "detailed_name": "ImplementedType", "qual_name_offset": 0, - "short_name": "ForwardType", + "short_name": "ImplementedType", "kind": 23, - "declarations": ["1:8-1:19|-1|1|1"], + "declarations": [], + "spell": "2:8-2:23|0|1|2", + "extent": "2:1-2:26|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["5:3-5:14|-1|1|4"] + "instances": [14727441168849658842], + "uses": ["6:3-6:18|0|1|4"] }, { - "id": 1, - "usr": 8508299082070213750, - "detailed_name": "ImplementedType", + "usr": 13749354388332789217, + "detailed_name": "ForwardType", "qual_name_offset": 0, - "short_name": "ImplementedType", + "short_name": "ForwardType", "kind": 23, - "declarations": [], - "spell": "2:8-2:23|-1|1|2", - "extent": "2:1-2:26|-1|1|0", + "declarations": ["1:8-1:19|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], - "uses": ["6:3-6:18|-1|1|4"] + "instances": [14314859014962085433], + "uses": ["5:3-5:14|0|1|4"] }, { - "id": 2, "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "4:8-4:11|-1|1|2", - "extent": "4:1-7:2|-1|1|0", + "spell": "4:8-4:11|0|1|2", + "extent": "4:1-7:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0, 1], + "vars": [14314859014962085433, 14727441168849658842], "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 14314859014962085433, "detailed_name": "ForwardType *Foo::a", "qual_name_offset": 13, "short_name": "a", "declarations": [], - "spell": "5:16-5:17|2|2|2", - "extent": "5:3-5:17|2|2|0", - "type": 0, + "spell": "5:16-5:17|15041163540773201510|2|2", + "extent": "5:3-5:17|15041163540773201510|2|0", + "type": 13749354388332789217, "uses": [], "kind": 8, "storage": 0 }, { - "id": 1, "usr": 14727441168849658842, "detailed_name": "ImplementedType Foo::b", "qual_name_offset": 16, "short_name": "b", "declarations": [], - "spell": "6:19-6:20|2|2|2", - "extent": "6:3-6:20|2|2|0", - "type": 1, + "spell": "6:19-6:20|15041163540773201510|2|2", + "extent": "6:3-6:20|15041163540773201510|2|0", + "type": 8508299082070213750, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 2822020db..436dbf71d 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -11,79 +11,77 @@ void Foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, - "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|-1|1|1"], + "usr2func": [{ + "usr": 4654328188330986029, + "detailed_name": "void Foo()", + "qual_name_offset": 5, + "short_name": "Foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|0|1|2", + "extent": "4:1-7:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": ["5:3-5:14|-1|1|4"] - }, { - "id": 1, + "vars": [16374832544037266261, 2580122838476012357], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 8508299082070213750, "detailed_name": "ImplementedType", "qual_name_offset": 0, "short_name": "ImplementedType", "kind": 23, "declarations": [], - "spell": "2:8-2:23|-1|1|2", - "extent": "2:1-2:26|-1|1|0", + "spell": "2:8-2:23|0|1|2", + "extent": "2:1-2:26|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], - "uses": ["6:3-6:18|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 4654328188330986029, - "detailed_name": "void Foo()", - "qual_name_offset": 5, - "short_name": "Foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "4:6-4:9|-1|1|2", - "extent": "4:1-7:2|-1|1|0", + "instances": [2580122838476012357], + "uses": ["6:3-6:18|0|1|4"] + }, { + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "qual_name_offset": 0, + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] + "types": [], + "funcs": [], + "vars": [], + "instances": [16374832544037266261], + "uses": ["5:3-5:14|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 11033478034711123650, - "detailed_name": "ForwardType *a", - "qual_name_offset": 13, - "short_name": "a", + "usr2var": [{ + "usr": 2580122838476012357, + "detailed_name": "ImplementedType b", + "qual_name_offset": 16, + "short_name": "b", "declarations": [], - "spell": "5:16-5:17|0|3|2", - "extent": "5:3-5:17|0|3|0", - "type": 0, + "spell": "6:19-6:20|4654328188330986029|3|2", + "extent": "6:3-6:20|4654328188330986029|3|0", + "type": 8508299082070213750, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 8949902309768550158, - "detailed_name": "ImplementedType b", - "qual_name_offset": 16, - "short_name": "b", + "usr": 16374832544037266261, + "detailed_name": "ForwardType *a", + "qual_name_offset": 13, + "short_name": "a", "declarations": [], - "spell": "6:19-6:20|0|3|2", - "extent": "6:3-6:20|0|3|0", - "type": 1, + "spell": "5:16-5:17|4654328188330986029|3|2", + "extent": "5:3-5:17|4654328188330986029|3|0", + "type": 13749354388332789217, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index b12d9ec31..205b9da96 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -8,79 +8,77 @@ void foo(ForwardType* f, ImplementedType a) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, - "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|-1|1|1"], + "usr2func": [{ + "usr": 1699390678058422036, + "detailed_name": "void foo(ForwardType *f, ImplementedType a)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "4:6-4:9|0|1|2", + "extent": "4:1-4:47|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": ["4:10-4:21|-1|1|4"] - }, { - "id": 1, + "vars": [13058491096576226774, 11055777568039014776], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 8508299082070213750, "detailed_name": "ImplementedType", "qual_name_offset": 0, "short_name": "ImplementedType", "kind": 23, "declarations": [], - "spell": "2:8-2:23|-1|1|2", - "extent": "2:1-2:26|-1|1|0", + "spell": "2:8-2:23|0|1|2", + "extent": "2:1-2:26|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [1], - "uses": ["4:26-4:41|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 1699390678058422036, - "detailed_name": "void foo(ForwardType *f, ImplementedType a)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "4:6-4:9|-1|1|2", - "extent": "4:1-4:47|-1|1|0", + "instances": [11055777568039014776], + "uses": ["4:26-4:41|0|1|4"] + }, { + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "qual_name_offset": 0, + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] + "types": [], + "funcs": [], + "vars": [], + "instances": [13058491096576226774], + "uses": ["4:10-4:21|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 2584795197111552890, - "detailed_name": "ForwardType *f", - "qual_name_offset": 13, - "short_name": "f", + "usr2var": [{ + "usr": 11055777568039014776, + "detailed_name": "ImplementedType a", + "qual_name_offset": 16, + "short_name": "a", "declarations": [], - "spell": "4:23-4:24|0|3|2", - "extent": "4:10-4:24|0|3|0", - "type": 0, + "spell": "4:42-4:43|1699390678058422036|3|2", + "extent": "4:26-4:43|1699390678058422036|3|0", + "type": 8508299082070213750, "uses": [], "kind": 253, "storage": 1 }, { - "id": 1, - "usr": 5136230284979460117, - "detailed_name": "ImplementedType a", - "qual_name_offset": 16, - "short_name": "a", + "usr": 13058491096576226774, + "detailed_name": "ForwardType *f", + "qual_name_offset": 13, + "short_name": "f", "declarations": [], - "spell": "4:42-4:43|0|3|2", - "extent": "4:26-4:43|0|3|0", - "type": 1, + "spell": "4:23-4:24|1699390678058422036|3|2", + "extent": "4:10-4:24|1699390678058422036|3|0", + "type": 13749354388332789217, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 7b16a92fb..e66c6db2b 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -13,52 +13,48 @@ void foo(Foo* f, Foo*) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|-1|1|1"], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": ["3:10-3:13|-1|1|4", "3:18-3:21|-1|1|4", "4:10-4:13|-1|1|4", "4:18-4:21|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 8908726657907936744, "detailed_name": "void foo(Foo *f, Foo *)", "qual_name_offset": 5, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "3:6-3:9|-1|1|1", - "param_spellings": ["3:15-3:16", "3:22-3:22"] - }], - "spell": "4:6-4:9|-1|1|2", - "extent": "4:1-4:26|-1|1|0", + "declarations": ["3:6-3:9|0|1|1"], + "spell": "4:6-4:9|0|1|2", + "extent": "4:1-4:26|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0], + "vars": [13823260660189154978], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 2161866804398917919, + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [13823260660189154978], + "uses": ["3:10-3:13|0|1|4", "3:18-3:21|0|1|4", "4:10-4:13|0|1|4", "4:18-4:21|0|1|4"] + }], + "usr2var": [{ + "usr": 13823260660189154978, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", "declarations": [], - "spell": "4:15-4:16|0|3|2", - "extent": "4:10-4:16|0|3|0", - "type": 0, + "spell": "4:15-4:16|8908726657907936744|3|2", + "extent": "4:10-4:16|8908726657907936744|3|0", + "type": 15041163540773201510, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index b588c4f7d..fb8c6e8fd 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -5,24 +5,7 @@ void foo(ForwardType*) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, - "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|-1|1|1"], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["2:10-2:21|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 15327735280790448926, "detailed_name": "void foo(ForwardType *)", "qual_name_offset": 5, @@ -30,14 +13,31 @@ void foo(ForwardType*) {} "kind": 12, "storage": 1, "declarations": [], - "spell": "2:6-2:9|-1|1|2", - "extent": "2:1-2:26|-1|1|0", + "spell": "2:6-2:9|0|1|2", + "extent": "2:1-2:26|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 13749354388332789217, + "detailed_name": "ForwardType", + "qual_name_offset": 0, + "short_name": "ForwardType", + "kind": 23, + "declarations": ["1:8-1:19|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["2:10-2:21|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 086219647..fbf7cac4b 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -11,26 +11,7 @@ void foo(Type& a0, const Type& a1) { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, - "short_name": "Type", - "kind": 23, - "declarations": [], - "spell": "1:8-1:12|-1|1|2", - "extent": "1:1-1:15|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1, 2, 3, 4, 5], - "uses": ["3:10-3:14|-1|1|4", "3:26-3:30|-1|1|4", "4:3-4:7|-1|1|4", "5:3-5:7|-1|1|4", "6:9-6:13|-1|1|4", "7:9-7:13|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 16858540520096802573, "detailed_name": "void foo(Type &a0, const Type &a1)", "qual_name_offset": 5, @@ -38,93 +19,106 @@ void foo(Type& a0, const Type& a1) { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-8:2|-1|1|0", + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0, 1, 2, 3, 4, 5], + "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 16414210592877294238, - "detailed_name": "Type &a0", - "qual_name_offset": 6, - "short_name": "a0", + "usr2type": [{ + "usr": 13487927231218873822, + "detailed_name": "Type", + "qual_name_offset": 0, + "short_name": "Type", + "kind": 23, "declarations": [], - "spell": "3:16-3:18|0|3|2", - "extent": "3:10-3:18|0|3|0", - "type": 0, - "uses": [], - "kind": 253, - "storage": 1 - }, { - "id": 1, - "usr": 11558141642862804306, - "detailed_name": "const Type &a1", + "spell": "1:8-1:12|0|1|2", + "extent": "1:1-1:15|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], + "uses": ["3:10-3:14|0|1|4", "3:26-3:30|0|1|4", "4:3-4:7|0|1|4", "5:3-5:7|0|1|4", "6:9-6:13|0|1|4", "7:9-7:13|0|1|4"] + }], + "usr2var": [{ + "usr": 5004072032239834773, + "detailed_name": "const Type *a4", "qual_name_offset": 12, - "short_name": "a1", - "declarations": [], - "spell": "3:32-3:34|0|3|2", - "extent": "3:20-3:34|0|3|0", - "type": 0, - "uses": [], - "kind": 253, - "storage": 1 - }, { - "id": 2, - "usr": 1536316608590232194, - "detailed_name": "Type a2", - "qual_name_offset": 5, - "short_name": "a2", + "short_name": "a4", "declarations": [], - "spell": "4:8-4:10|0|3|2", - "extent": "4:3-4:10|0|3|0", - "type": 0, + "spell": "6:15-6:17|16858540520096802573|3|2", + "extent": "6:3-6:17|16858540520096802573|3|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 1 }, { - "id": 3, - "usr": 316760354845869406, + "usr": 6081981442495435784, "detailed_name": "Type *a3", "qual_name_offset": 6, "short_name": "a3", "declarations": [], - "spell": "5:9-5:11|0|3|2", - "extent": "5:3-5:11|0|3|0", - "type": 0, + "spell": "5:9-5:11|16858540520096802573|3|2", + "extent": "5:3-5:11|16858540520096802573|3|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 1 }, { - "id": 4, - "usr": 12321730890779907974, - "detailed_name": "const Type *a4", - "qual_name_offset": 12, - "short_name": "a4", + "usr": 7997456978847868736, + "detailed_name": "Type &a0", + "qual_name_offset": 6, + "short_name": "a0", "declarations": [], - "spell": "6:15-6:17|0|3|2", - "extent": "6:3-6:17|0|3|0", - "type": 0, + "spell": "3:16-3:18|16858540520096802573|3|2", + "extent": "3:10-3:18|16858540520096802573|3|0", + "type": 13487927231218873822, "uses": [], - "kind": 13, + "kind": 253, "storage": 1 }, { - "id": 5, - "usr": 4771437488905761633, + "usr": 14939253431683105646, "detailed_name": "const Type *const a5", "qual_name_offset": 18, "short_name": "a5", "hover": "const Type *const a5 = nullptr", "declarations": [], - "spell": "7:21-7:23|0|3|2", - "extent": "7:3-7:33|0|3|0", - "type": 0, + "spell": "7:21-7:23|16858540520096802573|3|2", + "extent": "7:3-7:33|16858540520096802573|3|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 1 + }, { + "usr": 15429032129697337561, + "detailed_name": "Type a2", + "qual_name_offset": 5, + "short_name": "a2", + "declarations": [], + "spell": "4:8-4:10|16858540520096802573|3|2", + "extent": "4:3-4:10|16858540520096802573|3|0", + "type": 13487927231218873822, + "uses": [], + "kind": 13, + "storage": 1 + }, { + "usr": 17228576662112939520, + "detailed_name": "const Type &a1", + "qual_name_offset": 12, + "short_name": "a1", + "declarations": [], + "spell": "3:32-3:34|16858540520096802573|3|2", + "extent": "3:20-3:34|16858540520096802573|3|0", + "type": 13487927231218873822, + "uses": [], + "kind": 253, + "storage": 1 }] } */ diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index 53b6926a1..c2caccfce 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -5,35 +5,34 @@ static Type t; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 13487927231218873822, "detailed_name": "Type", "qual_name_offset": 0, "short_name": "Type", "kind": 23, "declarations": [], - "spell": "1:8-1:12|-1|1|2", - "extent": "1:1-1:15|-1|1|0", + "spell": "1:8-1:12|0|1|2", + "extent": "1:1-1:15|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["2:8-2:12|-1|1|4"] + "instances": [6601831367240627080], + "uses": ["2:8-2:12|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 6601831367240627080, "detailed_name": "Type t", "qual_name_offset": 5, "short_name": "t", "declarations": [], - "spell": "2:13-2:14|-1|1|2", - "extent": "2:1-2:14|-1|1|0", - "type": 0, + "spell": "2:13-2:14|0|1|2", + "extent": "2:1-2:14|0|1|0", + "type": 13487927231218873822, "uses": [], "kind": 13, "storage": 3 diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index dfbc8836a..385f079f2 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -22,138 +22,118 @@ static Type* bar() { return nullptr; } { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, - "short_name": "Type", - "kind": 23, - "declarations": ["1:8-1:12|-1|1|1"], + "usr2func": [{ + "usr": 4240751906910175539, + "detailed_name": "void Foo::Empty()", + "qual_name_offset": 5, + "short_name": "Empty", + "kind": 6, + "storage": 1, + "declarations": ["9:8-9:13|15041163540773201510|2|1"], + "spell": "13:11-13:16|15041163540773201510|2|2", + "extent": "13:1-13:21|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["3:1-3:5|-1|1|4", "4:1-4:5|-1|1|4", "5:1-5:5|-1|1|4", "8:3-8:7|-1|1|4", "12:1-12:5|-1|1|4", "15:14-15:18|-1|1|4", "17:8-17:12|-1|1|4", "18:8-18:12|-1|1|4"] + "uses": [], + "callees": [] }, { - "id": 1, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "7:7-7:10|-1|1|2", - "extent": "7:1-10:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [1, 2], - "vars": [], - "instances": [], - "uses": ["12:7-12:10|-1|1|4", "13:6-13:9|-1|1|4"] - }], - "funcs": [{ - "id": 0, "usr": 4259594751088586730, "detailed_name": "Type *foo()", "qual_name_offset": 6, "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "3:7-3:10|-1|1|1", - "param_spellings": [] - }, { - "spell": "4:7-4:10|-1|1|1", - "param_spellings": [] - }], - "spell": "5:7-5:10|-1|1|2", - "extent": "5:1-5:32|-1|1|0", + "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], + "spell": "5:7-5:10|0|1|2", + "extent": "5:1-5:32|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 1, - "usr": 13402221340333431092, - "detailed_name": "Type *Foo::Get(int)", - "qual_name_offset": 6, - "short_name": "Get", - "kind": 6, - "storage": 1, - "declarations": [{ - "spell": "8:9-8:12|1|2|1", - "param_spellings": ["8:16-8:16"] - }], - "spell": "12:12-12:15|1|2|2", - "extent": "12:1-12:40|-1|1|0", - "declaring_type": 1, + "usr": 7746867874366499515, + "detailed_name": "const Type &external()", + "qual_name_offset": 12, + "short_name": "external", + "kind": 12, + "storage": 2, + "declarations": ["15:20-15:28|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 2, - "usr": 4240751906910175539, - "detailed_name": "void Foo::Empty()", - "qual_name_offset": 5, - "short_name": "Empty", + "usr": 13402221340333431092, + "detailed_name": "Type *Foo::Get(int)", + "qual_name_offset": 6, + "short_name": "Get", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "9:8-9:13|1|2|1", - "param_spellings": [] - }], - "spell": "13:11-13:16|1|2|2", - "extent": "13:1-13:21|-1|1|0", - "declaring_type": 1, + "declarations": ["8:9-8:12|15041163540773201510|2|1"], + "spell": "12:12-12:15|15041163540773201510|2|2", + "extent": "12:1-12:40|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }, { - "id": 3, - "usr": 7746867874366499515, - "detailed_name": "const Type &external()", - "qual_name_offset": 12, - "short_name": "external", - "kind": 12, - "storage": 2, - "declarations": [{ - "spell": "15:20-15:28|-1|1|1", - "param_spellings": [] - }], - "bases": [], - "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "id": 4, "usr": 18408440185620243373, "detailed_name": "Type *bar()", "qual_name_offset": 6, "short_name": "bar", "kind": 12, "storage": 3, - "declarations": [{ - "spell": "17:14-17:17|-1|1|1", - "param_spellings": [] - }], - "spell": "18:14-18:17|-1|1|2", - "extent": "18:1-18:39|-1|1|0", + "declarations": ["17:14-17:17|0|1|1"], + "spell": "18:14-18:17|0|1|2", + "extent": "18:1-18:39|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [{ + "usr": 13487927231218873822, + "detailed_name": "Type", + "qual_name_offset": 0, + "short_name": "Type", + "kind": 23, + "declarations": ["1:8-1:12|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["3:1-3:5|0|1|4", "4:1-4:5|0|1|4", "5:1-5:5|0|1|4", "8:3-8:7|0|1|4", "12:1-12:5|0|1|4", "15:14-15:18|0|1|4", "17:8-17:12|0|1|4", "18:8-18:12|0|1|4"] + }, { + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "7:7-7:10|0|1|2", + "extent": "7:1-10:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [13402221340333431092, 4240751906910175539], + "vars": [], + "instances": [], + "uses": ["12:7-12:10|0|1|4", "13:6-13:9|0|1|4"] + }], + "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index 6b243e4a5..67b992fd3 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -14,86 +14,79 @@ void accept3(Foo3*) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|-1|1|1"], + "usr2func": [{ + "usr": 558620830317390922, + "detailed_name": "void accept1(Foo1 *)", + "qual_name_offset": 5, + "short_name": "accept1", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "8:6-8:13|0|1|2", + "extent": "8:1-8:23|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["2:14-2:17|-1|1|4", "3:9-3:12|-1|1|4", "7:13-7:16|-1|1|4"] + "uses": [], + "callees": [] }, { - "id": 1, - "usr": 1544499294580512394, - "detailed_name": "Foo1", - "qual_name_offset": 0, - "short_name": "Foo1", - "kind": 252, - "hover": "using Foo1 = Foo*", + "usr": 9119341505144503905, + "detailed_name": "void accept(Foo *)", + "qual_name_offset": 5, + "short_name": "accept", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "2:7-2:11|-1|1|2", - "extent": "2:1-2:18|-1|1|0", - "alias_of": 0, + "spell": "7:6-7:12|0|1|2", + "extent": "7:1-7:21|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["2:7-2:11|-1|1|4", "4:14-4:18|-1|1|4", "8:14-8:18|-1|1|4"] + "uses": [], + "callees": [] }, { - "id": 2, - "usr": 15466821155413653804, - "detailed_name": "Foo2", - "qual_name_offset": 0, - "short_name": "Foo2", - "kind": 252, - "hover": "typedef Foo Foo2", + "usr": 10523262907746124479, + "detailed_name": "void accept2(Foo2 *)", + "qual_name_offset": 5, + "short_name": "accept2", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "3:13-3:17|-1|1|2", - "extent": "3:1-3:17|-1|1|0", - "alias_of": 0, + "spell": "9:6-9:13|0|1|2", + "extent": "9:1-9:23|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["3:13-3:17|-1|1|4", "9:14-9:18|-1|1|4"] + "uses": [], + "callees": [] }, { - "id": 3, - "usr": 17897026942631673064, - "detailed_name": "Foo3", - "qual_name_offset": 0, - "short_name": "Foo3", - "kind": 252, - "hover": "using Foo3 = Foo1", + "usr": 14986366321326974406, + "detailed_name": "void accept3(Foo3 *)", + "qual_name_offset": 5, + "short_name": "accept3", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "4:7-4:11|-1|1|2", - "extent": "4:1-4:18|-1|1|0", - "alias_of": 1, + "spell": "10:6-10:13|0|1|2", + "extent": "10:1-10:23|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["4:7-4:11|-1|1|4", "10:14-10:18|-1|1|4"] - }, { - "id": 4, + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], @@ -102,90 +95,93 @@ void accept3(Foo3*) {} "instances": [], "uses": [] }, { - "id": 5, - "usr": 2638219001294786365, - "detailed_name": "Foo4", + "usr": 1544499294580512394, + "detailed_name": "Foo1", "qual_name_offset": 0, - "short_name": "Foo4", + "short_name": "Foo1", "kind": 252, - "hover": "using Foo4 = int", + "hover": "using Foo1 = Foo*", "declarations": [], - "spell": "5:7-5:11|-1|1|2", - "extent": "5:1-5:17|-1|1|0", - "alias_of": 4, + "spell": "2:7-2:11|0|1|2", + "extent": "2:1-2:18|0|1|0", + "alias_of": 15041163540773201510, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["5:7-5:11|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 9119341505144503905, - "detailed_name": "void accept(Foo *)", - "qual_name_offset": 5, - "short_name": "accept", - "kind": 12, - "storage": 1, + "uses": ["2:7-2:11|0|1|4", "4:14-4:18|0|1|4", "8:14-8:18|0|1|4"] + }, { + "usr": 2638219001294786365, + "detailed_name": "Foo4", + "qual_name_offset": 0, + "short_name": "Foo4", + "kind": 252, + "hover": "using Foo4 = int", "declarations": [], - "spell": "7:6-7:12|-1|1|2", - "extent": "7:1-7:21|-1|1|0", + "spell": "5:7-5:11|0|1|2", + "extent": "5:1-5:17|0|1|0", + "alias_of": 17, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["5:7-5:11|0|1|4"] }, { - "id": 1, - "usr": 558620830317390922, - "detailed_name": "void accept1(Foo1 *)", - "qual_name_offset": 5, - "short_name": "accept1", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "8:6-8:13|-1|1|2", - "extent": "8:1-8:23|-1|1|0", + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|0|1|1"], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["2:14-2:17|0|1|4", "3:9-3:12|0|1|4", "7:13-7:16|0|1|4"] }, { - "id": 2, - "usr": 10523262907746124479, - "detailed_name": "void accept2(Foo2 *)", - "qual_name_offset": 5, - "short_name": "accept2", - "kind": 12, - "storage": 1, + "usr": 15466821155413653804, + "detailed_name": "Foo2", + "qual_name_offset": 0, + "short_name": "Foo2", + "kind": 252, + "hover": "typedef Foo Foo2", "declarations": [], - "spell": "9:6-9:13|-1|1|2", - "extent": "9:1-9:23|-1|1|0", + "spell": "3:13-3:17|0|1|2", + "extent": "3:1-3:17|0|1|0", + "alias_of": 15041163540773201510, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["3:13-3:17|0|1|4", "9:14-9:18|0|1|4"] }, { - "id": 3, - "usr": 14986366321326974406, - "detailed_name": "void accept3(Foo3 *)", - "qual_name_offset": 5, - "short_name": "accept3", - "kind": 12, - "storage": 1, + "usr": 17897026942631673064, + "detailed_name": "Foo3", + "qual_name_offset": 0, + "short_name": "Foo3", + "kind": 252, + "hover": "using Foo3 = Foo1", "declarations": [], - "spell": "10:6-10:13|-1|1|2", - "extent": "10:1-10:23|-1|1|0", + "spell": "4:7-4:11|0|1|2", + "extent": "4:1-4:18|0|1|0", + "alias_of": 1544499294580512394, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": [] + "instances": [], + "uses": ["4:7-4:11|0|1|4", "10:14-10:18|0|1|4"] }], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index a9f31ef07..92b4f6b2d 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -9,32 +9,32 @@ typedef Foo Foo2; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 10528472276654770367, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 1544499294580512394, + "detailed_name": "Foo1", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": ["2:8-2:11|-1|1|1"], + "short_name": "Foo1", + "kind": 252, + "hover": "using Foo1 = Foo", + "declarations": [], + "spell": "4:7-4:11|0|1|2", + "extent": "4:1-4:22|0|1|0", + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["4:14-4:17|-1|1|4", "5:9-5:12|-1|1|4"] + "uses": ["4:7-4:11|0|1|4", "5:13-5:17|0|1|4"] }, { - "id": 1, - "usr": 1544499294580512394, - "detailed_name": "Foo1", + "usr": 10528472276654770367, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "Foo1", - "kind": 252, - "hover": "using Foo1 = Foo", - "declarations": [], - "spell": "4:7-4:11|-1|1|2", - "extent": "4:1-4:22|-1|1|0", + "short_name": "Foo", + "kind": 5, + "declarations": ["2:8-2:11|0|1|1"], "alias_of": 0, "bases": [], "derived": [], @@ -42,9 +42,8 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["4:7-4:11|-1|1|4", "5:13-5:17|-1|1|4"] + "uses": ["4:14-4:17|0|1|4", "5:9-5:12|0|1|4"] }, { - "id": 2, "usr": 15933698173231330933, "detailed_name": "Foo2", "qual_name_offset": 0, @@ -52,18 +51,17 @@ typedef Foo Foo2; "kind": 252, "hover": "typedef Foo Foo2", "declarations": [], - "spell": "5:19-5:23|-1|1|2", - "extent": "5:1-5:23|-1|1|0", - "alias_of": 0, + "spell": "5:19-5:23|0|1|2", + "extent": "5:1-5:23|0|1|0", + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["5:19-5:23|-1|1|4"] + "uses": ["5:19-5:23|0|1|4"] }], - "funcs": [], - "vars": [] + "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index a2ae182ef..5ad5b235a 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -14,69 +14,63 @@ extern Foo foo; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [0], - "vars": [], - "instances": [0, 1], - "uses": ["2:3-2:6|-1|1|4", "5:1-5:4|-1|1|4", "5:6-5:9|-1|1|4", "6:3-6:6|-1|1|4", "10:8-10:11|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 9488177941273031343, "detailed_name": "Foo *Foo::make()", "qual_name_offset": 5, "short_name": "make", "kind": 6, "storage": 1, - "declarations": [{ - "spell": "2:8-2:12|0|2|1", - "param_spellings": [] - }], - "spell": "5:11-5:15|0|2|2", - "extent": "5:1-8:2|-1|1|0", - "declaring_type": 0, + "declarations": ["2:8-2:12|15041163540773201510|2|1"], + "spell": "5:11-5:15|15041163540773201510|2|2", + "extent": "5:1-8:2|0|1|0", + "declaring_type": 15041163540773201510, "bases": [], "derived": [], - "vars": [0], + "vars": [16380484338511689669], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 14873619387499024780, - "detailed_name": "Foo f", - "qual_name_offset": 4, - "short_name": "f", + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "6:7-6:8|0|3|2", - "extent": "6:3-6:8|0|3|0", - "type": 0, - "uses": [], - "kind": 13, - "storage": 1 - }, { - "id": 1, + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [9488177941273031343], + "vars": [], + "instances": [16380484338511689669, 14455976355866885943], + "uses": ["2:3-2:6|0|1|4", "5:1-5:4|0|1|4", "5:6-5:9|0|1|4", "6:3-6:6|0|1|4", "10:8-10:11|0|1|4"] + }], + "usr2var": [{ "usr": 14455976355866885943, "detailed_name": "Foo foo", "qual_name_offset": 4, "short_name": "foo", - "declarations": ["10:12-10:15|-1|1|1"], - "type": 0, + "declarations": ["10:12-10:15|0|1|1"], + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 2 + }, { + "usr": 16380484338511689669, + "detailed_name": "Foo f", + "qual_name_offset": 4, + "short_name": "f", + "declarations": [], + "spell": "6:7-6:8|9488177941273031343|3|2", + "extent": "6:3-6:8|9488177941273031343|3|0", + "type": 15041163540773201510, + "uses": [], + "kind": 13, + "storage": 1 }] } */ diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index c005b4bfb..93875bafe 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -19,130 +19,121 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "5:8-5:11|-1|1|2", - "extent": "5:1-8:2|-1|1|0", + "spell": "12:6-12:9|0|1|2", + "extent": "12:1-15:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [1, 0], - "instances": [], - "uses": ["10:5-10:8|-1|1|4", "14:22-14:25|-1|1|4", "14:40-14:43|-1|1|4"] + "vars": [8039186520399841081], + "uses": [], + "callees": ["14:3-14:9|18319417758892371313|3|32", "14:14-14:17|11404602816585117695|3|32"] }, { - "id": 1, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "usr": 11404602816585117695, + "detailed_name": "int gen()", + "qual_name_offset": 4, + "short_name": "gen", + "kind": 12, + "storage": 1, + "declarations": ["3:5-3:8|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [0, 1, 2], - "uses": [] - }], - "funcs": [{ - "id": 0, + "uses": ["14:14-14:17|4259594751088586730|3|32"], + "callees": [] + }, { "usr": 18319417758892371313, "detailed_name": "void called(int a)", "qual_name_offset": 5, "short_name": "called", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:12|-1|1|1", - "param_spellings": ["1:17-1:18"] - }], + "declarations": ["1:6-1:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|2|3|32"], + "uses": ["14:3-14:9|4259594751088586730|3|32"], "callees": [] - }, { - "id": 1, - "usr": 11404602816585117695, - "detailed_name": "int gen()", - "qual_name_offset": 4, - "short_name": "gen", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "3:5-3:8|-1|1|1", - "param_spellings": [] - }], + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": ["14:14-14:17|2|3|32"], - "callees": [] + "instances": [11489549839875479478, 9648311402855509901, 8039186520399841081], + "uses": [] }, { - "id": 2, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "12:6-12:9|-1|1|2", - "extent": "12:1-15:2|-1|1|0", + "spell": "5:8-5:11|0|1|2", + "extent": "5:1-8:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [2], - "uses": [], - "callees": ["14:3-14:9|0|3|32", "14:14-14:17|1|3|32"] + "types": [], + "funcs": [], + "vars": [9648311402855509901, 11489549839875479478], + "instances": [], + "uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 11489549839875479478, - "detailed_name": "int Foo::static_var", + "usr2var": [{ + "usr": 8039186520399841081, + "detailed_name": "int a", "qual_name_offset": 4, - "short_name": "static_var", - "hover": "int Foo::static_var = 0", - "declarations": ["6:14-6:24|0|2|1"], - "spell": "10:10-10:20|0|2|2", - "extent": "10:1-10:24|-1|1|0", - "type": 1, - "uses": ["14:45-14:55|2|3|4"], - "kind": 8, + "short_name": "a", + "hover": "int a = 5", + "declarations": [], + "spell": "13:7-13:8|4259594751088586730|3|2", + "extent": "13:3-13:12|4259594751088586730|3|0", + "type": 17, + "uses": ["14:10-14:11|4259594751088586730|3|4"], + "kind": 13, "storage": 1 }, { - "id": 1, "usr": 9648311402855509901, "detailed_name": "int Foo::field_var", "qual_name_offset": 4, "short_name": "field_var", "declarations": [], - "spell": "7:7-7:16|0|2|2", - "extent": "7:3-7:16|0|2|0", - "type": 1, - "uses": ["14:28-14:37|2|3|4"], + "spell": "7:7-7:16|15041163540773201510|2|2", + "extent": "7:3-7:16|15041163540773201510|2|0", + "type": 17, + "uses": ["14:28-14:37|4259594751088586730|3|4"], "kind": 8, "storage": 0 }, { - "id": 2, - "usr": 13284113377394221067, - "detailed_name": "int a", + "usr": 11489549839875479478, + "detailed_name": "int Foo::static_var", "qual_name_offset": 4, - "short_name": "a", - "hover": "int a = 5", - "declarations": [], - "spell": "13:7-13:8|2|3|2", - "extent": "13:3-13:12|2|3|0", - "type": 1, - "uses": ["14:10-14:11|2|3|4"], - "kind": 13, + "short_name": "static_var", + "hover": "int Foo::static_var = 0", + "declarations": ["6:14-6:24|15041163540773201510|2|1"], + "spell": "10:10-10:20|15041163540773201510|2|2", + "extent": "10:1-10:24|0|1|0", + "type": 17, + "uses": ["14:45-14:55|4259594751088586730|3|4"], + "kind": 8, "storage": 1 }] } diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 4aaa7875d..326e6592b 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -11,26 +11,23 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, - "usr": 18319417758892371313, - "detailed_name": "void called(int a)", + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", "qual_name_offset": 5, - "short_name": "called", + "short_name": "foo", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "1:6-1:12|-1|1|1", - "param_spellings": ["1:17-1:18"] - }], + "declarations": [], + "spell": "5:6-5:9|0|1|2", + "extent": "5:1-7:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:9|2|3|32"], - "callees": [] + "uses": [], + "callees": ["6:3-6:9|18319417758892371313|3|32", "6:10-6:13|11404602816585117695|3|32", "6:18-6:21|11404602816585117695|3|32"] }, { - "id": 1, "usr": 11404602816585117695, "detailed_name": "int gen()", "qual_name_offset": 4, @@ -38,30 +35,30 @@ void foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:5-3:8|-1|1|2", - "extent": "3:1-3:24|-1|1|0", + "spell": "3:5-3:8|0|1|2", + "extent": "3:1-3:24|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:10-6:13|2|3|32", "6:18-6:21|2|3|32"], + "uses": ["6:10-6:13|4259594751088586730|3|32", "6:18-6:21|4259594751088586730|3|32"], "callees": [] }, { - "id": 2, - "usr": 4259594751088586730, - "detailed_name": "void foo()", + "usr": 18319417758892371313, + "detailed_name": "void called(int a)", "qual_name_offset": 5, - "short_name": "foo", + "short_name": "called", "kind": 12, "storage": 1, - "declarations": [], - "spell": "5:6-5:9|-1|1|2", - "extent": "5:1-7:2|-1|1|0", + "declarations": ["1:6-1:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": [], - "callees": ["6:3-6:9|0|3|32", "6:10-6:13|1|3|32", "6:18-6:21|1|3|32"] + "uses": ["6:3-6:9|4259594751088586730|3|32"], + "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 1c34a7f2d..33a835f65 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -12,9 +12,7 @@ void caller() { { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", "qual_name_offset": 5, @@ -22,15 +20,15 @@ void caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "1:6-1:12|-1|1|2", - "extent": "1:1-1:17|-1|1|0", + "spell": "1:6-1:12|0|1|2", + "extent": "1:1-1:17|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:13-4:19|1|3|32", "7:3-7:9|1|3|32"], + "uses": ["4:13-4:19|11404881820527069090|3|32", "7:3-7:9|11404881820527069090|3|32"], "callees": [] }, { - "id": 1, "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, @@ -38,24 +36,26 @@ void caller() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:12|-1|1|2", - "extent": "3:1-8:2|-1|1|0", + "spell": "3:6-3:12|0|1|2", + "extent": "3:1-8:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0], + "vars": [9121974011454213596], "uses": [], - "callees": ["4:13-4:19|0|3|32", "4:13-4:19|0|3|32", "7:3-7:9|0|3|32"] + "callees": ["4:13-4:19|468307235068920063|3|32", "4:13-4:19|468307235068920063|3|32", "7:3-7:9|468307235068920063|3|32"] }], - "vars": [{ - "id": 0, - "usr": 3510529098767253033, + "usr2type": [], + "usr2var": [{ + "usr": 9121974011454213596, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", "declarations": [], - "spell": "4:8-4:9|1|3|2", - "extent": "4:3-4:19|1|3|0", - "uses": ["5:3-5:4|1|3|4"], + "spell": "4:8-4:9|11404881820527069090|3|2", + "extent": "4:3-4:19|11404881820527069090|3|0", + "type": 0, + "uses": ["5:3-5:4|11404881820527069090|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 003834a72..9eeeb6e8e 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -22,127 +22,118 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-5:2|-1|1|0", + "spell": "10:6-10:9|0|1|2", + "extent": "10:1-18:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [0, 1], - "instances": [2], - "uses": ["11:3-11:6|-1|1|4"] + "vars": [14669930844300034456], + "uses": [], + "callees": ["14:3-14:9|17175780305784503374|3|32", "15:3-15:9|17175780305784503374|3|32", "16:3-16:9|12086644540399881766|3|32", "17:3-17:9|17175780305784503374|3|32"] }, { - "id": 1, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 17175780305784503374, - "detailed_name": "void accept(int)", + "usr": 12086644540399881766, + "detailed_name": "void accept(int *)", "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "7:6-7:12|-1|1|1", - "param_spellings": ["7:16-7:16"] - }], + "declarations": ["8:6-8:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|2|3|32", "15:3-15:9|2|3|32", "17:3-17:9|2|3|32"], + "uses": ["16:3-16:9|4259594751088586730|3|32"], "callees": [] }, { - "id": 1, - "usr": 12086644540399881766, - "detailed_name": "void accept(int *)", + "usr": 17175780305784503374, + "detailed_name": "void accept(int)", "qual_name_offset": 5, "short_name": "accept", "kind": 12, "storage": 1, - "declarations": [{ - "spell": "8:6-8:12|-1|1|1", - "param_spellings": ["8:17-8:17"] - }], + "declarations": ["7:6-7:12|0|1|1"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["16:3-16:9|2|3|32"], + "uses": ["14:3-14:9|4259594751088586730|3|32", "15:3-15:9|4259594751088586730|3|32", "17:3-17:9|4259594751088586730|3|32"], "callees": [] + }], + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [4220150017963593039, 3873837747174060388], + "uses": [] }, { - "id": 2, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], - "spell": "10:6-10:9|-1|1|2", - "extent": "10:1-18:2|-1|1|0", + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-5:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [2], - "uses": [], - "callees": ["14:3-14:9|0|3|32", "15:3-15:9|0|3|32", "16:3-16:9|1|3|32", "17:3-17:9|0|3|32"] + "types": [], + "funcs": [], + "vars": [4220150017963593039, 3873837747174060388], + "instances": [14669930844300034456], + "uses": ["11:3-11:6|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 4220150017963593039, - "detailed_name": "int Foo::x", + "usr2var": [{ + "usr": 3873837747174060388, + "detailed_name": "int Foo::y", "qual_name_offset": 4, - "short_name": "x", + "short_name": "y", "declarations": [], - "spell": "3:7-3:8|0|2|2", - "extent": "3:3-3:8|0|2|0", - "type": 1, - "uses": ["12:5-12:6|2|3|4", "13:5-13:6|2|3|4", "14:12-14:13|2|3|4", "15:12-15:13|2|3|4", "16:13-16:14|2|3|4"], + "spell": "4:7-4:8|15041163540773201510|2|2", + "extent": "4:3-4:8|15041163540773201510|2|0", + "type": 17, + "uses": ["17:12-17:13|4259594751088586730|3|4"], "kind": 8, "storage": 0 }, { - "id": 1, - "usr": 3873837747174060388, - "detailed_name": "int Foo::y", + "usr": 4220150017963593039, + "detailed_name": "int Foo::x", "qual_name_offset": 4, - "short_name": "y", + "short_name": "x", "declarations": [], - "spell": "4:7-4:8|0|2|2", - "extent": "4:3-4:8|0|2|0", - "type": 1, - "uses": ["17:12-17:13|2|3|4"], + "spell": "3:7-3:8|15041163540773201510|2|2", + "extent": "3:3-3:8|15041163540773201510|2|0", + "type": 17, + "uses": ["12:5-12:6|4259594751088586730|3|4", "13:5-13:6|4259594751088586730|3|4", "14:12-14:13|4259594751088586730|3|4", "15:12-15:13|4259594751088586730|3|4", "16:13-16:14|4259594751088586730|3|4"], "kind": 8, "storage": 0 }, { - "id": 2, - "usr": 16303259148898744165, + "usr": 14669930844300034456, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "11:7-11:8|2|3|2", - "extent": "11:3-11:8|2|3|0", - "type": 0, - "uses": ["12:3-12:4|2|3|4", "13:3-13:4|2|3|4", "14:10-14:11|2|3|4", "15:10-15:11|2|3|4", "16:11-16:12|2|3|4", "17:10-17:11|2|3|4"], + "spell": "11:7-11:8|4259594751088586730|3|2", + "extent": "11:3-11:8|4259594751088586730|3|0", + "type": 15041163540773201510, + "uses": ["12:3-12:4|4259594751088586730|3|4", "13:3-13:4|4259594751088586730|3|4", "14:10-14:11|4259594751088586730|3|4", "15:10-15:11|4259594751088586730|3|4", "16:11-16:12|4259594751088586730|3|4", "17:10-17:11|4259594751088586730|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 981bb21ac..1f9dd67c7 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -13,82 +13,78 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, "declarations": [], - "spell": "1:8-1:11|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "7:6-7:9|0|1|2", + "extent": "7:1-9:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], "vars": [], - "instances": [], - "uses": ["8:10-8:13|-1|1|4"] + "uses": [], + "callees": ["8:3-8:9|17175780305784503374|3|32"] }, { - "id": 1, + "usr": 17175780305784503374, + "detailed_name": "void accept(int)", + "qual_name_offset": 5, + "short_name": "accept", + "kind": 12, + "storage": 1, + "declarations": ["5:6-5:12|0|1|1"], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": ["8:3-8:9|4259594751088586730|3|32"], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [8599782646965457351], "uses": [] - }], - "funcs": [{ - "id": 0, - "usr": 17175780305784503374, - "detailed_name": "void accept(int)", - "qual_name_offset": 5, - "short_name": "accept", - "kind": 12, - "storage": 1, - "declarations": [{ - "spell": "5:6-5:12|-1|1|1", - "param_spellings": ["5:16-5:16"] - }], - "bases": [], - "derived": [], - "vars": [], - "uses": ["8:3-8:9|1|3|32"], - "callees": [] }, { - "id": 1, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, "declarations": [], - "spell": "7:6-7:9|-1|1|2", - "extent": "7:1-9:2|-1|1|0", + "spell": "1:8-1:11|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], + "types": [], + "funcs": [], "vars": [], - "uses": [], - "callees": ["8:3-8:9|0|3|32"] + "instances": [], + "uses": ["8:10-8:13|0|1|4"] }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 8599782646965457351, "detailed_name": "int Foo::x", "qual_name_offset": 4, "short_name": "x", - "declarations": ["2:14-2:15|0|2|1"], - "type": 1, - "uses": ["8:15-8:16|1|3|4"], + "declarations": ["2:14-2:15|15041163540773201510|2|1"], + "type": 17, + "uses": ["8:15-8:16|4259594751088586730|3|4"], "kind": 8, "storage": 3 }] diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index e6400caa9..21839e12c 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -12,53 +12,52 @@ const VarType Holder::static_var; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 5792006888140599735, "detailed_name": "VarType", "qual_name_offset": 0, "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "1:6-1:13|-1|1|2", - "extent": "1:1-1:16|-1|1|0", + "spell": "1:6-1:13|0|1|2", + "extent": "1:1-1:16|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["4:20-4:27|-1|1|4", "4:42-4:49|-1|1|4", "7:7-7:14|-1|1|4"] + "instances": [7057400933868440116], + "uses": ["4:20-4:27|0|1|4", "4:42-4:49|0|1|4", "7:7-7:14|0|1|4"] }, { - "id": 1, "usr": 10028537921178202800, "detailed_name": "Holder", "qual_name_offset": 0, "short_name": "Holder", "kind": 23, "declarations": [], - "spell": "3:8-3:14|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:8-3:14|0|1|2", + "extent": "3:1-5:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], + "vars": [7057400933868440116], "instances": [], - "uses": ["7:15-7:21|-1|1|4"] + "uses": ["7:15-7:21|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 7057400933868440116, "detailed_name": "const VarType Holder::static_var", "qual_name_offset": 14, "short_name": "static_var", "hover": "const VarType Holder::static_var = (VarType)0x0", - "declarations": ["4:28-4:38|1|2|1"], - "spell": "7:23-7:33|1|2|2", - "extent": "7:1-7:33|-1|1|0", - "type": 0, + "declarations": ["4:28-4:38|10028537921178202800|2|1"], + "spell": "7:23-7:33|10028537921178202800|2|2", + "extent": "7:1-7:33|0|1|0", + "type": 5792006888140599735, "uses": [], "kind": 8, "storage": 1 diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 441c73ac5..81100735e 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -8,24 +8,7 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": [] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, @@ -33,23 +16,39 @@ void foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [16721564935990383768], + "uses": [] + }], + "usr2var": [{ "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": ["1:12-1:13|-1|1|1"], - "type": 0, - "uses": ["4:3-4:4|0|3|4"], + "declarations": ["1:12-1:13|0|1|1"], + "type": 17, + "uses": ["4:3-4:4|4259594751088586730|3|4"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index f25318707..72d2a1d74 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -6,50 +6,49 @@ void foo(int a) { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 11998306017310352355, + "detailed_name": "void foo(int a)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-3:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [10063793875496522529], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [10063793875496522529], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 11998306017310352355, - "detailed_name": "void foo(int a)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 10063793875496522529, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|0|3|2", - "extent": "1:10-1:15|0|3|0", - "type": 0, - "uses": ["2:3-2:4|0|3|4"], + "spell": "1:14-1:15|11998306017310352355|3|2", + "extent": "1:10-1:15|11998306017310352355|3|0", + "type": 17, + "uses": ["2:3-2:4|11998306017310352355|3|4"], "kind": 253, "storage": 1 }] diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 64b460c65..2a1e89fdc 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -7,50 +7,49 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-4:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [14014650769929566957], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [14014650769929566957], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-4:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 8534460107894911680, + "usr2var": [{ + "usr": 14014650769929566957, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "2:7-2:8|0|3|2", - "extent": "2:3-2:8|0|3|0", - "type": 0, - "uses": ["3:3-3:4|0|3|4"], + "spell": "2:7-2:8|4259594751088586730|3|2", + "extent": "2:3-2:8|4259594751088586730|3|0", + "type": 17, + "uses": ["3:3-3:4|4259594751088586730|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 4e6bbe489..307e22064 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -12,63 +12,61 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-9:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [13311055950748663970, 14036425367303419504], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [13311055950748663970, 14036425367303419504], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-9:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 17941402366659878910, + "usr2var": [{ + "usr": 13311055950748663970, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|0|3|2", - "extent": "2:3-2:8|0|3|0", - "type": 0, - "uses": ["3:3-3:4|0|3|4", "8:3-8:4|0|3|4"], + "spell": "2:7-2:8|4259594751088586730|3|2", + "extent": "2:3-2:8|4259594751088586730|3|0", + "type": 17, + "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 11094102496276744608, + "usr": 14036425367303419504, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:9-5:10|0|3|2", - "extent": "5:5-5:10|0|3|0", - "type": 0, - "uses": ["6:5-6:6|0|3|4"], + "spell": "5:9-5:10|4259594751088586730|3|2", + "extent": "5:5-5:10|4259594751088586730|3|0", + "type": 17, + "uses": ["6:5-6:6|4259594751088586730|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 2d3194ef5..dfe22c82b 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -12,64 +12,62 @@ void foo(int a) { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 11998306017310352355, + "detailed_name": "void foo(int a)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-8:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [11608231465452906059, 6997229590862003559], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [11608231465452906059, 6997229590862003559], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 11998306017310352355, - "detailed_name": "void foo(int a)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-8:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 11608231465452906059, + "usr2var": [{ + "usr": 6997229590862003559, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|0|3|2", - "extent": "1:10-1:15|0|3|0", - "type": 0, - "uses": ["2:3-2:4|0|3|4", "7:3-7:4|0|3|4"], - "kind": 253, + "spell": "4:9-4:10|11998306017310352355|3|2", + "extent": "4:5-4:10|11998306017310352355|3|0", + "type": 17, + "uses": ["5:5-5:6|11998306017310352355|3|4"], + "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 8011559936501990179, + "usr": 11608231465452906059, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "4:9-4:10|0|3|2", - "extent": "4:5-4:10|0|3|0", - "type": 0, - "uses": ["5:5-5:6|0|3|4"], - "kind": 13, + "spell": "1:14-1:15|11998306017310352355|3|2", + "extent": "1:10-1:15|11998306017310352355|3|0", + "type": 17, + "uses": ["2:3-2:4|11998306017310352355|3|4", "7:3-7:4|11998306017310352355|3|4"], + "kind": 253, "storage": 1 }] } diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index b6fb8bc99..1b74d463e 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -9,24 +9,7 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": [] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, @@ -34,25 +17,41 @@ void foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, + "usr2type": [{ + "usr": 17, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [11823161916242867318], + "uses": [] + }], + "usr2var": [{ "usr": 11823161916242867318, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:12-1:13|-1|1|2", - "extent": "1:1-1:13|-1|1|0", - "type": 0, - "uses": ["4:3-4:4|0|3|4"], + "spell": "1:12-1:13|0|1|2", + "extent": "1:1-1:13|0|1|0", + "type": 17, + "uses": ["4:3-4:4|4259594751088586730|3|4"], "kind": 13, "storage": 3 }] diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 43e10c017..548da9808 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -6,35 +6,34 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], - "instances": [0], - "uses": ["2:3-2:6|-1|1|4"] + "vars": [13799811842374292251], + "instances": [13799811842374292251], + "uses": ["2:3-2:6|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 13799811842374292251, "detailed_name": "Foo *Foo::member", "qual_name_offset": 5, "short_name": "member", "declarations": [], - "spell": "2:8-2:14|0|2|2", - "extent": "2:3-2:14|0|2|0", - "type": 0, + "spell": "2:8-2:14|15041163540773201510|2|2", + "extent": "2:3-2:14|15041163540773201510|2|0", + "type": 15041163540773201510, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 8af93e6c3..ba6fbbe79 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -8,36 +8,35 @@ Foo* Foo::member = nullptr; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "Foo", "qual_name_offset": 0, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [0], - "instances": [0], - "uses": ["2:10-2:13|-1|1|4", "4:1-4:4|-1|1|4", "4:6-4:9|-1|1|4"] + "vars": [5844987037615239736], + "instances": [5844987037615239736], + "uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 5844987037615239736, "detailed_name": "Foo *Foo::member", "qual_name_offset": 5, "short_name": "member", "hover": "Foo *Foo::member = nullptr", - "declarations": ["2:15-2:21|0|2|1"], - "spell": "4:11-4:17|0|2|2", - "extent": "4:1-4:27|-1|1|0", - "type": 0, + "declarations": ["2:15-2:21|15041163540773201510|2|1"], + "spell": "4:11-4:17|15041163540773201510|2|2", + "extent": "4:1-4:27|0|1|0", + "type": 15041163540773201510, "uses": [], "kind": 8, "storage": 1 diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index 069ded36b..98781bc5f 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -6,48 +6,47 @@ class Foo { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", + "usr2func": [], + "usr2type": [{ + "usr": 17, + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-3:2|-1|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [5844987037615239736], "uses": [] }, { - "id": 1, - "usr": 17, - "detailed_name": "", + "usr": 15041163540773201510, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "short_name": "Foo", + "kind": 5, "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-3:2|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 5844987037615239736, "detailed_name": "int Foo::member", "qual_name_offset": 4, "short_name": "member", - "declarations": ["2:14-2:20|0|2|1"], - "type": 1, + "declarations": ["2:14-2:20|15041163540773201510|2|1"], + "type": 17, "uses": [], "kind": 8, "storage": 3 diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index cfe0d4fd1..654e5bf4b 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -9,26 +9,7 @@ void f() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|-1|1|2", - "extent": "1:1-1:13|-1|1|0", - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": ["3:16-3:19|-1|1|4", "4:17-4:20|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 880549676430489861, "detailed_name": "void f()", "qual_name_offset": 5, @@ -36,37 +17,54 @@ void f() { "kind": 12, "storage": 1, "declarations": [], - "spell": "2:6-2:7|-1|1|2", - "extent": "2:1-5:2|-1|1|0", + "spell": "2:6-2:7|0|1|2", + "extent": "2:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0, 1], + "vars": [10601729374837386290, 18422884837902130475], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 9275666070987716270, + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "spell": "1:7-1:10|0|1|2", + "extent": "1:1-1:13|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [10601729374837386290, 18422884837902130475], + "uses": ["3:16-3:19|0|1|4", "4:17-4:20|0|1|4"] + }], + "usr2var": [{ + "usr": 10601729374837386290, "detailed_name": "Foo *x", "qual_name_offset": 5, "short_name": "x", "declarations": [], - "spell": "3:8-3:9|0|3|2", - "extent": "3:3-3:21|0|3|0", - "type": 0, + "spell": "3:8-3:9|880549676430489861|3|2", + "extent": "3:3-3:21|880549676430489861|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 16202433437488621027, + "usr": 18422884837902130475, "detailed_name": "Foo *y", "qual_name_offset": 5, "short_name": "y", "declarations": [], - "spell": "4:9-4:10|0|3|2", - "extent": "4:3-4:22|0|3|0", - "type": 0, + "spell": "4:9-4:10|880549676430489861|3|2", + "extent": "4:3-4:22|880549676430489861|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index eef83fc49..8ea4fbe00 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -9,24 +9,7 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|-1|1|1"], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0], - "uses": ["4:3-4:6|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, @@ -34,24 +17,40 @@ void foo() { "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-5:2|-1|1|0", + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0], + "vars": [13198746475679542317], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 10782632605670042066, + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [13198746475679542317], + "uses": ["4:3-4:6|0|1|4"] + }], + "usr2var": [{ + "usr": 13198746475679542317, "detailed_name": "Foo *a", "qual_name_offset": 5, "short_name": "a", "declarations": [], - "spell": "4:8-4:9|0|3|2", - "extent": "4:3-4:9|0|3|0", - "type": 0, + "spell": "4:8-4:9|4259594751088586730|3|2", + "extent": "4:3-4:9|4259594751088586730|3|0", + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index df37bff6b..275078e19 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -7,24 +7,7 @@ void foo(Foo* p0, Foo* p1) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, - "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|-1|1|1"], - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [0, 1], - "uses": ["3:10-3:13|-1|1|4", "3:19-3:22|-1|1|4"] - }], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 8908726657907936744, "detailed_name": "void foo(Foo *p0, Foo *p1)", "qual_name_offset": 5, @@ -32,37 +15,52 @@ void foo(Foo* p0, Foo* p1) {} "kind": 12, "storage": 1, "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-3:30|-1|1|0", + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-3:30|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [0, 1], + "vars": [8730439006497971620, 2525014371090380500], "uses": [], "callees": [] }], - "vars": [{ - "id": 0, - "usr": 4580260577538694711, - "detailed_name": "Foo *p0", + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 23, + "declarations": ["1:8-1:11|0|1|1"], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [8730439006497971620, 2525014371090380500], + "uses": ["3:10-3:13|0|1|4", "3:19-3:22|0|1|4"] + }], + "usr2var": [{ + "usr": 2525014371090380500, + "detailed_name": "Foo *p1", "qual_name_offset": 5, - "short_name": "p0", + "short_name": "p1", "declarations": [], - "spell": "3:15-3:17|0|3|2", - "extent": "3:10-3:17|0|3|0", - "type": 0, + "spell": "3:24-3:26|8908726657907936744|3|2", + "extent": "3:19-3:26|8908726657907936744|3|0", + "type": 15041163540773201510, "uses": [], "kind": 253, "storage": 1 }, { - "id": 1, - "usr": 12071725611268840435, - "detailed_name": "Foo *p1", + "usr": 8730439006497971620, + "detailed_name": "Foo *p0", "qual_name_offset": 5, - "short_name": "p1", + "short_name": "p0", "declarations": [], - "spell": "3:24-3:26|0|3|2", - "extent": "3:19-3:26|0|3|0", - "type": 0, + "spell": "3:15-3:17|8908726657907936744|3|2", + "extent": "3:10-3:17|8908726657907936744|3|0", + "type": 15041163540773201510, "uses": [], "kind": 253, "storage": 1 diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index 8d4f88131..5615e382d 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -4,9 +4,7 @@ void foo(int, int) {} { "includes": [], "skipped_by_preprocessor": [], - "types": [], - "funcs": [{ - "id": 0, + "usr2func": [{ "usr": 2747674671862363334, "detailed_name": "void foo(int, int)", "qual_name_offset": 5, @@ -14,14 +12,16 @@ void foo(int, int) {} "kind": 12, "storage": 1, "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-1:22|-1|1|0", + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-1:22|0|1|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] }], - "vars": [] + "usr2type": [], + "usr2var": [] } */ diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index a27f81697..2905c2255 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -12,63 +12,61 @@ void foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 4259594751088586730, + "detailed_name": "void foo()", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-9:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [1894874819807168345, 4508045017817092115], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [1894874819807168345, 4508045017817092115], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 4259594751088586730, - "detailed_name": "void foo()", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-9:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, - "usr": 3440226937504376525, + "usr2var": [{ + "usr": 1894874819807168345, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|0|3|2", - "extent": "2:3-2:8|0|3|0", - "type": 0, - "uses": ["3:3-3:4|0|3|4", "8:3-8:4|0|3|4"], + "spell": "2:7-2:8|4259594751088586730|3|2", + "extent": "2:3-2:8|4259594751088586730|3|0", + "type": 17, + "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], "kind": 13, "storage": 1 }, { - "id": 1, - "usr": 14700715011944976607, + "usr": 4508045017817092115, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:9-5:10|0|3|2", - "extent": "5:5-5:10|0|3|0", - "type": 0, - "uses": ["6:5-6:6|0|3|4"], + "spell": "5:9-5:10|4259594751088586730|3|2", + "extent": "5:5-5:10|4259594751088586730|3|0", + "type": 17, + "uses": ["6:5-6:6|4259594751088586730|3|4"], "kind": 13, "storage": 1 }] diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index b4fdf18a0..62d96aaaf 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -6,63 +6,61 @@ void foo(int p) { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 11998306017310352355, + "detailed_name": "void foo(int p)", + "qual_name_offset": 5, + "short_name": "foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "1:6-1:9|0|1|2", + "extent": "1:1-3:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [5875271969926422921, 11404600766177939811], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0, 1], + "instances": [5875271969926422921, 11404600766177939811], "uses": [] }], - "funcs": [{ - "id": 0, - "usr": 11998306017310352355, - "detailed_name": "void foo(int p)", - "qual_name_offset": 5, - "short_name": "foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "1:6-1:9|-1|1|2", - "extent": "1:1-3:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0, 1], - "uses": [], - "callees": [] - }], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 5875271969926422921, "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", "declarations": [], - "spell": "1:14-1:15|0|3|2", - "extent": "1:10-1:15|0|3|0", - "type": 0, + "spell": "1:14-1:15|11998306017310352355|3|2", + "extent": "1:10-1:15|11998306017310352355|3|0", + "type": 17, "uses": [], "kind": 253, "storage": 1 }, { - "id": 1, - "usr": 2147918703972955240, + "usr": 11404600766177939811, "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", "hover": "int p = 0", "declarations": [], - "spell": "2:9-2:10|0|3|2", - "extent": "2:5-2:14|0|3|0", - "type": 0, + "spell": "2:9-2:10|11998306017310352355|3|2", + "extent": "2:5-2:14|11998306017310352355|3|0", + "type": 17, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index d40c35b80..48fe10ab0 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -4,34 +4,33 @@ static int global = 0; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [6834525061342585382], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 6834525061342585382, "detailed_name": "int global", "qual_name_offset": 4, "short_name": "global", "hover": "int global = 0", "declarations": [], - "spell": "1:12-1:18|-1|1|2", - "extent": "1:1-1:22|-1|1|0", - "type": 0, + "spell": "1:12-1:18|0|1|2", + "extent": "1:1-1:22|0|1|0", + "type": 17, "uses": [], "kind": 13, "storage": 3 diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index 2aaaedcd5..947e42c84 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -4,31 +4,30 @@ extern int global; { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [], + "usr2type": [{ "usr": 17, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, "declarations": [], + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], + "instances": [9937941849651546906], "uses": [] }], - "funcs": [], - "vars": [{ - "id": 0, + "usr2var": [{ "usr": 9937941849651546906, "detailed_name": "int global", "qual_name_offset": 4, "short_name": "global", - "declarations": ["1:12-1:18|-1|1|1"], - "type": 0, + "declarations": ["1:12-1:18|0|1|1"], + "type": 17, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 654030b40..88cd787ea 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -11,25 +11,41 @@ void Foo() { { "includes": [], "skipped_by_preprocessor": [], - "types": [{ - "id": 0, + "usr2func": [{ + "usr": 4654328188330986029, + "detailed_name": "void Foo()", + "qual_name_offset": 5, + "short_name": "Foo", + "kind": 12, + "storage": 1, + "declarations": [], + "spell": "3:6-3:9|0|1|2", + "extent": "3:1-5:2|0|1|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [6975456769752895964], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 4750332761459066907, "detailed_name": "S", "qual_name_offset": 0, "short_name": "S", "kind": 23, "declarations": [], - "spell": "1:8-1:9|-1|1|2", - "extent": "1:1-1:12|-1|1|0", + "spell": "1:8-1:9|0|1|2", + "extent": "1:1-1:12|0|1|0", + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["2:11-2:12|-1|1|4"] + "uses": ["2:11-2:12|0|1|4"] }, { - "id": 1, "usr": 7434820806199665424, "detailed_name": "F", "qual_name_offset": 0, @@ -37,44 +53,26 @@ void Foo() { "kind": 252, "hover": "using F = S", "declarations": [], - "spell": "2:7-2:8|-1|1|2", - "extent": "2:1-2:12|-1|1|0", - "alias_of": 0, + "spell": "2:7-2:8|0|1|2", + "extent": "2:1-2:12|0|1|0", + "alias_of": 4750332761459066907, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [0], - "uses": ["2:7-2:8|-1|1|4", "4:3-4:4|-1|1|4"] - }], - "funcs": [{ - "id": 0, - "usr": 4654328188330986029, - "detailed_name": "void Foo()", - "qual_name_offset": 5, - "short_name": "Foo", - "kind": 12, - "storage": 1, - "declarations": [], - "spell": "3:6-3:9|-1|1|2", - "extent": "3:1-5:2|-1|1|0", - "bases": [], - "derived": [], - "vars": [0], - "uses": [], - "callees": [] + "instances": [6975456769752895964], + "uses": ["2:7-2:8|0|1|4", "4:3-4:4|0|1|4"] }], - "vars": [{ - "id": 0, - "usr": 7730100248624586522, + "usr2var": [{ + "usr": 6975456769752895964, "detailed_name": "F a", "qual_name_offset": 2, "short_name": "a", "declarations": [], - "spell": "4:5-4:6|0|3|2", - "extent": "4:3-4:6|0|3|0", - "type": 1, + "spell": "4:5-4:6|4654328188330986029|3|2", + "extent": "4:3-4:6|4654328188330986029|3|0", + "type": 7434820806199665424, "uses": [], "kind": 13, "storage": 1 diff --git a/src/cache_manager.cc b/src/cache_manager.cc index d33f66fe6..2c67b63a1 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -137,9 +137,3 @@ std::unique_ptr ICacheManager::TryTakeOrLoad( return RawCacheLoad(path); } - -std::unique_ptr ICacheManager::TakeOrLoad(const std::string& path) { - auto result = TryTakeOrLoad(path); - assert(result); - return result; -} diff --git a/src/cache_manager.h b/src/cache_manager.h index 920e37195..a410d608a 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -31,10 +31,6 @@ struct ICacheManager { // the cache does not exist. std::unique_ptr TryTakeOrLoad(const std::string& path); - // Takes the existing cache or loads the cache at |path|. Asserts the cache - // exists. - std::unique_ptr TakeOrLoad(const std::string& path); - virtual void WriteToCache(IndexFile& file) = 0; virtual std::optional LoadCachedFileContents( diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 2c2ce6334..327d7fc2c 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -477,37 +477,18 @@ std::string GetDocumentContentInRange(CXTranslationUnit cx_tu, return result; } -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; - } -} - // |parent| should be resolved before using |SetUsePreflight| so that |def| will // not be invalidated by |To{Func,Type,Var}Id|. Use SetUse(IndexFile* db, Range range, ClangCursor parent, Role role) { switch (GetSymbolKind(parent.get_kind())) { case SymbolKind::Func: - return Use(range, db->ToFuncId(parent.cx_cursor), SymbolKind::Func, role, - {}); + return Use{{range, db->ToFunc(parent).usr, SymbolKind::Func, role}}; case SymbolKind::Type: - return Use(range, db->ToTypeId(parent.cx_cursor), SymbolKind::Type, role, - {}); + return Use{{range, db->ToType(parent).usr, SymbolKind::Type, role}}; case SymbolKind::Var: - return Use(range, db->ToVarId(parent.cx_cursor), SymbolKind::Var, role, - {}); + return Use{{range, db->ToVar(parent).usr, SymbolKind::Var, role}}; default: - return Use(range, Id(), SymbolKind::File, role, {}); + return Use{{range, 0, SymbolKind::File, role}}; } } @@ -528,7 +509,7 @@ const char* GetAnonName(CXCursorKind kind) { } } -void SetTypeName(IndexType* type, +void SetTypeName(IndexType& type, const ClangCursor& cursor, const CXIdxContainerInfo* container, const char* name, @@ -544,20 +525,20 @@ void SetTypeName(IndexType* type, // ns {}` which are not qualified. // type->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor); int short_name_offset, short_name_size; - std::tie(type->def.detailed_name, short_name_offset, short_name_size) = + std::tie(type.def.detailed_name, short_name_offset, short_name_size) = param->ns.QualifiedName(container ? container : &parent, name); - type->def.qual_name_offset = 0; - type->def.short_name_offset = short_name_offset; - type->def.short_name_size = short_name_size; + type.def.qual_name_offset = 0; + type.def.short_name_offset = short_name_offset; + type.def.short_name_size = short_name_size; } // Finds the cursor associated with the declaration type of |cursor|. This // strips // qualifies from |cursor| (ie, Foo* => Foo) and removes template arguments // (ie, Foo => Foo<*,*>). -std::optional ResolveToDeclarationType(IndexFile* db, - ClangCursor cursor, - IndexParam* param) { +IndexType* ResolveToDeclarationType(IndexFile* db, + ClangCursor cursor, + IndexParam* param) { ClangType type = cursor.get_type(); // auto x = new Foo() will not be deduced to |Foo| if we do not use the @@ -570,7 +551,7 @@ std::optional ResolveToDeclarationType(IndexFile* db, if (type.is_builtin()) { // For builtin types, use type kinds as USR hash. - return db->ToTypeId(type.cx_type.kind); + return &db->ToType(static_cast(type.cx_type.kind)); } ClangCursor declaration = @@ -579,27 +560,26 @@ std::optional ResolveToDeclarationType(IndexFile* db, const char* str_usr = clang_getCString(cx_usr); if (!str_usr || str_usr[0] == '\0') { clang_disposeString(cx_usr); - return std::nullopt; + return nullptr; } Usr usr = HashUsr(str_usr); clang_disposeString(cx_usr); - IndexTypeId type_id = db->ToTypeId(usr); - IndexType* typ = db->Resolve(type_id); - if (typ->def.detailed_name.empty()) { + IndexType& typ = db->ToType(usr); + if (typ.def.detailed_name.empty()) { std::string name = declaration.get_spell_name(); SetTypeName(typ, declaration, nullptr, name.c_str(), param); } - return type_id; + return &typ; } -void SetVarDetail(IndexVar* var, +void SetVarDetail(IndexVar& var, std::string_view short_name, const ClangCursor& cursor, const CXIdxContainerInfo* semanticContainer, bool is_first_seen, IndexFile* db, IndexParam* param) { - IndexVar::Def& def = var->def; + IndexVar::Def& def = var.def; const CXType cx_type = clang_getCursorType(cursor.cx_cursor); std::string type_name = ToString(clang_getTypeSpelling(cx_type)); // clang may report "(lambda at foo.cc)" which end up being a very long @@ -666,15 +646,15 @@ void SetVarDetail(IndexVar* var, } if (is_first_seen) { - if (std::optional var_type = + if (IndexType* var_type = ResolveToDeclarationType(db, cursor, param)) { // Don't treat enum definition variables as instantiations. bool is_enum_member = semanticContainer && semanticContainer->cursor.kind == CXCursor_EnumDecl; if (!is_enum_member) - db->Resolve(var_type.value())->instances.push_back(var->id); + var_type->instances.push_back(var.usr); - def.type = *var_type; + def.type = var_type->usr; } } } @@ -682,27 +662,23 @@ void SetVarDetail(IndexVar* var, void OnIndexReference_Function(IndexFile* db, Range loc, ClangCursor parent_cursor, - IndexFuncId called_id, + IndexFunc& called, Role role) { switch (GetSymbolKind(parent_cursor.get_kind())) { case SymbolKind::Func: { - IndexFunc* parent = db->Resolve(db->ToFuncId(parent_cursor.cx_cursor)); - IndexFunc* called = db->Resolve(called_id); - parent->def.callees.push_back( - SymbolRef(loc, called->id, SymbolKind::Func, role)); - called->uses.push_back(Use(loc, parent->id, SymbolKind::Func, role, {})); + IndexFunc& parent = db->ToFunc(parent_cursor.cx_cursor); + parent.def.callees.push_back( + SymbolRef{loc, called.usr, SymbolKind::Func, role}); + called.uses.push_back(Use{{loc, parent.usr, 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); - called->uses.push_back(Use(loc, parent->id, SymbolKind::Type, role, {})); + IndexType& parent = db->ToType(parent_cursor.cx_cursor); + called.uses.push_back(Use{{loc, parent.usr, SymbolKind::Type, role}}); break; } default: { - IndexFunc* called = db->Resolve(called_id); - called->uses.push_back(Use(loc, Id(), SymbolKind::File, role, {})); + called.uses.push_back(Use{{loc, 0, SymbolKind::File, role}}); break; } } @@ -715,80 +691,35 @@ const int IndexFile::kMajorVersion = 15; const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(const std::string& path, const std::string& contents) - : id_cache{path}, path(path), file_contents(contents) {} - -IndexTypeId IndexFile::ToTypeId(Usr usr) { - auto it = id_cache.usr_to_type_id.find(usr); - if (it != id_cache.usr_to_type_id.end()) - return it->second; - - IndexTypeId id(types.size()); - IndexType type; - type.usr = usr; - type.id = id; - types.push_back(type); - id_cache.usr_to_type_id[usr] = id; - id_cache.type_id_to_usr[id] = usr; - return id; -} -IndexFuncId IndexFile::ToFuncId(Usr usr) { - auto it = id_cache.usr_to_func_id.find(usr); - if (it != id_cache.usr_to_func_id.end()) - return it->second; - - IndexFuncId id(funcs.size()); - IndexFunc func; - func.usr = usr; - func.id = id; - funcs.push_back(std::move(func)); - id_cache.usr_to_func_id[usr] = id; - id_cache.func_id_to_usr[id] = usr; - return id; -} -IndexVarId IndexFile::ToVarId(Usr usr) { - auto it = id_cache.usr_to_var_id.find(usr); - if (it != id_cache.usr_to_var_id.end()) - return it->second; - - IndexVarId id(vars.size()); - IndexVar var; - var.usr = usr; - var.id = id; - vars.push_back(std::move(var)); - id_cache.usr_to_var_id[usr] = id; - id_cache.var_id_to_usr[id] = usr; - return id; -} - -IndexTypeId IndexFile::ToTypeId(const CXCursor& cursor) { - return ToTypeId(ClangCursor(cursor).get_usr_hash()); -} + : path(path), file_contents(contents) {} -IndexFuncId IndexFile::ToFuncId(const CXCursor& cursor) { - return ToFuncId(ClangCursor(cursor).get_usr_hash()); +IndexFunc& IndexFile::ToFunc(Usr usr) { + auto ret = usr2func.try_emplace(usr); + if (ret.second) + ret.first->second.usr = usr; + return ret.first->second; } -IndexVarId IndexFile::ToVarId(const CXCursor& cursor) { - return ToVarId(ClangCursor(cursor).get_usr_hash()); +IndexType& IndexFile::ToType(Usr usr) { + auto ret = usr2type.try_emplace(usr); + if (ret.second) + ret.first->second.usr = usr; + return ret.first->second; } -IndexType* IndexFile::Resolve(IndexTypeId id) { - return &types[id.id]; -} -IndexFunc* IndexFile::Resolve(IndexFuncId id) { - return &funcs[id.id]; -} -IndexVar* IndexFile::Resolve(IndexVarId id) { - return &vars[id.id]; +IndexVar& IndexFile::ToVar(Usr usr) { + auto ret = usr2var.try_emplace(usr); + if (ret.second) + ret.first->second.usr = usr; + return ret.first->second; } std::string IndexFile::ToString() { return Serialize(SerializeFormat::Json, *this); } -template -void Uniquify(std::vector>& ids) { - std::unordered_set> seen; +void Uniquify(std::vector& ids) { + std::unordered_set seen; size_t n = 0; for (size_t i = 0; i < ids.size(); i++) if (seen.insert(ids[i]).second) @@ -820,15 +751,15 @@ void AddUse(IndexFile* db, Role role = Role::Reference) { switch (GetSymbolKind(parent.get_kind())) { case SymbolKind::Func: - uses.push_back(Use(range, db->ToFuncId(parent.cx_cursor), - SymbolKind::Func, role, {})); + uses.push_back(Use{ + {range, db->ToFunc(parent.cx_cursor).usr, SymbolKind::Func, role}}); break; case SymbolKind::Type: - uses.push_back(Use(range, db->ToTypeId(parent.cx_cursor), - SymbolKind::Type, role, {})); + uses.push_back(Use{ + {range, db->ToType(parent.cx_cursor).usr, SymbolKind::Type, role}}); break; default: - uses.push_back(Use(range, Id(), SymbolKind::File, role, {})); + uses.push_back(Use{{range, 0, SymbolKind::File, role}}); break; } } @@ -934,12 +865,12 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) { struct VisitDeclForTypeUsageParam { IndexFile* db; - std::optional toplevel_type; + IndexType* toplevel_type; int has_processed_any = false; std::optional previous_cursor; - std::optional initial_type; + IndexType* initial_type = nullptr; - VisitDeclForTypeUsageParam(IndexFile* db, std::optional toplevel_type) + VisitDeclForTypeUsageParam(IndexFile* db, IndexType* toplevel_type) : db(db), toplevel_type(toplevel_type) {} }; @@ -962,11 +893,11 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, // // We will attribute |::C| to the parent class. if (param->toplevel_type) { - IndexType* ref_type = db->Resolve(*param->toplevel_type); + IndexType& ref_type = *param->toplevel_type; std::string name = cursor.get_referenced().get_spell_name(); - if (name == ref_type->def.Name(false)) { - AddUseSpell(db, ref_type->uses, cursor); - param->toplevel_type = std::nullopt; + if (name == ref_type.def.Name(false)) { + AddUseSpell(db, ref_type.uses, cursor); + param->toplevel_type = nullptr; return; } } @@ -979,15 +910,14 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, if (referenced_usr == "") return; - IndexTypeId ref_type_id = db->ToTypeId(HashUsr(referenced_usr)); + IndexType& ref_type = db->ToType(HashUsr(referenced_usr)); if (!param->initial_type) - param->initial_type = ref_type_id; + param->initial_type = &ref_type; - IndexType* ref_type_def = db->Resolve(ref_type_id); // TODO: Should we even be visiting this if the file is not from the main // def? Try adding assert on |loc| later. - AddUseSpell(db, ref_type_def->uses, cursor); + AddUseSpell(db, ref_type.uses, cursor); } ClangCursor::VisitResult VisitDeclForTypeUsageVisitor( @@ -1037,12 +967,11 @@ ClangCursor::VisitResult VisitDeclForTypeUsageVisitor( // template. // We use |toplevel_type| to attribute the use to the specialized template // instead of the primary template. -std::optional AddDeclTypeUsages( - IndexFile* db, - ClangCursor decl_cursor, - std::optional toplevel_type, - const CXIdxContainerInfo* semantic_container, - const CXIdxContainerInfo* lexical_container) { +IndexType* AddDeclTypeUsages(IndexFile* db, + ClangCursor decl_cursor, + IndexType* toplevel_type, + const CXIdxContainerInfo* semantic_container, + const CXIdxContainerInfo* lexical_container) { // // The general AST format for definitions follows this pattern: // @@ -1163,8 +1092,8 @@ std::optional AddDeclTypeUsages( return param.initial_type; CXType cx_under = clang_getTypedefDeclUnderlyingType(decl_cursor.cx_cursor); if (cx_under.kind == CXType_Invalid) - return std::nullopt; - return db->ToTypeId(ClangType(cx_under).strip_qualifiers().get_usr_hash()); + return nullptr; + return &db->ToType(ClangType(cx_under).strip_qualifiers().get_usr_hash()); } // Various versions of LLVM (ie, 4.0) will not visit inline variable references @@ -1208,11 +1137,11 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor, .template_specialization_to_template_definition() .get_usr(); // std::string ref_usr = ref.get_usr_hash(); - if (ref_usr == "") + if (ref_usr.empty()) break; - IndexVar* ref_var = db->Resolve(db->ToVarId(HashUsr(ref_usr))); - AddUseSpell(db, ref_var->uses, cursor); + IndexVar& ref_var = db->ToVar(HashUsr(ref_usr)); + AddUseSpell(db, ref_var.uses, cursor); break; } @@ -1248,26 +1177,25 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, else decl_usr = cursor.get_referenced().get_usr_hash(); - SetUsePreflight(db, parent); - IndexVar* var_def = db->Resolve(db->ToVarId(decl_usr)); + IndexVar& var_def = db->ToVar(decl_usr); if (cursor.get_kind() == CXCursor_MacroDefinition) { CXSourceRange cx_extent = clang_getCursorExtent(cursor.cx_cursor); - var_def->def.detailed_name = cursor.get_display_name(); - var_def->def.qual_name_offset = 0; - var_def->def.short_name_offset = 0; - var_def->def.short_name_size = - int16_t(strlen(var_def->def.detailed_name.c_str())); - var_def->def.hover = + var_def.def.detailed_name = cursor.get_display_name(); + var_def.def.qual_name_offset = 0; + var_def.def.short_name_offset = 0; + var_def.def.short_name_size = + int16_t(strlen(var_def.def.detailed_name.c_str())); + var_def.def.hover = "#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent); - var_def->def.kind = lsSymbolKind::Macro; + var_def.def.kind = lsSymbolKind::Macro; if (g_config->index.comments) - var_def->def.comments = cursor.get_comments(); - var_def->def.spell = + var_def.def.comments = cursor.get_comments(); + var_def.def.spell = SetUse(db, decl_loc_spelling, parent, Role::Definition); - var_def->def.extent = SetUse( + var_def.def.extent = SetUse( db, ResolveCXSourceRange(cx_extent, nullptr), parent, Role::None); } else - AddUse(db, var_def->uses, decl_loc_spelling, parent); + AddUse(db, var_def.uses, decl_loc_spelling, parent); break; } @@ -1298,37 +1226,31 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, case CXCursor_DeclRefExpr: { ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); if (ref_cursor.get_kind() == CXCursor_NonTypeTemplateParameter) { - IndexVarId ref_var_id = db->ToVarId(ref_cursor.get_usr_hash()); - IndexVar* ref_var = db->Resolve(ref_var_id); - if (ref_var->def.detailed_name.empty()) { + IndexVar& ref_var = db->ToVar(ref_cursor); + if (ref_var.def.detailed_name.empty()) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - SetUsePreflight(db, sem_parent); - SetUsePreflight(db, lex_parent); - ref_var = db->Resolve(ref_var_id); - ref_var->def.spell = + ref_var.def.spell = SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition); - ref_var->def.extent = + ref_var.def.extent = SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None); - ref_var = db->Resolve(ref_var_id); - ref_var->def.kind = lsSymbolKind::TypeParameter; + ref_var.def.kind = lsSymbolKind::TypeParameter; SetVarDetail(ref_var, ref_cursor.get_spell_name(), ref_cursor, nullptr, true, db, param); - ClangType ref_type = clang_getCursorType(ref_cursor.cx_cursor); + ClangType ref_type_c = clang_getCursorType(ref_cursor.cx_cursor); // TODO optimize - if (ref_type.get_usr().size()) { - IndexType* ref_type_index = - db->Resolve(db->ToTypeId(ref_type.get_usr_hash())); + if (ref_type_c.get_usr().size()) { + IndexType& ref_type = db->ToType(ref_type_c.get_usr_hash()); // The cursor extent includes `type name`, not just `name`. There // seems no way to extract the spelling range of `type` and we do // not want to do subtraction here. // See https://github.com/cquery-project/cquery/issues/252 - AddUse(db, ref_type_index->uses, ref_cursor.get_extent(), + AddUse(db, ref_type.uses, ref_cursor.get_extent(), ref_cursor.get_lexical_parent()); } } - AddUseSpell(db, ref_var->uses, cursor); + AddUseSpell(db, ref_var.uses, cursor); } break; } @@ -1341,9 +1263,9 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, break; case CXCursor_FunctionDecl: case CXCursor_FunctionTemplate: { - IndexFuncId called_id = db->ToFuncId(overloaded.get_usr_hash()); + IndexFunc& called = db->ToFunc(overloaded.get_usr_hash()); OnIndexReference_Function(db, cursor.get_spell(), data->container, - called_id, Role::Call); + called, Role::Call); break; } } @@ -1353,69 +1275,61 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, case CXCursor_TemplateRef: { ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); if (ref_cursor.get_kind() == CXCursor_TemplateTemplateParameter) { - IndexTypeId ref_type_id = db->ToTypeId(ref_cursor.get_usr_hash()); - IndexType* ref_type = db->Resolve(ref_type_id); + IndexType& ref_type = db->ToType(ref_cursor); // TODO It seems difficult to get references to template template // parameters. // CXCursor_TemplateTemplateParameter can be visited by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting // {Class,Function}Template. Thus we need to initialize it here. - if (ref_type->def.detailed_name.empty()) { + if (ref_type.def.detailed_name.empty()) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - SetUsePreflight(db, sem_parent); - SetUsePreflight(db, lex_parent); - ref_type = db->Resolve(ref_type_id); - ref_type->def.spell = + ref_type.def.spell = SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition); - ref_type->def.extent = + ref_type.def.extent = SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None); #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(); + ref_type.def.detailed_name = ref_cursor.get_spell_name(); #endif - ref_type->def.short_name_offset = 0; - ref_type->def.short_name_size = - int16_t(strlen(ref_type->def.detailed_name.c_str())); - ref_type->def.kind = lsSymbolKind::TypeParameter; + ref_type.def.short_name_offset = 0; + ref_type.def.short_name_size = + int16_t(strlen(ref_type.def.detailed_name.c_str())); + ref_type.def.kind = lsSymbolKind::TypeParameter; } - AddUseSpell(db, ref_type->uses, cursor); + AddUseSpell(db, ref_type.uses, cursor); } break; } case CXCursor_TypeRef: { ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); if (ref_cursor.get_kind() == CXCursor_TemplateTypeParameter) { - IndexTypeId ref_type_id = db->ToTypeId(ref_cursor.get_usr_hash()); - IndexType* ref_type = db->Resolve(ref_type_id); + IndexType& ref_type = db->ToType(ref_cursor); // TODO It seems difficult to get a FunctionTemplate's template // parameters. // CXCursor_TemplateTypeParameter can be visited by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting // {Class,Function}Template. Thus we need to initialize it here. - if (ref_type->def.detailed_name.empty()) { + if (ref_type.def.detailed_name.empty()) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - SetUsePreflight(db, sem_parent); - SetUsePreflight(db, lex_parent); - ref_type = db->Resolve(ref_type_id); - ref_type->def.spell = + ref_type.def.spell = SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition); - ref_type->def.extent = + ref_type.def.extent = SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None); #if 0 && CINDEX_HAVE_PRETTY // template void f(T t){} // weird, the name is empty ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); #else - ref_type->def.detailed_name = ref_cursor.get_spell_name(); + ref_type.def.detailed_name = ref_cursor.get_spell_name(); #endif - ref_type->def.short_name_offset = 0; - ref_type->def.short_name_size = - int16_t(strlen(ref_type->def.detailed_name.c_str())); - ref_type->def.kind = lsSymbolKind::TypeParameter; + ref_type.def.short_name_offset = 0; + ref_type.def.short_name_size = + int16_t(strlen(ref_type.def.detailed_name.c_str())); + ref_type.def.kind = lsSymbolKind::TypeParameter; } - AddUseSpell(db, ref_type->uses, cursor); + AddUseSpell(db, ref_type.uses, cursor); } break; } @@ -1501,8 +1415,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { ClangCursor sem_parent(fromContainer(decl->semanticContainer)); ClangCursor lex_parent(fromContainer(decl->lexicalContainer)); - SetUsePreflight(db, sem_parent); - SetUsePreflight(db, lex_parent); ClangCursor cursor = decl->cursor; switch (decl->entityInfo->kind) { @@ -1512,25 +1424,21 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { case CXIdxEntity_CXXNamespace: { Range spell = cursor.get_spell(); - IndexTypeId ns_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); - IndexType* ns = db->Resolve(ns_id); - ns->def.kind = GetSymbolKind(decl->entityInfo->kind); - if (ns->def.detailed_name.empty()) { + IndexType& ns = db->ToType(HashUsr(decl->entityInfo->USR)); + ns.def.kind = GetSymbolKind(decl->entityInfo->kind); + if (ns.def.detailed_name.empty()) { SetTypeName(ns, cursor, decl->semanticContainer, decl->entityInfo->name, param); - ns->def.spell = SetUse(db, spell, sem_parent, Role::Definition); - ns->def.extent = + ns.def.spell = SetUse(db, spell, sem_parent, Role::Definition); + ns.def.extent = SetUse(db, cursor.get_extent(), lex_parent, Role::None); if (decl->semanticContainer) { - IndexTypeId parent_id = db->ToTypeId( - ClangCursor(decl->semanticContainer->cursor).get_usr_hash()); - db->Resolve(parent_id)->derived.push_back(ns_id); - // |ns| may be invalidated. - ns = db->Resolve(ns_id); - ns->def.bases.push_back(parent_id); + IndexType& parent = db->ToType(decl->semanticContainer->cursor); + parent.derived.push_back(ns.usr); + ns.def.bases.push_back(parent.usr); } } - AddUse(db, ns->uses, spell, lex_parent); + AddUse(db, ns.uses, spell, lex_parent); break; } @@ -1550,8 +1458,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { if (cursor != cursor.template_specialization_to_template_definition()) break; - IndexVarId var_id = db->ToVarId(HashUsr(decl->entityInfo->USR)); - IndexVar* var = db->Resolve(var_id); + IndexVar& var = db->ToVar(HashUsr(decl->entityInfo->USR)); // TODO: Eventually run with this if. Right now I want to iron out bugs // this may shadow. @@ -1560,31 +1467,32 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetVarDetail(var, std::string(decl->entityInfo->name), decl->cursor, decl->semanticContainer, !decl->isRedeclaration, db, param); - var->def.kind = GetSymbolKind(decl->entityInfo->kind); - if (var->def.kind == lsSymbolKind::Variable && + var.def.kind = GetSymbolKind(decl->entityInfo->kind); + if (var.def.kind == lsSymbolKind::Variable && decl->cursor.kind == CXCursor_ParmDecl) - var->def.kind = lsSymbolKind::Parameter; + var.def.kind = lsSymbolKind::Parameter; //} if (decl->isDefinition) { - var->def.spell = SetUse(db, spell, sem_parent, Role::Definition); - var->def.extent = + var.def.spell = SetUse(db, spell, sem_parent, Role::Definition); + var.def.extent = SetUse(db, cursor.get_extent(), lex_parent, Role::None); } else { - var->declarations.push_back( + var.declarations.push_back( SetUse(db, spell, lex_parent, Role::Declaration)); } cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db); - var = db->Resolve(var_id); // Declaring variable type information. Note that we do not insert an // interesting reference for parameter declarations - that is handled when // 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 ? &db->ToType(var.def.type) : nullptr, + decl->semanticContainer, decl->lexicalContainer); // We don't need to assign declaring type multiple times if this variable // has already been seen. @@ -1592,14 +1500,14 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { if (decl->isDefinition && decl->semanticContainer) { switch (GetSymbolKind(decl->semanticContainer->cursor.kind)) { case SymbolKind::Func: { - db->Resolve(db->ToFuncId(decl->semanticContainer->cursor)) - ->def.vars.push_back(var_id); + db->ToFunc(decl->semanticContainer->cursor) + .def.vars.push_back(var.usr); break; } case SymbolKind::Type: if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) { - db->Resolve(db->ToTypeId(decl->semanticContainer->cursor)) - ->def.vars.push_back(var_id); + db->ToType(decl->semanticContainer->cursor) + .def.vars.push_back(var.usr); } break; default: @@ -1625,17 +1533,16 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { cursor.template_specialization_to_template_definition(); bool is_template_specialization = cursor != decl_cursor_resolved; - IndexFuncId func_id = db->ToFuncId(decl_cursor_resolved.cx_cursor); - IndexFunc* func = db->Resolve(func_id); + IndexFunc& func = db->ToFunc(decl_cursor_resolved); if (g_config->index.comments) - func->def.comments = cursor.get_comments(); - func->def.kind = GetSymbolKind(decl->entityInfo->kind); - func->def.storage = + func.def.comments = cursor.get_comments(); + func.def.kind = GetSymbolKind(decl->entityInfo->kind); + func.def.storage = GetStorageClass(clang_Cursor_getStorageClass(decl->cursor)); // We don't actually need to know the return type, but we need to mark it // as an interesting usage. - AddDeclTypeUsages(db, cursor, std::nullopt, decl->semanticContainer, + AddDeclTypeUsages(db, cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); // Add definition or declaration. This is a bit tricky because we treat @@ -1646,35 +1553,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { if (decl->isDefinition && !is_template_specialization) { // assert(!func->def.spell); // assert(!func->def.extent); - func->def.spell = SetUse(db, spell, sem_parent, Role::Definition); - func->def.extent = SetUse(db, extent, lex_parent, Role::None); + func.def.spell = SetUse(db, spell, sem_parent, Role::Definition); + func.def.extent = SetUse(db, extent, lex_parent, Role::None); } else { - IndexFunc::Declaration declaration; - declaration.spell = SetUse(db, spell, lex_parent, Role::Declaration); - - // Add parameters. - for (ClangCursor arg : cursor.get_arguments()) { - switch (arg.get_kind()) { - case CXCursor_ParmDecl: { - Range param_spelling = arg.get_spell(); - - // If the name is empty (which is common for parameters), clang - // will report a range with length 1, which is not correct. - if (param_spelling.start.column == - (param_spelling.end.column - 1) && - arg.get_display_name().empty()) { - param_spelling.end.column -= 1; - } - - declaration.param_spellings.push_back(param_spelling); - break; - } - default: - break; - } - } - - func->declarations.push_back(declaration); + func.declarations.push_back( + SetUse(db, spell, lex_parent, Role::Declaration)); } // Emit definition data for the function. We do this even if it isn't a @@ -1684,13 +1567,13 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // information. if (!is_template_specialization) { #if CINDEX_HAVE_PRETTY - std::tie(func->def.detailed_name, func->def.qual_name_offset, - func->def.short_name_offset, func->def.short_name_size) = + std::tie(func.def.detailed_name, func.def.qual_name_offset, + func.def.short_name_offset, func.def.short_name_size) = param->PrettyPrintCursor(decl->cursor, decl->entityInfo->name); #else - std::tie(func->def.detailed_name, func->def.qual_name_offset, - func->def.short_name_offset, func->def.short_name_size) = - GetFunctionSignature(db, ¶m->ns, decl); + std::tie(func.def.detailed_name, func.def.qual_name_offset, + func.def.short_name_offset, func.def.short_name_size) = + GetFunctionSignature(db, ¶m->ns, decl); #endif // CXCursor_OverloadedDeclRef in templates are not processed by @@ -1702,26 +1585,23 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { data.param = param; data.container = cursor; cursor.VisitChildren(&TemplateVisitor, &data); - // TemplateVisitor calls ToFuncId which invalidates func - func = db->Resolve(func_id); } // Add function usage information. We only want to do it once per // definition/declaration. Do it on definition since there should only // ever be one of those in the entire program. if (IsTypeDefinition(decl->semanticContainer)) { - IndexTypeId declaring_type_id = - db->ToTypeId(decl->semanticContainer->cursor); - IndexType* declaring_type_def = db->Resolve(declaring_type_id); - func->def.declaring_type = declaring_type_id; + IndexType& declaring_type = + db->ToType(decl->semanticContainer->cursor); + func.def.declaring_type = declaring_type.usr; // Mark a type reference at the ctor/dtor location. if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor) - AddUse(db, declaring_type_def->uses, spell, + AddUse(db, declaring_type.uses, spell, fromContainer(decl->lexicalContainer)); // Add function to declaring type. - declaring_type_def->def.funcs.push_back(func_id); + declaring_type.def.funcs.push_back(func.usr); } // Process inheritance. @@ -1735,12 +1615,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { ClangCursor parent = ClangCursor(overridden[i]) .template_specialization_to_template_definition(); - IndexFuncId parent_id = db->ToFuncId(parent.get_usr_hash()); - IndexFunc* parent_def = db->Resolve(parent_id); - func = db->Resolve(func_id); // ToFuncId invalidated func_def - - func->def.bases.push_back(parent_id); - parent_def->derived.push_back(func_id); + IndexFunc& parent_def = db->ToFunc(parent); + func.def.bases.push_back(parent_def.usr); + parent_def.derived.push_back(func.usr); } clang_disposeOverriddenCursors(overridden); @@ -1754,26 +1631,24 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // Note we want to fetch the first TypeRef. Running // ResolveCursorType(decl->cursor) would return // the type of the typedef/using, not the type of the referenced type. - std::optional alias_of = AddDeclTypeUsages( - db, cursor, std::nullopt, decl->semanticContainer, decl->lexicalContainer); + IndexType* alias_of = AddDeclTypeUsages( + db, cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); - IndexTypeId type_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); - IndexType* type = db->Resolve(type_id); + IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); if (alias_of) - type->def.alias_of = alias_of.value(); + type.def.alias_of = alias_of->usr; - ClangCursor decl_cursor = decl->cursor; - Range spell = decl_cursor.get_spell(); - Range extent = decl_cursor.get_extent(); - type->def.spell = SetUse(db, spell, sem_parent, Role::Definition); - type->def.extent = SetUse(db, extent, lex_parent, Role::None); + Range spell = cursor.get_spell(); + Range extent = cursor.get_extent(); + type.def.spell = SetUse(db, spell, sem_parent, Role::Definition); + type.def.extent = SetUse(db, extent, lex_parent, Role::None); - SetTypeName(type, decl_cursor, decl->semanticContainer, + SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, param); - type->def.kind = GetSymbolKind(decl->entityInfo->kind); + type.def.kind = GetSymbolKind(decl->entityInfo->kind); if (g_config->index.comments) - type->def.comments = decl_cursor.get_comments(); + type.def.comments = cursor.get_comments(); // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. @@ -1785,14 +1660,14 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { spell_end = fc.ToOffset(spell.end), extent_end = fc.ToOffset(extent.end); if (extent_start && spell_start && spell_end && extent_end) { - type->def.hover = + type.def.hover = fc.content.substr(*extent_start, *spell_start - *extent_start) + - type->def.detailed_name.c_str() + + type.def.detailed_name.c_str() + fc.content.substr(*spell_end, *extent_end - *spell_end); } } - AddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer)); + AddUse(db, type.uses, spell, fromContainer(decl->lexicalContainer)); break; } @@ -1806,8 +1681,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { case CXIdxEntity_CXXClass: { Range spell = cursor.get_spell(); - IndexTypeId type_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); - IndexType* type = db->Resolve(type_id); + IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); // TODO: Eventually run with this if. Right now I want to iron out bugs // this may shadow. @@ -1816,29 +1690,26 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, param); - type->def.kind = GetSymbolKind(decl->entityInfo->kind); + type.def.kind = GetSymbolKind(decl->entityInfo->kind); if (g_config->index.comments) - type->def.comments = cursor.get_comments(); + type.def.comments = cursor.get_comments(); // } if (decl->isDefinition) { - type->def.spell = SetUse(db, spell, sem_parent, Role::Definition); - type->def.extent = + type.def.spell = SetUse(db, spell, sem_parent, Role::Definition); + type.def.extent = SetUse(db, cursor.get_extent(), lex_parent, Role::None); if (cursor.get_kind() == CXCursor_EnumDecl) { ClangType enum_type = clang_getEnumDeclIntegerType(decl->cursor); if (!enum_type.is_builtin()) { - IndexType* int_type = - db->Resolve(db->ToTypeId(enum_type.get_usr_hash())); - AddUse(db, int_type->uses, spell, + IndexType& int_type = db->ToType(enum_type.get_usr_hash()); + AddUse(db, int_type.uses, spell, fromContainer(decl->lexicalContainer)); - // type is invalidated. - type = db->Resolve(type_id); } } } else - AddUse(db, type->declarations, spell, + AddUse(db, type.declarations, spell, fromContainer(decl->lexicalContainer), Role::Declaration); switch (decl->entityInfo->templateKind) { @@ -1849,38 +1720,31 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // TODO Use a different dimension ClangCursor origin_cursor = cursor.template_specialization_to_template_definition(); - IndexTypeId origin_id = db->ToTypeId(origin_cursor.get_usr_hash()); - IndexType* origin = db->Resolve(origin_id); - // |type| may be invalidated. - type = db->Resolve(type_id); + IndexType& origin = db->ToType(origin_cursor); // template class function; // not visited by // OnIndexDeclaration template<> class function {}; // current // cursor - if (origin->def.detailed_name.empty()) { + if (origin.def.detailed_name.empty()) { SetTypeName(origin, origin_cursor, nullptr, - &type->def.Name(false)[0], param); - origin->def.kind = type->def.kind; + &type.def.Name(false)[0], param); + origin.def.kind = type.def.kind; } // TODO The name may be assigned in |ResolveToDeclarationType| but // |spell| is std::nullopt. CXFile origin_file; Range origin_spell = origin_cursor.get_spell(&origin_file); - if (!origin->def.spell && file == origin_file) { + if (!origin.def.spell && file == origin_file) { ClangCursor origin_sem = origin_cursor.get_semantic_parent(); ClangCursor origin_lex = origin_cursor.get_lexical_parent(); - SetUsePreflight(db, origin_sem); - SetUsePreflight(db, origin_lex); - origin = db->Resolve(origin_id); - type = db->Resolve(type_id); - origin->def.spell = + origin.def.spell = SetUse(db, origin_spell, origin_sem, Role::Definition); - origin->def.extent = + origin.def.extent = SetUse(db, origin_cursor.get_extent(), origin_lex, Role::None); } - origin->derived.push_back(type_id); - type->def.bases.push_back(origin_id); + origin.derived.push_back(type.usr); + type.def.bases.push_back(origin.usr); + [[fallthrough]]; } - // fallthrough case CXIdxEntity_Template: { TemplateVisitorData data; data.db = db; @@ -1904,17 +1768,13 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { for (unsigned int i = 0; i < class_info->numBases; ++i) { const CXIdxBaseClassInfo* base_class = class_info->bases[i]; - AddDeclTypeUsages(db, base_class->cursor, std::nullopt, + AddDeclTypeUsages(db, base_class->cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); - std::optional parent_type_id = + IndexType* parent_type = ResolveToDeclarationType(db, base_class->cursor, param); - // type_def ptr could be invalidated by ResolveToDeclarationType and - // TemplateVisitor. - type = db->Resolve(type_id); - if (parent_type_id) { - IndexType* parent_type_def = db->Resolve(parent_type_id.value()); - parent_type_def->derived.push_back(type_id); - type->def.bases.push_back(*parent_type_id); + if (parent_type) { + parent_type->derived.push_back(type.usr); + type.def.bases.push_back(parent_type->usr); } } } @@ -1969,7 +1829,6 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { ClangCursor referenced; if (ref->referencedEntity) referenced = ref->referencedEntity->cursor; - SetUsePreflight(db, lex_parent); switch (ref->referencedEntity->kind) { case CXIdxEntity_Unexposed: @@ -1977,22 +1836,20 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { break; case CXIdxEntity_CXXNamespace: { - IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); - AddUse(db, ns->uses, cursor.get_spell(), fromContainer(ref->container)); + IndexType& ns = db->ToType(referenced.get_usr_hash()); + AddUse(db, ns.uses, cursor.get_spell(), fromContainer(ref->container)); break; } case CXIdxEntity_CXXNamespaceAlias: { - IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); - AddUse(db, ns->uses, cursor.get_spell(), fromContainer(ref->container)); - if (!ns->def.spell) { + IndexType& ns = db->ToType(referenced.get_usr_hash()); + AddUse(db, ns.uses, cursor.get_spell(), fromContainer(ref->container)); + if (!ns.def.spell) { ClangCursor sem_parent = referenced.get_semantic_parent(); ClangCursor lex_parent = referenced.get_lexical_parent(); - SetUsePreflight(db, sem_parent); - SetUsePreflight(db, lex_parent); - ns->def.spell = + ns.def.spell = SetUse(db, referenced.get_spell(), sem_parent, Role::Definition); - ns->def.extent = + 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); @@ -2011,18 +1868,17 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { referenced = referenced.template_specialization_to_template_definition(); - IndexVarId var_id = db->ToVarId(referenced.get_usr_hash()); - IndexVar* var = db->Resolve(var_id); + IndexVar& var = db->ToVar(referenced); // Lambda paramaters are not processed by OnIndexDeclaration and // may not have a short_name yet. Note that we only process the lambda // parameter as a definition if it is in the same file as the reference, // as lambdas cannot be split across files. - if (var->def.detailed_name.empty()) { + if (var.def.detailed_name.empty()) { CXFile referenced_file; Range spell = referenced.get_spell(&referenced_file); if (file == referenced_file) { - var->def.spell = SetUse(db, spell, lex_parent, Role::Definition); - var->def.extent = + var.def.spell = SetUse(db, spell, lex_parent, Role::Definition); + var.def.extent = SetUse(db, referenced.get_extent(), lex_parent, Role::None); // TODO Some of the logic here duplicates CXIdxEntity_Variable branch @@ -2030,10 +1886,10 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { // and has more information, thus not easy to reuse the code. SetVarDetail(var, referenced.get_spell_name(), referenced, nullptr, true, db, param); - var->def.kind = lsSymbolKind::Parameter; + var.def.kind = lsSymbolKind::Parameter; } } - AddUse(db, var->uses, loc, fromContainer(ref->container), + AddUse(db, var.uses, loc, fromContainer(ref->container), GetRole(ref, Role::Reference)); break; } @@ -2058,10 +1914,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { // TODO: search full history? Range loc = cursor.get_spell(); - IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR)); - IndexFunc* called = db->Resolve(called_id); + IndexFunc& called = db->ToFunc(HashUsr(ref->referencedEntity->USR)); - std::string_view short_name = called->def.Name(false); + std::string_view short_name = called.def.Name(false); // libclang doesn't provide a nice api to check if the given function // call is implicit. ref->kind should probably work (it's either direct // or implicit), but libclang only supports implicit for objective-c. @@ -2089,7 +1944,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { CheckTypeDependentMemberRefExpr(&loc, cursor, param, db); OnIndexReference_Function( - db, loc, ref->container->cursor, called_id, + db, loc, ref->container->cursor, called, GetRole(ref, Role::Call) | (is_implicit ? Role::Implicit : Role::None)); @@ -2130,9 +1985,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { std::optional ctor_usr = param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc); if (ctor_usr) { - IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr)); - ctor->uses.push_back(Use(loc, Id(), SymbolKind::File, - Role::Call | Role::Implicit, {})); + IndexFunc& ctor = db->ToFunc(*ctor_usr); + ctor.uses.push_back( + Use{{loc, 0, SymbolKind::File, Role::Call | Role::Implicit}}); } } } @@ -2151,12 +2006,11 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { case CXIdxEntity_Struct: case CXIdxEntity_CXXClass: { referenced = referenced.template_specialization_to_template_definition(); - IndexType* ref_type = - db->Resolve(db->ToTypeId(referenced.get_usr_hash())); + IndexType& ref_type = db->ToType(referenced); if (!ref->parentEntity || IsDeclContext(ref->parentEntity->kind)) - AddUseSpell(db, ref_type->declarations, ref->cursor); + AddUseSpell(db, ref_type.declarations, ref->cursor); else - AddUseSpell(db, ref_type->uses, ref->cursor); + AddUseSpell(db, ref_type.uses, ref->cursor); break; } } @@ -2262,19 +2116,19 @@ std::vector> ParseWithTu( for (std::unique_ptr& entry : result) { entry->import_file = file; entry->args = args; - for (IndexFunc& func : entry->funcs) { + for (auto& it : entry->usr2func) { // e.g. declaration + out-of-line definition - Uniquify(func.derived); - Uniquify(func.uses); + Uniquify(it.second.derived); + Uniquify(it.second.uses); } - for (IndexType& type : entry->types) { - Uniquify(type.derived); - Uniquify(type.uses); + for (auto& it : entry->usr2type) { + Uniquify(it.second.derived); + Uniquify(it.second.uses); // e.g. declaration + out-of-line definition - Uniquify(type.def.funcs); + Uniquify(it.second.def.funcs); } - for (IndexVar& var : entry->vars) - Uniquify(var.uses); + for (auto& it : entry->usr2var) + Uniquify(it.second.uses); if (param.primary_file) { // If there are errors, show at least one at the include position. @@ -2333,29 +2187,27 @@ void Reflect(Reader& visitor, Reference& value) { char* s = const_cast(t.c_str()); value.range = Range::FromString(s); s = strchr(s, '|'); - value.id.id = RawId(strtol(s + 1, &s, 10)); + value.usr = strtoull(s + 1, &s, 10); value.kind = static_cast(strtol(s + 1, &s, 10)); value.role = static_cast(strtol(s + 1, &s, 10)); } else { Reflect(visitor, value.range); - Reflect(visitor, value.id); + Reflect(visitor, value.usr); Reflect(visitor, value.kind); Reflect(visitor, value.role); } } void Reflect(Writer& visitor, Reference& value) { if (visitor.Format() == SerializeFormat::Json) { - // RawId(-1) -> "-1" char buf[99]; - snprintf(buf, sizeof buf, "%s|%" PRId32 "|%d|%d", - value.range.ToString().c_str(), - static_cast>(value.id.id), - int(value.kind), int(value.role)); + snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", + value.range.ToString().c_str(), value.usr, int(value.kind), + int(value.role)); std::string s(buf); Reflect(visitor, s); } else { Reflect(visitor, value.range); - Reflect(visitor, value.id); + Reflect(visitor, value.usr); Reflect(visitor, value.kind); Reflect(visitor, value.role); } diff --git a/src/command_line.cc b/src/command_line.cc index c244811fd..5109dcf7c 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -3,7 +3,6 @@ #include "clang_complete.h" #include "diagnostics_engine.h" #include "file_consumer.h" -#include "import_manager.h" #include "import_pipeline.h" #include "include_complete.h" #include "indexer.h" @@ -112,7 +111,6 @@ bool QueryDbMainLoop(QueryDatabase* db, MultiQueueWaiter* waiter, Project* project, FileConsumerSharedState* file_consumer_shared, - ImportManager* import_manager, ImportPipelineStatus* status, TimestampManager* timestamp_manager, SemanticHighlightSymbolCache* semantic_cache, @@ -143,8 +141,7 @@ bool QueryDbMainLoop(QueryDatabase* db, // TODO: consider rate-limiting and checking for IPC messages so we don't // block requests / we can serve partial requests. - if (QueryDb_ImportMain(db, import_manager, status, semantic_cache, - working_files)) { + if (QueryDb_ImportMain(db, status, semantic_cache, working_files)) { did_work = true; } @@ -186,7 +183,6 @@ void RunQueryDbThread(const std::string& bin_name, auto global_code_complete_cache = std::make_unique(); auto non_global_code_complete_cache = std::make_unique(); auto signature_cache = std::make_unique(); - ImportManager import_manager; ImportPipelineStatus import_pipeline_status; TimestampManager timestamp_manager; QueryDatabase db; @@ -198,7 +194,6 @@ void RunQueryDbThread(const std::string& bin_name, handler->project = &project; handler->diag_engine = &diag_engine; handler->file_consumer_shared = &file_consumer_shared; - handler->import_manager = &import_manager; handler->import_pipeline_status = &import_pipeline_status; handler->timestamp_manager = ×tamp_manager; handler->semantic_cache = &semantic_cache; @@ -216,7 +211,7 @@ void RunQueryDbThread(const std::string& bin_name, while (true) { bool did_work = QueryDbMainLoop( &db, querydb_waiter, &project, &file_consumer_shared, - &import_manager, &import_pipeline_status, ×tamp_manager, + &import_pipeline_status, ×tamp_manager, &semantic_cache, &working_files, &clang_complete, &include_complete, global_code_complete_cache.get(), non_global_code_complete_cache.get(), signature_cache.get()); @@ -226,8 +221,7 @@ void RunQueryDbThread(const std::string& bin_name, if (!did_work) { auto* queue = QueueManager::instance(); - querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb, - &queue->do_id_map); + querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb); } } } diff --git a/src/import_manager.h b/src/import_manager.h deleted file mode 100644 index 7740aec11..000000000 --- a/src/import_manager.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -// Manages files inside of the indexing pipeline so we don't have the same file -// being imported multiple times. -// -// NOTE: This is not thread safe and should only be used on the querydb thread. -struct ImportManager { - std::unordered_set querydb_processing_; - - // TODO: use std::shared_mutex so we can have multiple readers. - std::mutex dependency_mutex_; - std::unordered_set dependency_imported_; -}; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index f970e92b3..ea3448d9a 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -3,7 +3,6 @@ #include "cache_manager.h" #include "config.h" #include "diagnostics_engine.h" -#include "import_manager.h" #include "lsp.h" #include "message_handler.h" #include "platform.h" @@ -22,7 +21,6 @@ namespace { struct Out_Progress : public lsOutMessage { struct Params { int indexRequestCount = 0; - int doIdMapCount = 0; int loadPreviousIndexCount = 0; int onIdMappedCount = 0; int onIndexedCount = 0; @@ -33,7 +31,6 @@ struct Out_Progress : public lsOutMessage { }; MAKE_REFLECT_STRUCT(Out_Progress::Params, indexRequestCount, - doIdMapCount, loadPreviousIndexCount, onIdMappedCount, onIndexedCount, @@ -61,8 +58,6 @@ struct IModificationTimestampFetcher { virtual std::optional LastWriteTime(const std::string& path) = 0; }; struct RealModificationTimestampFetcher : IModificationTimestampFetcher { - ~RealModificationTimestampFetcher() override = default; - // IModificationTimestamp: std::optional LastWriteTime(const std::string& path) override { return ::LastWriteTime(path); @@ -71,8 +66,6 @@ struct RealModificationTimestampFetcher : IModificationTimestampFetcher { struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { std::unordered_map> entries; - ~FakeModificationTimestampFetcher() override = default; - // IModificationTimestamp: std::optional LastWriteTime(const std::string& path) override { auto it = entries.find(path); @@ -110,8 +103,6 @@ struct ActiveThread { auto* queue = QueueManager::instance(); Out_Progress out; out.params.indexRequestCount = queue->index_request.Size(); - out.params.doIdMapCount = queue->do_id_map.Size(); - out.params.loadPreviousIndexCount = queue->load_previous_index.Size(); out.params.onIdMappedCount = queue->on_id_mapped.Size(); out.params.onIndexedCount = queue->on_indexed.Size(); out.params.activeThreads = status_->num_active_threads; @@ -119,11 +110,11 @@ struct ActiveThread { // Ignore this progress update if the last update was too recent. if (g_config && g_config->progressReportFrequencyMs != 0) { // Make sure we output a status update if queue lengths are zero. - bool all_zero = - out.params.indexRequestCount == 0 && out.params.doIdMapCount == 0 && - out.params.loadPreviousIndexCount == 0 && - out.params.onIdMappedCount == 0 && out.params.onIndexedCount == 0 && - out.params.activeThreads == 0; + bool all_zero = out.params.indexRequestCount == 0 && + out.params.loadPreviousIndexCount == 0 && + out.params.onIdMappedCount == 0 && + out.params.onIndexedCount == 0 && + out.params.activeThreads == 0; if (!all_zero && GetCurrentTimeInMilliseconds() < status_->next_progress_output) return; @@ -148,7 +139,6 @@ ShouldParse FileNeedsParse( bool is_interactive, TimestampManager* timestamp_manager, IModificationTimestampFetcher* modification_timestamp_fetcher, - ImportManager* import_manager, const std::shared_ptr& cache_manager, IndexFile* opt_previous_index, const std::string& path, @@ -160,14 +150,6 @@ ShouldParse FileNeedsParse( return ""; }; - // If the file is a dependency but another file as already imported it, - // don't bother. - if (!is_interactive && from) { - std::lock_guard lock(import_manager->dependency_mutex_); - if (!import_manager->dependency_imported_.insert(path).second) - return ShouldParse::No; - } - std::optional modification_timestamp = modification_timestamp_fetcher->LastWriteTime(path); @@ -212,7 +194,6 @@ CacheLoadResult TryLoadFromCache( FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, IModificationTimestampFetcher* modification_timestamp_fetcher, - ImportManager* import_manager, const std::shared_ptr& cache_manager, bool is_interactive, const Project::Entry& entry, @@ -230,7 +211,7 @@ CacheLoadResult TryLoadFromCache( // Check timestamps and update |file_consumer_shared|. ShouldParse path_state = FileNeedsParse( is_interactive, timestamp_manager, modification_timestamp_fetcher, - import_manager, cache_manager, previous_index, path_to_index, entry.args, + cache_manager, previous_index, path_to_index, entry.args, std::nullopt); if (path_state == ShouldParse::Yes) file_consumer_shared->Reset(path_to_index); @@ -248,8 +229,8 @@ CacheLoadResult TryLoadFromCache( assert(!dependency.empty()); if (FileNeedsParse(is_interactive, timestamp_manager, - modification_timestamp_fetcher, import_manager, - cache_manager, previous_index, dependency, entry.args, + modification_timestamp_fetcher, cache_manager, + previous_index, dependency, entry.args, previous_index->path) == ShouldParse::Yes) { needs_reparse = true; @@ -269,10 +250,10 @@ CacheLoadResult TryLoadFromCache( // TODO/FIXME: real perf PerformanceImportFile perf; - std::vector result; - result.push_back(Index_DoIdMap(cache_manager->TakeOrLoad(path_to_index), - cache_manager, perf, is_interactive, - false /*write_to_disk*/)); + std::vector result; + result.push_back(Index_OnIdMapped( + cache_manager, nullptr, cache_manager->TryTakeOrLoad(path_to_index), 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. // @@ -281,23 +262,20 @@ CacheLoadResult TryLoadFromCache( if (!file_consumer_shared->Mark(dependency)) continue; - LOG_S(INFO) << "Emitting index result for " << dependency << " (via " - << previous_index->path << ")"; - - std::unique_ptr dependency_index = - cache_manager->TryTakeOrLoad(dependency); + LOG_S(INFO) << "emit index for " << dependency << " via " + << previous_index->path; // |dependency_index| may be null if there is no cache for it but // another file has already started importing it. - if (!dependency_index) - continue; - - result.push_back(Index_DoIdMap(std::move(dependency_index), cache_manager, - perf, is_interactive, - false /*write_to_disk*/)); + if (std::unique_ptr dependency_index = + cache_manager->TryTakeOrLoad(dependency)) { + result.push_back( + Index_OnIdMapped(cache_manager, nullptr, std::move(dependency_index), + perf, is_interactive, false /*write_to_disk*/)); + } } - QueueManager::instance()->do_id_map.EnqueueAll(std::move(result)); + QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result)); return CacheLoadResult::DoNotParse; } @@ -356,7 +334,6 @@ void ParseFile(DiagnosticsEngine* diag_engine, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, IModificationTimestampFetcher* modification_timestamp_fetcher, - ImportManager* import_manager, IIndexer* indexer, const Index_Request& request, const Project::Entry& entry) { @@ -372,8 +349,8 @@ void ParseFile(DiagnosticsEngine* diag_engine, // Try to load the file from cache. if (TryLoadFromCache(file_consumer_shared, timestamp_manager, - modification_timestamp_fetcher, import_manager, - request.cache_manager, request.is_interactive, entry, + modification_timestamp_fetcher, request.cache_manager, + request.is_interactive, entry, path_to_index) == CacheLoadResult::DoNotParse) { return; } @@ -382,7 +359,7 @@ void ParseFile(DiagnosticsEngine* diag_engine, std::vector file_contents = PreloadFileContents( request.cache_manager, entry, request.contents, path_to_index); - std::vector result; + std::vector result; PerformanceImportFile perf; auto indexes = indexer->Index(file_consumer_shared, path_to_index, entry.args, file_contents, &perf); @@ -411,13 +388,15 @@ void ParseFile(DiagnosticsEngine* diag_engine, // 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, - true /*write_to_disk*/)); + result.push_back( + Index_OnIdMapped(request.cache_manager, + request.cache_manager->TryTakeOrLoad(path_to_index), + std::move(new_index), perf, request.is_interactive, + true /*write_to_disk*/)); } - QueueManager::instance()->do_id_map.EnqueueAll(std::move(result), - request.is_interactive); + QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result), + request.is_interactive); } bool IndexMain_DoParse( @@ -426,7 +405,6 @@ bool IndexMain_DoParse( FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, IModificationTimestampFetcher* modification_timestamp_fetcher, - ImportManager* import_manager, IIndexer* indexer) { auto* queue = QueueManager::instance(); std::optional request = queue->index_request.TryPopFront(); @@ -437,7 +415,7 @@ bool IndexMain_DoParse( entry.filename = request->path; entry.args = request->args; ParseFile(diag_engine, working_files, file_consumer_shared, - timestamp_manager, modification_timestamp_fetcher, import_manager, + timestamp_manager, modification_timestamp_fetcher, indexer, request.value(), entry); return true; } @@ -456,31 +434,22 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { Timer time; - IdMap* previous_id_map = nullptr; - IndexFile* previous_index = nullptr; - if (response->previous) { - previous_id_map = response->previous->ids.get(); - previous_index = response->previous->file.get(); - } - // Build delta update. - IndexUpdate update = - IndexUpdate::CreateDelta(previous_id_map, response->current->ids.get(), - previous_index, response->current->file.get()); + IndexUpdate update = IndexUpdate::CreateDelta(response->previous.get(), + response->current.get()); response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); - LOG_S(INFO) << "Built index update for " << response->current->file->path + LOG_S(INFO) << "Built index update for " << response->current->path << " (is_delta=" << !!response->previous << ")"; // Write current index to disk if requested. if (response->write_to_disk) { - LOG_S(INFO) << "Writing cached index to disk for " - << response->current->file->path; + LOG_S(INFO) << "Writing index to disk for " << response->current->path; time.Reset(); - response->cache_manager->WriteToCache(*response->current->file); + response->cache_manager->WriteToCache(*response->current); response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); timestamp_manager->UpdateCachedModificationTime( - response->current->file->path, - response->current->file->last_modification_time); + response->current->path, + response->current->last_modification_time); } Index_OnIndexed reply(std::move(update), response->perf); @@ -490,42 +459,6 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { return did_work; } -bool IndexMain_LoadPreviousIndex() { - auto* queue = QueueManager::instance(); - std::optional response = queue->load_previous_index.TryPopFront(); - if (!response) - return false; - - 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; - - queue->do_id_map.PushBack(std::move(*response)); - return true; -} - -bool IndexMergeIndexUpdates() { - auto* queue = QueueManager::instance(); - std::optional root = queue->on_indexed.TryPopBack(); - if (!root) - return false; - - bool did_merge = false; - IterationLoop loop; - while (loop.Next()) { - std::optional to_join = queue->on_indexed.TryPopBack(); - if (!to_join) - break; - did_merge = true; - root->update.Merge(std::move(to_join->update)); - } - - queue->on_indexed.PushFront(std::move(*root)); - return did_merge; -} - } // namespace std::optional TimestampManager::GetLastCachedModificationTime( @@ -573,7 +506,7 @@ void IndexWithTuFromCodeCompletion( if (indexes.empty()) return; - std::vector result; + std::vector result; for (std::unique_ptr& new_index : indexes) { Timer time; @@ -581,22 +514,21 @@ void IndexWithTuFromCodeCompletion( assert(false && "FIXME cache_manager"); // 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), cache_manager, perf, - true /*is_interactive*/, - true /*write_to_disk*/)); + LOG_S(INFO) << "Emitting index for " << new_index->path; + result.push_back(Index_OnIdMapped( + cache_manager, cache_manager->TryTakeOrLoad(path), std::move(new_index), + perf, true /*is_interactive*/, true /*write_to_disk*/)); } LOG_IF_S(WARNING, result.size() > 1) << "Code completion index update generated more than one index"; - QueueManager::instance()->do_id_map.EnqueueAll(std::move(result)); + QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result)); } void Indexer_Main(DiagnosticsEngine* diag_engine, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, - ImportManager* import_manager, ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, @@ -624,121 +556,55 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, did_work = IndexMain_DoParse(diag_engine, working_files, file_consumer_shared, timestamp_manager, &modification_timestamp_fetcher, - import_manager, indexer.get()) || + indexer.get()) || did_work; did_work = IndexMain_DoCreateIndexUpdate(timestamp_manager) || did_work; - - did_work = IndexMain_LoadPreviousIndex() || did_work; - - // Nothing to index and no index updates to create, so join some already - // created index updates to reduce work on querydb thread. - if (!did_work) - did_work = IndexMergeIndexUpdates() || did_work; } // We didn't do any work, so wait for a notification. if (!did_work) { waiter->Wait(&queue->on_indexed, &queue->index_request, - &queue->on_id_mapped, &queue->load_previous_index); + &queue->on_id_mapped); } } } namespace { -void QueryDb_DoIdMap(QueueManager* queue, - QueryDatabase* db, - ImportManager* import_manager, - Index_DoIdMap* request) { - assert(request->current); - - // If the request does not have previous state and we have already imported - // it, load the previous state from disk and rerun IdMap logic later. Do not - // do this if we have already attempted in the past. - if (!request->load_previous && !request->previous && - db->usr_to_file.find(LowerPathIfInsensitive(request->current->path)) != - db->usr_to_file.end()) { - assert(!request->load_previous); - request->load_previous = true; - queue->load_previous_index.PushBack(std::move(*request)); - return; - } - - // Check if the file is already being imported into querydb. If it is, drop - // the request. - // - // Note, we must do this *after* we have checked for the previous index, - // otherwise we will never actually generate the IdMap. - if (!import_manager->querydb_processing_.insert(request->current->path) - .second) { - LOG_S(INFO) << "Dropping index as it is already being imported for " - << request->current->path; - return; - } - - Index_OnIdMapped response(request->cache_manager, request->perf, - request->is_interactive, request->write_to_disk); - Timer time; - - auto make_map = [db](std::unique_ptr file) - -> std::unique_ptr { - if (!file) - return nullptr; - - auto id_map = std::make_unique(db, file->id_cache); - return std::make_unique(std::move(file), - std::move(id_map)); - }; - response.current = make_map(std::move(request->current)); - response.previous = make_map(std::move(request->previous)); - response.perf.querydb_id_map = time.ElapsedMicrosecondsAndReset(); - - queue->on_id_mapped.PushBack(std::move(response)); -} - void QueryDb_OnIndexed(QueueManager* queue, QueryDatabase* db, - ImportManager* import_manager, ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, Index_OnIndexed* response) { Timer time; db->ApplyIndexUpdate(&response->update); - time.ResetAndPrint("Applying index update for " + - StringJoinMap(response->update.files_def_update, - [](const QueryFile::DefUpdate& value) { - return value.value.path; - })); // Update indexed content, inactive lines, and semantic highlighting. - for (auto& updated_file : response->update.files_def_update) { + if (response->update.files_def_update) { + auto& update = *response->update.files_def_update; + time.ResetAndPrint("apply index for " + update.value.path); WorkingFile* working_file = - working_files->GetFileByFilename(updated_file.value.path); + working_files->GetFileByFilename(update.value.path); if (working_file) { // Update indexed content. - working_file->SetIndexContent(updated_file.file_content); + working_file->SetIndexContent(update.file_content); // Inactive lines. - EmitInactiveLines(working_file, updated_file.value.inactive_regions); + EmitInactiveLines(working_file, update.value.inactive_regions); // Semantic highlighting. - QueryFileId file_id = - db->usr_to_file[LowerPathIfInsensitive(working_file->filename)]; - QueryFile* file = &db->files[file_id.id]; + int file_id = + db->name2file_id[LowerPathIfInsensitive(working_file->filename)]; + QueryFile* file = &db->files[file_id]; EmitSemanticHighlighting(db, semantic_cache, working_file, file); } - - // Mark the files as being done in querydb stage after we apply the index - // update. - import_manager->querydb_processing_.erase(updated_file.value.path); } } } // namespace bool QueryDb_ImportMain(QueryDatabase* db, - ImportManager* import_manager, ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files) { @@ -749,22 +615,13 @@ bool QueryDb_ImportMain(QueryDatabase* db, bool did_work = false; IterationLoop loop; - while (loop.Next()) { - std::optional request = queue->do_id_map.TryPopFront(); - if (!request) - break; - did_work = true; - QueryDb_DoIdMap(queue, db, import_manager, &*request); - } - - loop.Reset(); while (loop.Next()) { std::optional response = queue->on_indexed.TryPopFront(); if (!response) break; did_work = true; - QueryDb_OnIndexed(queue, db, import_manager, status, semantic_cache, - working_files, &*response); + QueryDb_OnIndexed(queue, db, status, semantic_cache, working_files, + &*response); } return did_work; @@ -785,8 +642,7 @@ TEST_SUITE("ImportPipeline") { bool PumpOnce() { return IndexMain_DoParse(&diag_engine, &working_files, &file_consumer_shared, ×tamp_manager, - &modification_timestamp_fetcher, &import_manager, - indexer.get()); + &modification_timestamp_fetcher, indexer.get()); } void MakeRequest(const std::string& path, @@ -807,7 +663,6 @@ TEST_SUITE("ImportPipeline") { FileConsumerSharedState file_consumer_shared; TimestampManager timestamp_manager; FakeModificationTimestampFetcher modification_timestamp_fetcher; - ImportManager import_manager; std::shared_ptr cache_manager; std::unique_ptr indexer; }; @@ -827,8 +682,8 @@ TEST_SUITE("ImportPipeline") { from = std::string("---.cc"); return FileNeedsParse(is_interactive /*is_interactive*/, ×tamp_manager, &modification_timestamp_fetcher, - &import_manager, cache_manager, - opt_previous_index.get(), file, new_args, from); + cache_manager, opt_previous_index.get(), file, + new_args, from); }; // A file with no timestamp is not imported, since this implies the file no @@ -882,10 +737,10 @@ TEST_SUITE("ImportPipeline") { MakeRequest("foo.cc"); REQUIRE(queue->index_request.Size() == 1); - REQUIRE(queue->do_id_map.Size() == 0); + REQUIRE(queue->on_id_mapped.Size() == 0); PumpOnce(); REQUIRE(queue->index_request.Size() == 0); - REQUIRE(queue->do_id_map.Size() == 0); + REQUIRE(queue->on_id_mapped.Size() == 0); REQUIRE(file_consumer_shared.used_files.empty()); } @@ -896,10 +751,10 @@ TEST_SUITE("ImportPipeline") { MakeRequest("foo.cc"); REQUIRE(queue->index_request.Size() == 1); - REQUIRE(queue->do_id_map.Size() == 0); + REQUIRE(queue->on_id_mapped.Size() == 0); PumpOnce(); REQUIRE(queue->index_request.Size() == 0); - REQUIRE(queue->do_id_map.Size() == 100); + REQUIRE(queue->on_id_mapped.Size() == 100); REQUIRE(file_consumer_shared.used_files.empty()); } @@ -912,11 +767,11 @@ TEST_SUITE("ImportPipeline") { MakeRequest("bar.cc"); REQUIRE(queue->index_request.Size() == 2); - REQUIRE(queue->do_id_map.Size() == 0); + //REQUIRE(queue->do_id_map.Size() == 0); while (PumpOnce()) { } REQUIRE(queue->index_request.Size() == 0); - REQUIRE(queue->do_id_map.Size() == 105); + //REQUIRE(queue->do_id_map.Size() == 105); REQUIRE(file_consumer_shared.used_files.empty()); } diff --git a/src/import_pipeline.h b/src/import_pipeline.h index 5a0fbc4e0..9b74dd13e 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -15,7 +15,6 @@ struct ClangTranslationUnit; class DiagnosticsEngine; struct FileConsumerSharedState; struct ICacheManager; -struct ImportManager; struct MultiQueueWaiter; struct Project; struct QueryDatabase; @@ -53,14 +52,12 @@ void IndexWithTuFromCodeCompletion( void Indexer_Main(DiagnosticsEngine* diag_engine, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, - ImportManager* import_manager, ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, MultiQueueWaiter* waiter); bool QueryDb_ImportMain(QueryDatabase* db, - ImportManager* import_manager, ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files); diff --git a/src/indexer.h b/src/indexer.h index 7b46b4e8a..1d2b1aeac 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -71,33 +71,30 @@ void Reflect(TVisitor& visitor, Id& id) { } using IndexFileId = Id; -using IndexTypeId = Id; -using IndexFuncId = Id; -using IndexVarId = Id; struct SymbolIdx { - Id id; + Usr usr; SymbolKind kind; bool operator==(const SymbolIdx& o) const { - return id == o.id && kind == o.kind; + return usr == o.usr && kind == o.kind; } bool operator<(const SymbolIdx& o) const { - return !(id == o.id) ? id < o.id : kind < o.kind; + return usr != o.usr ? usr < o.usr : kind < o.kind; } }; -MAKE_REFLECT_STRUCT(SymbolIdx, kind, id); +MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind); struct Reference { Range range; - Id id; + Usr usr; SymbolKind kind; Role role; bool Valid() const { return range.Valid(); } - operator SymbolIdx() const { return {id, kind}; } - std::tuple, SymbolKind, Role> ToTuple() const { - return std::make_tuple(range, id, kind, role); + operator SymbolIdx() const { return {usr, kind}; } + std::tuple ToTuple() const { + return std::make_tuple(range, usr, kind, role); } bool operator==(const Reference& o) const { return ToTuple() == o.ToTuple(); } bool operator<(const Reference& o) const { return ToTuple() < o.ToTuple(); } @@ -106,31 +103,20 @@ struct Reference { // |id,kind| refer to the referenced entity. struct SymbolRef : Reference { SymbolRef() = default; - SymbolRef(Range range, Id id, SymbolKind kind, Role role) - : Reference{range, id, kind, role} {} + SymbolRef(Range range, Usr usr, SymbolKind kind, Role role) + : Reference{range, usr, kind, role} {} }; // Represents an occurrence of a variable/type, |id,kind| refer to the lexical // parent. struct Use : Reference { // |file| is used in Query* but not in Index* - Id file; - Use() = default; - Use(Range range, Id id, SymbolKind kind, Role role, Id file) - : Reference{range, id, kind, role}, file(file) {} + int file_id = -1; }; void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); -struct IndexFamily { - using FileId = Id; - using FuncId = Id; - using TypeId = Id; - using VarId = Id; - using Range = ::Range; -}; - template struct NameMixin { std::string_view Name(bool qualified) const { @@ -145,184 +131,145 @@ struct NameMixin { } }; -template -struct TypeDef : NameMixin> { +struct FuncDef : NameMixin { // General metadata. std::string detailed_name; NtString hover; NtString comments; - - // While a class/type can technically have a separate declaration/definition, - // it doesn't really happen in practice. The declaration never contains - // comments or insightful information. The user always wants to jump from - // the declaration to the definition - never the other way around like in - // functions and (less often) variables. - // - // It's also difficult to identify a `class Foo;` statement with the clang - // indexer API (it's doable using cursor AST traversal), so we don't bother - // supporting the feature. Maybe spell; Maybe extent; - // Immediate parent types. - std::vector bases; + // Method this method overrides. + std::vector bases; - // Types, functions, and variables defined in this type. - std::vector types; - std::vector funcs; - std::vector vars; + // Local variables or parameters. + std::vector vars; - typename F::FileId file; - // If set, then this is the same underlying type as the given value (ie, this - // type comes from a using or typedef statement). - Maybe alias_of; + // Functions that this function calls. + std::vector callees; + int file_id; + // Type which declares this one (ie, it is a method) + Usr declaring_type = 0; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; + StorageClass storage = StorageClass::Invalid; - bool operator==(const TypeDef& o) const { + bool operator==(const FuncDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && - extent == o.extent && alias_of == o.alias_of && bases == o.bases && - types == o.types && funcs == o.funcs && vars == o.vars && - kind == o.kind && hover == o.hover && comments == o.comments; + extent == o.extent && declaring_type == o.declaring_type && + bases == o.bases && vars == o.vars && callees == o.callees && + kind == o.kind && storage == o.storage && hover == o.hover && + comments == o.comments; } }; -template -void Reflect(TVisitor& visitor, TypeDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(detailed_name); - REFLECT_MEMBER(qual_name_offset); - REFLECT_MEMBER(short_name_offset); - REFLECT_MEMBER(short_name_size); - REFLECT_MEMBER(kind); - REFLECT_MEMBER(hover); - REFLECT_MEMBER(comments); - REFLECT_MEMBER(spell); - REFLECT_MEMBER(extent); - REFLECT_MEMBER(file); - REFLECT_MEMBER(alias_of); - REFLECT_MEMBER(bases); - REFLECT_MEMBER(types); - REFLECT_MEMBER(funcs); - REFLECT_MEMBER(vars); - REFLECT_MEMBER_END(); -} - -struct IndexType { - using Def = TypeDef; +MAKE_REFLECT_STRUCT(FuncDef, + detailed_name, + qual_name_offset, + short_name_offset, + short_name_size, + kind, + storage, + hover, + comments, + spell, + extent, + file_id, + declaring_type, + bases, + vars, + callees); +struct IndexFunc : NameMixin { + using Def = FuncDef; Usr usr; - IndexTypeId id; - Def def; std::vector declarations; - - // Immediate derived types. - std::vector derived; - - // Declared variables of this type. - std::vector instances; - - // Every usage, useful for things like renames. - // NOTE: Do not insert directly! Use AddUsage instead. std::vector uses; + std::vector derived; - bool operator<(const IndexType& other) const { return id < other.id; } + bool operator<(const IndexFunc& other) const { return usr < other.usr; } }; -template -struct FuncDef : NameMixin> { +struct TypeDef : NameMixin { // General metadata. std::string detailed_name; NtString hover; NtString comments; + + // While a class/type can technically have a separate declaration/definition, + // it doesn't really happen in practice. The declaration never contains + // comments or insightful information. The user always wants to jump from + // the declaration to the definition - never the other way around like in + // functions and (less often) variables. + // + // It's also difficult to identify a `class Foo;` statement with the clang + // indexer API (it's doable using cursor AST traversal), so we don't bother + // supporting the feature. Maybe spell; Maybe extent; - // Method this method overrides. - std::vector bases; + // Immediate parent types. + std::vector bases; - // Local variables or parameters. - std::vector vars; + // Types, functions, and variables defined in this type. + std::vector types; + std::vector funcs; + std::vector vars; - // Functions that this function calls. - std::vector callees; + // If set, then this is the same underlying type as the given value (ie, this + // type comes from a using or typedef statement). + Usr alias_of = 0; + int file_id; - typename F::FileId file; - // Type which declares this one (ie, it is a method) - Maybe declaring_type; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; - StorageClass storage = StorageClass::Invalid; - bool operator==(const FuncDef& o) const { + bool operator==(const TypeDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && - extent == o.extent && declaring_type == o.declaring_type && - bases == o.bases && vars == o.vars && callees == o.callees && - kind == o.kind && storage == o.storage && hover == o.hover && - comments == o.comments; + extent == o.extent && alias_of == o.alias_of && bases == o.bases && + types == o.types && funcs == o.funcs && vars == o.vars && + kind == o.kind && hover == o.hover && comments == o.comments; } }; +MAKE_REFLECT_STRUCT(TypeDef, + detailed_name, + qual_name_offset, + short_name_offset, + short_name_size, + kind, + hover, + comments, + spell, + extent, + file_id, + alias_of, + bases, + types, + funcs, + vars); -template -void Reflect(TVisitor& visitor, FuncDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(detailed_name); - REFLECT_MEMBER(qual_name_offset); - REFLECT_MEMBER(short_name_offset); - REFLECT_MEMBER(short_name_size); - REFLECT_MEMBER(kind); - REFLECT_MEMBER(storage); - REFLECT_MEMBER(hover); - REFLECT_MEMBER(comments); - REFLECT_MEMBER(spell); - REFLECT_MEMBER(extent); - REFLECT_MEMBER(file); - REFLECT_MEMBER(declaring_type); - REFLECT_MEMBER(bases); - REFLECT_MEMBER(vars); - REFLECT_MEMBER(callees); - REFLECT_MEMBER_END(); -} - -struct IndexFunc : NameMixin { - using Def = FuncDef; - +struct IndexType { + using Def = TypeDef; Usr usr; - IndexFuncId id; - Def def; - - struct Declaration { - // Range of only the function name. - Use spell; - // Location of the parameter names. - std::vector param_spellings; - }; - - // Places the function is forward-declared. - std::vector declarations; - - // Methods which directly override this one. - std::vector derived; - - // Calls/usages of this function. If the call is coming from outside a - // function context then the FuncRef will not have an associated id. - // - // To get all usages, also include the ranges inside of declarations and - // def.spell. + std::vector declarations; std::vector uses; + std::vector derived; + std::vector instances; - bool operator<(const IndexFunc& other) const { return id < other.id; } + // Every usage, useful for things like renames. + // NOTE: Do not insert directly! Use AddUsage instead. + + bool operator<(const IndexType& other) const { return usr < other.usr; } }; -MAKE_REFLECT_STRUCT(IndexFunc::Declaration, spell, param_spellings); -template -struct VarDef : NameMixin> { + +struct VarDef : NameMixin { // General metadata. std::string detailed_name; NtString hover; @@ -332,9 +279,9 @@ struct VarDef : NameMixin> { Maybe spell; Maybe extent; - typename F::FileId file; + int file_id; // Type of the variable. - Maybe type; + Usr type = 0; // Function/type which declares this one. int16_t qual_name_offset = 0; @@ -354,47 +301,28 @@ struct VarDef : NameMixin> { storage == o.storage && hover == o.hover && comments == o.comments; } }; - -template -void Reflect(TVisitor& visitor, VarDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(detailed_name); - REFLECT_MEMBER(qual_name_offset); - REFLECT_MEMBER(short_name_offset); - REFLECT_MEMBER(short_name_size); - REFLECT_MEMBER(hover); - REFLECT_MEMBER(comments); - REFLECT_MEMBER(spell); - REFLECT_MEMBER(extent); - REFLECT_MEMBER(file); - REFLECT_MEMBER(type); - REFLECT_MEMBER(kind); - REFLECT_MEMBER(storage); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(VarDef, + detailed_name, + qual_name_offset, + short_name_offset, + short_name_size, + hover, + comments, + spell, + extent, + file_id, + type, + kind, + storage); struct IndexVar { - using Def = VarDef; - + using Def = VarDef; Usr usr; - IndexVarId id; - Def def; - std::vector declarations; std::vector uses; - bool operator<(const IndexVar& other) const { return id < other.id; } -}; - -struct IdCache { - std::string primary_file; - std::unordered_map usr_to_type_id; - std::unordered_map usr_to_func_id; - std::unordered_map usr_to_var_id; - std::unordered_map type_id_to_usr; - std::unordered_map func_id_to_usr; - std::unordered_map var_id_to_usr; + bool operator<(const IndexVar& other) const { return usr < other.usr; } }; struct IndexInclude { @@ -406,8 +334,6 @@ struct IndexInclude { }; struct IndexFile { - IdCache id_cache; - // For both JSON and MessagePack cache files. static const int kMajorVersion; // For MessagePack cache files. @@ -432,9 +358,9 @@ struct IndexFile { std::vector includes; std::vector dependencies; - std::vector types; - std::vector funcs; - std::vector vars; + std::unordered_map usr2func; + std::unordered_map usr2type; + std::unordered_map usr2var; // Diagnostics found when indexing this file. Not serialized. std::vector diagnostics_; @@ -443,15 +369,12 @@ struct IndexFile { IndexFile(const std::string& path, const std::string& contents); - IndexTypeId ToTypeId(Usr usr); - IndexFuncId ToFuncId(Usr usr); - IndexVarId ToVarId(Usr usr); - IndexTypeId ToTypeId(const CXCursor& usr); - IndexFuncId ToFuncId(const CXCursor& usr); - IndexVarId ToVarId(const CXCursor& usr); - IndexType* Resolve(IndexTypeId id); - IndexFunc* Resolve(IndexFuncId id); - IndexVar* Resolve(IndexVarId id); + IndexFunc& ToFunc(Usr usr); + IndexType& ToType(Usr usr); + IndexVar& ToVar(Usr usr); + IndexFunc& ToFunc(const ClangCursor& c) { return ToFunc(c.get_usr_hash()); } + IndexType& ToType(const ClangCursor& c) { return ToType(c.get_usr_hash()); } + IndexVar& ToVar(const ClangCursor& c) { return ToVar(c.get_usr_hash()); } std::string ToString(); }; diff --git a/src/message_handler.cc b/src/message_handler.cc index b43f87648..1a2a3c875 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -9,7 +9,7 @@ #include -MAKE_HASHABLE(SymbolIdx, t.kind, t.id); +MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); namespace { @@ -130,22 +130,22 @@ bool FindFileOrFail(QueryDatabase* db, std::optional id, const std::string& absolute_path, QueryFile** out_query_file, - QueryFileId* out_file_id) { + int* out_file_id) { *out_query_file = nullptr; - auto it = db->usr_to_file.find(LowerPathIfInsensitive(absolute_path)); - if (it != db->usr_to_file.end()) { - QueryFile& file = db->files[it->second.id]; + auto it = db->name2file_id.find(LowerPathIfInsensitive(absolute_path)); + if (it != db->name2file_id.end()) { + QueryFile& file = db->files[it->second]; if (file.def) { *out_query_file = &file; if (out_file_id) - *out_file_id = QueryFileId(it->second.id); + *out_file_id = it->second; return true; } } if (out_file_id) - *out_file_id = QueryFileId(); + *out_file_id = -1; bool indexing = project->absolute_path_to_entry_index_.find(absolute_path) != project->absolute_path_to_entry_index_.end(); diff --git a/src/message_handler.h b/src/message_handler.h index ca6c7a2f3..8f35dbb08 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -143,7 +143,7 @@ bool FindFileOrFail(QueryDatabase* db, std::optional id, const std::string& absolute_path, QueryFile** out_query_file, - QueryFileId* out_file_id = nullptr); + int* out_file_id = nullptr); void EmitInactiveLines(WorkingFile* working_file, const std::vector& inactive_regions); diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index cc6819865..804137623 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -33,13 +33,13 @@ struct Handler_CclsBase : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { if (const auto* def = db->GetType(sym).AnyDef()) - out.result = GetLsLocationExs(db, working_files, - GetDeclarations(db, def->bases)); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db->usr2type, def->bases)); break; } else if (sym.kind == SymbolKind::Func) { if (const auto* def = db->GetFunc(sym).AnyDef()) - out.result = GetLsLocationExs(db, working_files, - GetDeclarations(db, def->bases)); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db->usr2func, def->bases)); break; } } diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index e9aebe4f0..410cfdcf8 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -29,7 +29,8 @@ struct In_CclsCallHierarchy : public RequestInMessage { lsTextDocumentIdentifier textDocument; lsPosition position; - Maybe id; + Usr usr; + std::string id; // true: callee tree (functions called by this function); false: caller tree // (where this function is called) @@ -56,7 +57,8 @@ REGISTER_IN_MESSAGE(In_CclsCallHierarchy); struct Out_CclsCallHierarchy : public lsOutMessage { struct Entry { - QueryFuncId id; + Usr usr; + std::string id; std::string_view name; lsLocation location; CallType callType = CallType::Direct; @@ -83,7 +85,7 @@ bool Expand(MessageHandler* m, CallType call_type, bool qualified, int levels) { - const QueryFunc& func = m->db->funcs[entry->id.id]; + const QueryFunc& func = m->db->Func(entry->usr); const QueryFunc::Def* def = func.AnyDef(); entry->numChildren = 0; if (!def) @@ -92,7 +94,8 @@ bool Expand(MessageHandler* m, entry->numChildren++; if (levels > 0) { Out_CclsCallHierarchy::Entry entry1; - entry1.id = QueryFuncId(use.id); + entry1.id = std::to_string(use.usr); + entry1.usr = use.usr; if (auto loc = GetLsLocation(m->db, m->working_files, use)) entry1.location = *loc; entry1.callType = call_type; @@ -105,7 +108,7 @@ bool Expand(MessageHandler* m, if (const auto* def = func.AnyDef()) for (SymbolRef ref : def->callees) if (ref.kind == SymbolKind::Func) - handle(Use(ref.range, ref.id, ref.kind, ref.role, def->file), + handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id}, call_type); } else { for (Use use : func.uses) @@ -127,7 +130,7 @@ bool Expand(MessageHandler* m, const QueryFunc& func1 = *stack.back(); stack.pop_back(); if (auto* def1 = func1.AnyDef()) { - EachDefinedEntity(m->db->funcs, def1->bases, [&](QueryFunc& func2) { + EachDefinedEntity(m->db->usr2func, def1->bases, [&](QueryFunc& func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -144,7 +147,7 @@ bool Expand(MessageHandler* m, while (stack.size()) { const QueryFunc& func1 = *stack.back(); stack.pop_back(); - EachDefinedEntity(m->db->funcs, func1.derived, [&](QueryFunc& func2) { + EachDefinedEntity(m->db->usr2func, func1.derived, [&](QueryFunc& func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -160,17 +163,18 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional BuildInitial(QueryFuncId root_id, - bool callee, - CallType call_type, - bool qualified, - int levels) { - const auto* def = db->funcs[root_id.id].AnyDef(); + std::optional BuildInitial(Usr root_usr, + bool callee, + CallType call_type, + bool qualified, + int levels) { + const auto* def = db->Func(root_usr).AnyDef(); if (!def) return {}; Out_CclsCallHierarchy::Entry entry; - entry.id = root_id; + entry.id = std::to_string(root_usr); + entry.usr = root_usr; entry.callType = CallType::Direct; if (def->spell) { if (std::optional loc = @@ -186,11 +190,17 @@ struct Handler_CclsCallHierarchy Out_CclsCallHierarchy out; out.id = request->id; - if (params.id) { + if (params.id.size()) { + try { + params.usr = std::stoull(params.id); + } catch (...) { + return; + } Out_CclsCallHierarchy::Entry entry; - entry.id = *params.id; + entry.id = std::to_string(params.usr); + entry.usr = params.usr; entry.callType = CallType::Direct; - if (entry.id.id < db->funcs.size()) + if (db->usr2func.count(params.usr)) Expand(this, &entry, params.callee, params.callType, params.qualified, params.levels); out.result = std::move(entry); @@ -204,9 +214,8 @@ struct Handler_CclsCallHierarchy for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, params.position)) { if (sym.kind == SymbolKind::Func) { - out.result = - BuildInitial(QueryFuncId(sym.id), params.callee, params.callType, - params.qualified, params.levels); + out.result = BuildInitial(sym.usr, params.callee, params.callType, + params.qualified, params.levels); break; } } diff --git a/src/messages/ccls_derived.cc b/src/messages/ccls_derived.cc index d8676211a..7a0c33ebb 100644 --- a/src/messages/ccls_derived.cc +++ b/src/messages/ccls_derived.cc @@ -30,13 +30,13 @@ struct Handler_CclsDerived : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { QueryType& type = db->GetType(sym); - out.result = GetLsLocationExs(db, working_files, - GetDeclarations(db, type.derived)); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db->usr2type, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); - out.result = GetLsLocationExs(db, working_files, - GetDeclarations(db, func.derived)); + out.result = GetLsLocationExs( + db, working_files, GetDeclarations(db->usr2func, func.derived)); break; } } diff --git a/src/messages/ccls_file_info.cc b/src/messages/ccls_file_info.cc index 4a8acf592..cbd6ed78d 100644 --- a/src/messages/ccls_file_info.cc +++ b/src/messages/ccls_file_info.cc @@ -3,7 +3,6 @@ #include "queue_manager.h" MAKE_REFLECT_STRUCT(QueryFile::Def, - file, path, args, language, diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 3ead318d3..2f4d83be4 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -13,7 +13,8 @@ struct In_CclsInheritanceHierarchy : public RequestInMessage { lsTextDocumentIdentifier textDocument; lsPosition position; - Maybe> id; + Usr usr; + std::string id; SymbolKind kind = SymbolKind::Invalid; // true: derived classes/functions; false: base classes/functions @@ -38,7 +39,8 @@ REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); struct Out_CclsInheritanceHierarchy : public lsOutMessage { struct Entry { - Id id; + Usr usr; + std::string id; SymbolKind kind; std::string_view name; lsLocation location; @@ -86,9 +88,10 @@ bool ExpandHelper(MessageHandler* m, } if (derived) { if (levels > 0) { - for (auto id : entity.derived) { + for (auto usr : entity.derived) { Out_CclsInheritanceHierarchy::Entry entry1; - entry1.id = id; + entry1.id = std::to_string(usr); + entry1.usr = usr; entry1.kind = entry->kind; if (Expand(m, &entry1, derived, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); @@ -98,9 +101,10 @@ bool ExpandHelper(MessageHandler* m, entry->numChildren = int(entity.derived.size()); } else { if (levels > 0) { - for (auto id : def->bases) { + for (auto usr : def->bases) { Out_CclsInheritanceHierarchy::Entry entry1; - entry1.id = id; + entry1.id = std::to_string(usr); + entry1.usr = usr; entry1.kind = entry->kind; if (Expand(m, &entry1, derived, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); @@ -119,10 +123,10 @@ bool Expand(MessageHandler* m, int levels) { if (entry->kind == SymbolKind::Func) return ExpandHelper(m, entry, derived, qualified, levels, - m->db->funcs[entry->id.id]); + m->db->Func(entry->usr)); else return ExpandHelper(m, entry, derived, qualified, levels, - m->db->types[entry->id.id]); + m->db->Type(entry->usr)); } struct Handler_CclsInheritanceHierarchy @@ -132,7 +136,8 @@ struct Handler_CclsInheritanceHierarchy std::optional BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) { Out_CclsInheritanceHierarchy::Entry entry; - entry.id = sym.id; + entry.id = std::to_string(sym.usr); + entry.usr = sym.usr; entry.kind = sym.kind; Expand(this, &entry, derived, qualified, levels); return entry; @@ -143,15 +148,19 @@ struct Handler_CclsInheritanceHierarchy Out_CclsInheritanceHierarchy out; out.id = request->id; - if (params.id) { + if (params.id.size()) { + try { + params.usr = std::stoull(params.id); + } catch (...) { + return; + } Out_CclsInheritanceHierarchy::Entry entry; - entry.id = *params.id; + entry.id = std::to_string(params.usr); + entry.usr = params.usr; entry.kind = params.kind; - if (((entry.kind == SymbolKind::Func && entry.id.id < db->funcs.size()) || - (entry.kind == SymbolKind::Type && - entry.id.id < db->types.size())) && - Expand(this, &entry, params.derived, params.qualified, - params.levels)) + if (((entry.kind == SymbolKind::Func && db->usr2func.count(entry.usr)) || + (entry.kind == SymbolKind::Type && db->usr2type.count(entry.usr))) && + Expand(this, &entry, params.derived, params.qualified, params.levels)) out.result = std::move(entry); } else { QueryFile* file; diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 747f4f85b..c8daab6b7 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -14,7 +14,9 @@ struct In_CclsMemberHierarchy : public RequestInMessage { lsTextDocumentIdentifier textDocument; lsPosition position; - Maybe id; + // Type + Usr usr; + std::string id; bool qualified = false; int levels = 1; @@ -34,7 +36,8 @@ REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); struct Out_CclsMemberHierarchy : public lsOutMessage { struct Entry { - QueryTypeId id; + Usr usr; + std::string id; std::string_view name; std::string fieldName; lsLocation location; @@ -82,11 +85,13 @@ void DoField(MessageHandler* m, entry1.location = *loc; } if (def1->type) { - entry1.id = *def1->type; + entry1.id = std::to_string(def1->type); + entry1.usr = def1->type; if (Expand(m, &entry1, qualified, levels)) entry->children.push_back(std::move(entry1)); } else { - entry1.id = QueryTypeId(); + entry1.id = "0"; + entry1.usr = 0; entry->children.push_back(std::move(entry1)); } } @@ -96,13 +101,13 @@ bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, bool qualified, int levels) { - const QueryType& type = m->db->types[entry->id.id]; - const QueryType::Def* def = type.AnyDef(); - // builtin types have no declaration and empty |qualified|. - if (CXType_FirstBuiltin <= type.usr && type.usr <= CXType_LastBuiltin) { - entry->name = ClangBuiltinTypeName(CXTypeKind(type.usr)); + if (CXType_FirstBuiltin <= entry->usr && entry->usr <= CXType_LastBuiltin) { + entry->name = ClangBuiltinTypeName(CXTypeKind(entry->usr)); return true; } + const QueryType& type = m->db->Type(entry->usr); + const QueryType::Def* def = type.AnyDef(); + // builtin types have no declaration and empty |qualified|. if (!def) return false; entry->name = def->Name(qualified); @@ -115,16 +120,17 @@ bool Expand(MessageHandler* m, const auto* def = stack.back()->AnyDef(); stack.pop_back(); if (def) { - EachDefinedEntity(m->db->types, def->bases, [&](QueryType& type1) { + EachDefinedEntity(m->db->usr2type, def->bases, [&](QueryType& type1) { if (!seen.count(type1.usr)) { seen.insert(type1.usr); stack.push_back(&type1); } }); if (def->alias_of) { - const QueryType::Def* def1 = m->db->types[def->alias_of->id].AnyDef(); + const QueryType::Def* def1 = m->db->Type(def->alias_of).AnyDef(); Out_CclsMemberHierarchy::Entry entry1; - entry1.id = *def->alias_of; + entry1.id = std::to_string(def->alias_of); + entry1.usr = def->alias_of; if (def1 && def1->spell) { // The declaration of target type. if (std::optional loc = @@ -146,7 +152,7 @@ bool Expand(MessageHandler* m, entry->children.push_back(std::move(entry1)); } } else { - EachDefinedEntity(m->db->vars, def->vars, [&](QueryVar& var) { + EachDefinedEntity(m->db->usr2var, def->vars, [&](QueryVar& var) { DoField(m, entry, var, qualified, levels - 1); }); } @@ -162,43 +168,48 @@ struct Handler_CclsMemberHierarchy : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional BuildInitial(QueryFuncId root_id, - bool qualified, - int levels) { - const auto* def = db->funcs[root_id.id].AnyDef(); - if (!def) + std::optional BuildInitial(SymbolKind kind, + Usr root_usr, + bool qualified, + int levels) { + switch (kind) { + default: return {}; + case SymbolKind::Func: { + const auto* def = db->Func(root_usr).AnyDef(); + if (!def) + return {}; - Out_CclsMemberHierarchy::Entry entry; - // Not type, |id| is invalid. - entry.name = std::string(def->Name(qualified)); - if (def->spell) { - if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) - entry.location = *loc; + Out_CclsMemberHierarchy::Entry entry; + // Not type, |id| is invalid. + entry.name = std::string(def->Name(qualified)); + if (def->spell) { + if (std::optional loc = + GetLsLocation(db, working_files, *def->spell)) + entry.location = *loc; + } + EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) { + DoField(this, &entry, var, qualified, levels - 1); + }); + return entry; } - EachDefinedEntity(db->vars, def->vars, [&](QueryVar& var) { - DoField(this, &entry, var, qualified, levels - 1); - }); - return entry; - } + case SymbolKind::Type: { + const auto* def = db->Type(root_usr).AnyDef(); + if (!def) + return {}; - std::optional BuildInitial(QueryTypeId root_id, - bool qualified, - int levels) { - const auto* def = db->types[root_id.id].AnyDef(); - if (!def) - return {}; - - Out_CclsMemberHierarchy::Entry entry; - entry.id = root_id; - if (def->spell) { - if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) - entry.location = *loc; + Out_CclsMemberHierarchy::Entry entry; + entry.id = std::to_string(root_usr); + entry.usr = root_usr; + if (def->spell) { + if (std::optional loc = + GetLsLocation(db, working_files, *def->spell)) + entry.location = *loc; + } + Expand(this, &entry, qualified, levels); + return entry; + } } - Expand(this, &entry, qualified, levels); - return entry; } void Run(In_CclsMemberHierarchy* request) override { @@ -206,11 +217,17 @@ struct Handler_CclsMemberHierarchy Out_CclsMemberHierarchy out; out.id = request->id; - if (params.id) { + if (params.id.size()) { + try { + params.usr = std::stoull(params.id); + } catch (...) { + return; + } Out_CclsMemberHierarchy::Entry entry; - entry.id = *request->params.id; + entry.id = std::to_string(params.usr); + entry.usr = params.usr; // entry.name is empty as it is known by the client. - if (entry.id.id < db->types.size() && + if (db->usr2type.count(entry.usr) && Expand(this, &entry, params.qualified, params.levels)) out.result = std::move(entry); } else { @@ -224,17 +241,14 @@ struct Handler_CclsMemberHierarchy FindSymbolsAtLocation(wfile, file, params.position)) { switch (sym.kind) { case SymbolKind::Func: - out.result = BuildInitial(QueryFuncId(sym.id), params.qualified, - params.levels); - break; case SymbolKind::Type: - out.result = BuildInitial(QueryTypeId(sym.id), params.qualified, + out.result = BuildInitial(sym.kind, sym.usr, params.qualified, params.levels); break; case SymbolKind::Var: { const QueryVar::Def* def = db->GetVar(sym).AnyDef(); if (def && def->type) - out.result = BuildInitial(QueryTypeId(*def->type), + out.result = BuildInitial(SymbolKind::Type, def->type, params.qualified, params.levels); break; } diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index 80f1e85a2..3a32f6efb 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -6,7 +6,7 @@ #include #include -MAKE_HASHABLE(SymbolIdx, t.kind, t.id); +MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); namespace { MethodType kMethodType = "$ccls/random"; @@ -20,29 +20,14 @@ REGISTER_IN_MESSAGE(In_CclsRandom); const double kDeclWeight = 3; const double kDamping = 0.1; -template -struct Kind; -template <> -struct Kind { - static constexpr SymbolKind value = SymbolKind::Func; -}; -template <> -struct Kind { - static constexpr SymbolKind value = SymbolKind::Type; -}; -template <> -struct Kind { - static constexpr SymbolKind value = SymbolKind::Var; -}; - -template +template void Add(const std::unordered_map& sym2id, std::vector>& adj, - const std::vector>& ids, + const std::vector& collection, int n, double w = 1) { - for (Id id : ids) { - auto it = sym2id.find(SymbolIdx{id, Kind::value}); + for (Usr usr : collection) { + auto it = sym2id.find(SymbolIdx{usr, Q}); if (it != sym2id.end()) adj[it->second][n] += w; } @@ -56,19 +41,19 @@ struct Handler_CclsRandom : BaseMessageHandler { std::vector syms; int n = 0; - for (RawId i = 0; i < db->funcs.size(); i++) - if (db->funcs[i].AnyDef()) { - syms.push_back(SymbolIdx{Id(i), SymbolKind::Func}); + for (auto& it : db->usr2func) + if (it.second.AnyDef()) { + syms.push_back(SymbolIdx{it.first, SymbolKind::Func}); sym2id[syms.back()] = n++; } - for (RawId i = 0; i < db->types.size(); i++) - if (db->types[i].AnyDef()) { - syms.push_back(SymbolIdx{Id(i), SymbolKind::Type}); + for (auto& it : db->usr2type) + if (it.second.AnyDef()) { + syms.push_back(SymbolIdx{it.first, SymbolKind::Type}); sym2id[syms.back()] = n++; } - for (RawId i = 0; i < db->vars.size(); i++) - if (db->vars[i].AnyDef()) { - syms.push_back(SymbolIdx{Id(i), SymbolKind::Var}); + for (auto& it : db->usr2var) + if (it.second.AnyDef()) { + syms.push_back(SymbolIdx{it.first, SymbolKind::Var}); sym2id[syms.back()] = n++; } @@ -81,26 +66,26 @@ struct Handler_CclsRandom : BaseMessageHandler { } }; n = 0; - for (QueryFunc& func : db->funcs) - if (func.AnyDef()) { - add(func.declarations, kDeclWeight); - add(func.uses, 1); - Add(sym2id, adj, func.derived, n); + for (auto& it : db->usr2func) + if (it.second.AnyDef()) { + add(it.second.declarations, kDeclWeight); + add(it.second.uses, 1); + Add(sym2id, adj, it.second.derived, n); n++; } - for (QueryType& type : db->types) - if (const auto* def = type.AnyDef()) { - add(type.uses, 1); - Add(sym2id, adj, type.instances, n); - Add(sym2id, adj, def->funcs, n); - Add(sym2id, adj, def->types, n); - Add(sym2id, adj, def->vars, n); + for (auto& it : db->usr2type) + if (const auto* def = it.second.AnyDef()) { + add(it.second.uses, 1); + Add(sym2id, adj, it.second.instances, n); + Add(sym2id, adj, def->funcs, n); + Add(sym2id, adj, def->types, n); + Add(sym2id, adj, def->vars, n); n++; } - for (QueryVar& var : db->vars) - if (var.AnyDef()) { - add(var.declarations, kDeclWeight); - add(var.uses, 1); + for (auto& it : db->usr2var) + if (it.second.AnyDef()) { + add(it.second.declarations, kDeclWeight); + add(it.second.uses, 1); n++; } for (int i = 0; i < n; i++) { diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index a19803c56..90575b905 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -30,7 +30,7 @@ struct Handler_CclsVars : BaseMessageHandler { out.id = request->id; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { - Id id = sym.id; + Usr usr = sym.usr; switch (sym.kind) { default: break; @@ -38,15 +38,14 @@ struct Handler_CclsVars : BaseMessageHandler { const QueryVar::Def* def = db->GetVar(sym).AnyDef(); if (!def || !def->type) continue; - id = *def->type; + usr = def->type; + [[fallthrough]]; } - // fallthrough - case SymbolKind::Type: { - QueryType& type = db->types[id.id]; - out.result = GetLsLocationExs(db, working_files, - GetDeclarations(db, type.instances)); + case SymbolKind::Type: + out.result = GetLsLocationExs( + db, working_files, + GetDeclarations(db->usr2var, db->Type(usr).instances)); break; - } } } QueueManager::WriteStdout(kMethodType, out); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 8ee38d91f..7c8687f77 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -521,7 +521,7 @@ struct Handler_Initialize : BaseMessageHandler { std::thread([=]() { SetThreadName("indexer" + std::to_string(i)); Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, - import_manager, import_pipeline_status, project, + import_pipeline_status, project, working_files, waiter); }).detach(); } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 3251e3f21..2ac395c9e 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -50,12 +50,12 @@ void AddCodeLens(const char* singular, std::optional range = GetLsRange(common->working_file, use.range); if (!range) return; - if (use.file == QueryFileId()) + if (use.file_id < 0) return; code_lens.range = *range; code_lens.command = lsCommand(); code_lens.command->command = "ccls.showReferences"; - code_lens.command->arguments.uri = GetLsDocumentUri(common->db, use.file); + code_lens.command->arguments.uri = GetLsDocumentUri(common->db, use.file_id); code_lens.command->arguments.position = code_lens.range.start; // Add unique uses. @@ -106,7 +106,7 @@ struct Handler_TextDocumentCodeLens for (SymbolRef sym : file->def->outline) { // NOTE: We OffsetColumn so that the code lens always show up in a // predictable order. Otherwise, the client may randomize it. - Use use(sym.range, sym.id, sym.kind, sym.role, file->def->file); + Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id}; switch (sym.kind) { case SymbolKind::Type: { @@ -117,10 +117,10 @@ struct Handler_TextDocumentCodeLens AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), type.uses, true /*force_display*/); AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), - GetDeclarations(db, type.derived), + GetDeclarations(db->usr2type, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetDeclarations(db, type.instances), + GetDeclarations(db->usr2var, type.instances), false /*force_display*/); break; } @@ -165,9 +165,10 @@ struct Handler_TextDocumentCodeLens false /*force_display*/); } - AddCodeLens( - "derived", "derived", &common, OffsetStartColumn(use, offset++), - GetDeclarations(db, func.derived), false /*force_display*/); + AddCodeLens("derived", "derived", &common, + OffsetStartColumn(use, offset++), + GetDeclarations(db->usr2func, func.derived), + false /*force_display*/); // "Base" if (def->bases.size() == 1) { @@ -194,7 +195,7 @@ struct Handler_TextDocumentCodeLens } } else { AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), - GetDeclarations(db, def->bases), + GetDeclarations(db->usr2type, def->bases), false /*force_display*/); } diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 8a7590a2f..103436d19 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -33,7 +33,7 @@ std::vector GetNonDefDeclarationTargets(QueryDatabase* db, SymbolRef sym) { for (auto& def : db->GetVar(sym).def) if (def.type) { if (Maybe use = GetDefinitionSpell( - db, SymbolIdx{*def.type, SymbolKind::Type})) { + db, SymbolIdx{def.type, SymbolKind::Type})) { ret.push_back(*use); break; } @@ -51,7 +51,7 @@ struct Handler_TextDocumentDefinition MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDefinition* request) override { auto& params = request->params; - QueryFileId file_id; + int file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file, &file_id)) @@ -79,7 +79,7 @@ struct Handler_TextDocumentDefinition if (def.spell && def.extent) { Use spell = *def.spell; // If on a definition, clear |uses| to find declarations below. - if (spell.file == file_id && + if (spell.file_id == file_id && spell.range.Contains(ls_pos.line, ls_pos.character)) { on_def = spell; uses.clear(); @@ -148,7 +148,7 @@ struct Handler_TextDocumentDefinition if (Maybe use = GetDefinitionSpell(db, db->symbols[i])) { std::tuple score{ int(name.size() - short_query.size()), 0, - use->file != file_id, + use->file_id != file_id, std::abs(use->range.start.line - position.line)}; // Update the score with qualified name if the qualified name // occurs in |name|. diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index e3b1e4c65..643ef8599 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -24,7 +24,7 @@ struct Handler_TextDocumentDocumentHighlight : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDocumentHighlight* request) override { - QueryFileId file_id; + int file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, @@ -42,7 +42,7 @@ struct Handler_TextDocumentDocumentHighlight FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references to highlight. EachOccurrence(db, sym, true, [&](Use use) { - if (use.file != file_id) + if (use.file_id != file_id) return; if (std::optional ls_loc = GetLsLocation(db, working_files, use)) { diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index b3461029b..29071eb7c 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -32,7 +32,7 @@ struct Handler_TextDocumentDocumentSymbol out.id = request->id; QueryFile* file; - QueryFileId file_id; + int file_id; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, &file_id)) { @@ -58,7 +58,7 @@ struct Handler_TextDocumentDocumentSymbol if (std::optional location = GetLsLocation( db, working_files, - Use(sym.range, sym.id, sym.kind, sym.role, file_id))) { + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { info->location = *location; out.result.push_back(*info); } diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index 6dc26450b..a3301998f 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -9,18 +9,18 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, SymbolRef sym, const std::string& new_text) { - std::unordered_map path_to_edit; + std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { std::optional ls_location = GetLsLocation(db, working_files, use); if (!ls_location) return; - QueryFileId file_id = use.file; + int file_id = use.file_id; if (path_to_edit.find(file_id) == path_to_edit.end()) { path_to_edit[file_id] = lsTextDocumentEdit(); - QueryFile& file = db->files[file_id.id]; + QueryFile& file = db->files[file_id]; if (!file.def) return; @@ -80,7 +80,7 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result); struct Handler_TextDocumentRename : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentRename* request) override { - QueryFileId file_id; + int file_id; QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 738636e6d..4a31cde21 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -36,17 +36,17 @@ struct Handler_TextDocumentTypeDefinition out.id = request->id; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { - Id id = sym.id; + Usr usr = sym.usr; switch (sym.kind) { case SymbolKind::Var: { const QueryVar::Def* def = db->GetVar(sym).AnyDef(); if (!def || !def->type) continue; - id = *def->type; + usr = def->type; + [[fallthrough]]; } - // fallthrough case SymbolKind::Type: { - QueryType& type = db->types[id.id]; + QueryType& type = db->Type(usr); for (const auto& def : type.def) if (def.spell) { if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, diff --git a/src/performance.h b/src/performance.h index 56c348803..e79b810ab 100644 --- a/src/performance.h +++ b/src/performance.h @@ -13,8 +13,6 @@ struct PerformanceImportFile { uint64_t index_parse = 0; // [indexer] build the IndexFile object from clang parse uint64_t index_build = 0; - // [querydb] create IdMap object from IndexFile - uint64_t querydb_id_map = 0; // [indexer] save the IndexFile to disk uint64_t index_save_to_disk = 0; // [indexer] loading previously cached index @@ -29,7 +27,6 @@ struct PerformanceImportFile { MAKE_REFLECT_STRUCT(PerformanceImportFile, index_parse, index_build, - querydb_id_map, index_save_to_disk, index_load_cached, - index_make_delta); \ No newline at end of file + index_make_delta); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index aba1b7f0f..6d8f59367 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -176,8 +176,9 @@ void TraceMe() { // If the environment variable is defined, wait for a debugger. // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. - if (getenv("CCLS_TRACEME")) - raise(SIGSTOP); + const char* traceme = getenv("CCLS_TRACEME"); + if (traceme) + raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } std::string GetExternalCommandOutput(const std::vector& command, diff --git a/src/query.cc b/src/query.cc index 093d2b401..cc7058907 100644 --- a/src/query.cc +++ b/src/query.cc @@ -22,12 +22,12 @@ MAKE_HASHABLE(Range, t.start, t.end); MAKE_HASHABLE(Use, t.range); -template -void Reflect(TVisitor& visitor, MergeableUpdate& value) { +template +void Reflect(TVisitor& visitor, MergeableUpdate& value) { REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(to_add); + REFLECT_MEMBER(usr); REFLECT_MEMBER(to_remove); + REFLECT_MEMBER(to_add); REFLECT_MEMBER_END(); } @@ -67,124 +67,53 @@ MAKE_REFLECT_STRUCT(IndexUpdate, namespace { -template -void AddRange(std::vector* dest, const std::vector& to_add) { - dest->insert(dest->end(), to_add.begin(), to_add.end()); +void AssignFileId(int file_id, SymbolRef& ref) { + if (ref.kind == SymbolKind::File) + ref.usr = file_id; } -template -void AddRange(std::vector* dest, std::vector&& to_add) { - dest->insert(dest->end(), std::make_move_iterator(to_add.begin()), - std::make_move_iterator(to_add.end())); +void AssignFileId(int file_id, Use& use) { + if (use.kind == SymbolKind::File) + use.usr = file_id; + use.file_id = file_id; } template -void RemoveRange(std::vector* dest, const std::vector& to_remove) { - std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); - dest->erase( - std::remove_if(dest->begin(), dest->end(), - [&](const T& t) { return to_remove_set.count(t) > 0; }), - dest->end()); +void AssignFileId(int file_id, T&) {} + +template +void AssignFileId(int file_id, Maybe& x) { + if (x) + AssignFileId(file_id, *x); } -std::optional ToQuery(const IdMap& id_map, - const IndexType::Def& type) { - if (type.detailed_name.empty()) - return std::nullopt; - - QueryType::Def result; - result.detailed_name = type.detailed_name; - result.qual_name_offset = type.qual_name_offset; - result.short_name_offset = type.short_name_offset; - result.short_name_size = type.short_name_size; - result.kind = type.kind; - if (!type.hover.empty()) - result.hover = type.hover; - if (!type.comments.empty()) - result.comments = type.comments; - result.file = id_map.primary_file; - result.spell = id_map.ToQuery(type.spell); - result.extent = id_map.ToQuery(type.extent); - result.alias_of = id_map.ToQuery(type.alias_of); - result.bases = id_map.ToQuery(type.bases); - result.types = id_map.ToQuery(type.types); - result.funcs = id_map.ToQuery(type.funcs); - result.vars = id_map.ToQuery(type.vars); - return result; +template +void AssignFileId(int file_id, std::vector& xs) { + for (T& x : xs) + AssignFileId(file_id, x); } -std::optional ToQuery(const IdMap& id_map, - const IndexFunc::Def& func) { - if (func.detailed_name.empty()) - return std::nullopt; - - QueryFunc::Def result; - result.detailed_name = func.detailed_name; - result.qual_name_offset = func.qual_name_offset; - result.short_name_offset = func.short_name_offset; - result.short_name_size = func.short_name_size; - result.kind = func.kind; - result.storage = func.storage; - if (!func.hover.empty()) - result.hover = func.hover; - if (!func.comments.empty()) - result.comments = func.comments; - result.file = id_map.primary_file; - result.spell = id_map.ToQuery(func.spell); - result.extent = id_map.ToQuery(func.extent); - result.declaring_type = id_map.ToQuery(func.declaring_type); - result.bases = id_map.ToQuery(func.bases); - result.vars = id_map.ToQuery(func.vars); - result.callees = id_map.ToQuery(func.callees); - return result; + +void AddRange(int file_id, std::vector& into, const std::vector& from) { + into.reserve(into.size() + from.size()); + for (Use use : from) { + use.file_id = file_id; + into.push_back(use); + } } -std::optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { - if (var.detailed_name.empty()) - return std::nullopt; - - QueryVar::Def result; - result.detailed_name = var.detailed_name; - result.qual_name_offset = var.qual_name_offset; - result.short_name_offset = var.short_name_offset; - result.short_name_size = var.short_name_size; - if (!var.hover.empty()) - result.hover = var.hover; - if (!var.comments.empty()) - result.comments = var.comments; - result.file = id_map.primary_file; - result.spell = id_map.ToQuery(var.spell); - result.extent = id_map.ToQuery(var.extent); - result.type = id_map.ToQuery(var.type); - result.kind = var.kind; - result.storage = var.storage; - return result; +void AddRange(int _, std::vector& into, const std::vector& from) { + into.insert(into.end(), from.begin(), from.end()); } -// Adds the mergeable updates in |source| to |dest|. If a mergeable update for -// the destination type already exists, it will be combined. This makes merging -// updates take longer but reduces import time on the querydb thread. -template -void AddMergeableRange(std::vector>* dest, - std::vector>&& source) { - // TODO: Consider caching the lookup table. It can probably save even more - // time at the cost of some additional memory. - - // Build lookup table. - spp::sparse_hash_map id_to_index; - id_to_index.resize(dest->size()); - for (size_t i = 0; i < dest->size(); ++i) - id_to_index[(*dest)[i].id] = i; - - // Add entries. Try to add them to an existing entry. - for (auto& entry : source) { - auto it = id_to_index.find(entry.id); - if (it != id_to_index.end()) { - AddRange(&(*dest)[it->second].to_add, std::move(entry.to_add)); - AddRange(&(*dest)[it->second].to_remove, std::move(entry.to_remove)); - } else { - dest->push_back(std::move(entry)); - } +template +void RemoveRange(std::vector& dest, const std::vector& to_remove) { + if (to_remove.size()) { + std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); + dest.erase( + std::remove_if(dest.begin(), dest.end(), + [&](const T& t) { return to_remove_set.count(t) > 0; }), + dest.end()); } } @@ -194,8 +123,8 @@ void AddMergeableRange(std::vector>* dest, // // Returns true iff |removed| or |added| are non-empty. template -bool ComputeDifferenceForUpdate(std::vector&& previous, - std::vector&& current, +bool ComputeDifferenceForUpdate(std::vector previous, + std::vector current, std::vector* removed, std::vector* added) { // We need to sort to use std::set_difference. @@ -222,54 +151,25 @@ bool ComputeDifferenceForUpdate(std::vector&& previous, } template -void CompareGroups(std::vector& previous_data, - std::vector& current_data, - std::function on_removed, - std::function on_added, - std::function on_found) { - std::sort(previous_data.begin(), previous_data.end()); - std::sort(current_data.begin(), current_data.end()); - - auto prev_it = previous_data.begin(); - auto curr_it = current_data.begin(); - while (prev_it != previous_data.end() && curr_it != current_data.end()) { - // same id - if (prev_it->usr == curr_it->usr) { - on_found(&*prev_it, &*curr_it); - ++prev_it; - ++curr_it; - } - - // prev_id is smaller - prev_it has data curr_it does not have. - else if (prev_it->usr < curr_it->usr) { - on_removed(&*prev_it); - ++prev_it; - } - - // prev_id is bigger - curr_it has data prev_it does not have. - else { - on_added(&*curr_it); - ++curr_it; - } - } - - // if prev_it still has data, that means it is not in curr_it and was removed. - while (prev_it != previous_data.end()) { - on_removed(&*prev_it); - ++prev_it; - } - - // if curr_it still has data, that means it is not in prev_it and was added. - while (curr_it != current_data.end()) { - on_added(&*curr_it); - ++curr_it; +void CompareGroups(std::unordered_map& prev, + std::unordered_map& curr, + std::function on_remove, + std::function on_add, + std::function on_found) { + for (auto& it : prev) { + auto it1 = curr.find(it.first); + if (it1 != curr.end()) + on_found(it.second, it1->second); + else + on_remove(it.second); } + for (auto& it : curr) + if (!prev.count(it.first)) + on_add(it.second); } -QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, - const IndexFile& indexed) { +QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { QueryFile::Def def; - def.file = id_map.primary_file; def.path = indexed.path; def.args = indexed.args; def.includes = indexed.includes; @@ -292,38 +192,38 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, } }(); - auto add_all_symbols = [&](Use use, Id id, SymbolKind kind) { - def.all_symbols.push_back(SymbolRef(use.range, id, kind, use.role)); + auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { + def.all_symbols.push_back(SymbolRef(use.range, usr, kind, use.role)); }; - auto add_outline = [&](Use use, Id id, SymbolKind kind) { - def.outline.push_back(SymbolRef(use.range, id, kind, use.role)); + auto add_outline = [&](Use use, Usr usr, SymbolKind kind) { + def.outline.push_back(SymbolRef(use.range, usr, kind, use.role)); }; - for (const IndexType& type : indexed.types) { - QueryTypeId id = id_map.ToQuery(type.id); + for (auto& it : indexed.usr2type) { + const IndexType& type = it.second; if (type.def.spell) - add_all_symbols(*type.def.spell, id, SymbolKind::Type); + add_all_symbols(*type.def.spell, type.usr, SymbolKind::Type); if (type.def.extent) - add_outline(*type.def.extent, id, SymbolKind::Type); + add_outline(*type.def.extent, type.usr, SymbolKind::Type); for (Use decl : type.declarations) { - add_all_symbols(decl, id, SymbolKind::Type); + add_all_symbols(decl, type.usr, SymbolKind::Type); // Constructor positions have references to the class, // which we do not want to show in textDocument/documentSymbol if (!(decl.role & Role::Reference)) - add_outline(decl, id, SymbolKind::Type); + add_outline(decl, type.usr, SymbolKind::Type); } for (Use use : type.uses) - add_all_symbols(use, id, SymbolKind::Type); + add_all_symbols(use, type.usr, SymbolKind::Type); } - for (const IndexFunc& func : indexed.funcs) { - QueryFuncId id = id_map.ToQuery(func.id); + for (auto& it: indexed.usr2func) { + const IndexFunc& func = it.second; if (func.def.spell) - add_all_symbols(*func.def.spell, id, SymbolKind::Func); + add_all_symbols(*func.def.spell, func.usr, SymbolKind::Func); if (func.def.extent) - add_outline(*func.def.extent, id, SymbolKind::Func); - for (const IndexFunc::Declaration& decl : func.declarations) { - add_all_symbols(decl.spell, id, SymbolKind::Func); - add_outline(decl.spell, id, SymbolKind::Func); + add_outline(*func.def.extent, func.usr, SymbolKind::Func); + for (Use use : func.declarations) { + add_all_symbols(use, func.usr, SymbolKind::Func); + add_outline(use, func.usr, SymbolKind::Func); } for (Use use : func.uses) { // Make ranges of implicit function calls larger (spanning one more column @@ -335,21 +235,21 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, use.range.start.column--; use.range.end.column++; } - add_all_symbols(use, id, SymbolKind::Func); + add_all_symbols(use, func.usr, SymbolKind::Func); } } - for (const IndexVar& var : indexed.vars) { - QueryVarId id = id_map.ToQuery(var.id); + for (auto& it : indexed.usr2var) { + const IndexVar& var = it.second; if (var.def.spell) - add_all_symbols(*var.def.spell, id, SymbolKind::Var); + add_all_symbols(*var.def.spell, var.usr, SymbolKind::Var); if (var.def.extent) - add_outline(*var.def.extent, id, SymbolKind::Var); + add_outline(*var.def.extent, var.usr, SymbolKind::Var); for (Use decl : var.declarations) { - add_all_symbols(decl, id, SymbolKind::Var); - add_outline(decl, id, SymbolKind::Var); + add_all_symbols(decl, var.usr, SymbolKind::Var); + add_outline(decl, var.usr, SymbolKind::Var); } for (Use use : var.uses) - add_all_symbols(use, id, SymbolKind::Var); + add_all_symbols(use, var.usr, SymbolKind::Var); } std::sort(def.outline.begin(), def.outline.end(), @@ -364,74 +264,14 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, return QueryFile::DefUpdate(def, indexed.file_contents); } -Maybe GetQueryFileIdFromPath(QueryDatabase* query_db, - const std::string& path, - bool create_if_missing) { - std::string normalized_path = LowerPathIfInsensitive(path); - auto it = query_db->usr_to_file.find(normalized_path); - if (it != query_db->usr_to_file.end()) - return QueryFileId(it->second.id); - if (!create_if_missing) - return {}; - - RawId idx = query_db->files.size(); - query_db->usr_to_file[normalized_path] = QueryFileId(idx); - query_db->files.push_back(QueryFile(path)); - return QueryFileId(idx); -} - -Maybe GetQueryTypeIdFromUsr(QueryDatabase* query_db, - Usr usr, - bool create_if_missing) { - auto it = query_db->usr_to_type.find(usr); - if (it != query_db->usr_to_type.end()) - return QueryTypeId(it->second.id); - if (!create_if_missing) - return {}; - - RawId idx = query_db->types.size(); - query_db->usr_to_type[usr] = QueryTypeId(idx); - query_db->types.push_back(QueryType(usr)); - return QueryTypeId(idx); -} - -Maybe GetQueryFuncIdFromUsr(QueryDatabase* query_db, - Usr usr, - bool create_if_missing) { - auto it = query_db->usr_to_func.find(usr); - if (it != query_db->usr_to_func.end()) - return QueryFuncId(it->second.id); - if (!create_if_missing) - return {}; - - RawId idx = query_db->funcs.size(); - query_db->usr_to_func[usr] = QueryFuncId(idx); - query_db->funcs.push_back(QueryFunc(usr)); - return QueryFuncId(idx); -} - -Maybe GetQueryVarIdFromUsr(QueryDatabase* query_db, - Usr usr, - bool create_if_missing) { - auto it = query_db->usr_to_var.find(usr); - if (it != query_db->usr_to_var.end()) - return QueryVarId(it->second.id); - if (!create_if_missing) - return {}; - - RawId idx = query_db->vars.size(); - query_db->usr_to_var[usr] = QueryVarId(idx); - query_db->vars.push_back(QueryVar(usr)); - return QueryVarId(idx); -} - // Returns true if an element with the same file is found. template bool TryReplaceDef(std::forward_list& def_list, Q&& def) { for (auto& def1 : def_list) - if (def1.file == def.file) { - if (!def1.spell || def.spell) + if (def1.file_id == def.file_id) { + if (!def1.spell || def.spell) { def1 = std::move(def); + } return true; } return false; @@ -439,347 +279,147 @@ bool TryReplaceDef(std::forward_list& def_list, Q&& def) { } // namespace -Maybe QueryDatabase::GetQueryFileIdFromPath( - const std::string& path) { - return ::GetQueryFileIdFromPath(this, path, false); -} - -Maybe QueryDatabase::GetQueryTypeIdFromUsr(Usr usr) { - return ::GetQueryTypeIdFromUsr(this, usr, false); -} - -Maybe QueryDatabase::GetQueryFuncIdFromUsr(Usr usr) { - return ::GetQueryFuncIdFromUsr(this, usr, false); -} - -Maybe QueryDatabase::GetQueryVarIdFromUsr(Usr usr) { - return ::GetQueryVarIdFromUsr(this, usr, false); -} - -IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids) - : local_ids{local_ids} { - // LOG_S(INFO) << "Creating IdMap for " << local_ids.primary_file; - primary_file = - *GetQueryFileIdFromPath(query_db, local_ids.primary_file, true); - - cached_type_ids_.resize(local_ids.type_id_to_usr.size()); - for (const auto& entry : local_ids.type_id_to_usr) - cached_type_ids_[entry.first] = - *GetQueryTypeIdFromUsr(query_db, entry.second, true); - - cached_func_ids_.resize(local_ids.func_id_to_usr.size()); - for (const auto& entry : local_ids.func_id_to_usr) - cached_func_ids_[entry.first] = - *GetQueryFuncIdFromUsr(query_db, entry.second, true); - - cached_var_ids_.resize(local_ids.var_id_to_usr.size()); - for (const auto& entry : local_ids.var_id_to_usr) - cached_var_ids_[entry.first] = - *GetQueryVarIdFromUsr(query_db, entry.second, true); -} - -QueryTypeId IdMap::ToQuery(IndexTypeId id) const { - assert(cached_type_ids_.find(id) != cached_type_ids_.end()); - return QueryTypeId(cached_type_ids_.find(id)->second); -} -QueryFuncId IdMap::ToQuery(IndexFuncId id) const { - assert(cached_func_ids_.find(id) != cached_func_ids_.end()); - return QueryFuncId(cached_func_ids_.find(id)->second); -} -QueryVarId IdMap::ToQuery(IndexVarId id) const { - assert(cached_var_ids_.find(id) != cached_var_ids_.end()); - return QueryVarId(cached_var_ids_.find(id)->second); -} - -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; - } - return ret; -} -SymbolRef IdMap::ToQuery(SymbolRef ref) const { - ref.Reference::operator=(ToQuery(static_cast(ref))); - return ref; -} -Use IdMap::ToQuery(Use use) const { - return ToQuery(static_cast(use)); -} - -Use IdMap::ToQuery(IndexFunc::Declaration decl) const { - return ToQuery(static_cast(decl.spell)); -} - // ---------------------- // INDEX THREAD FUNCTIONS // ---------------------- // static -IndexUpdate IndexUpdate::CreateDelta(const IdMap* previous_id_map, - const IdMap* current_id_map, - IndexFile* previous, +IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, IndexFile* current) { - // This function runs on an indexer thread. - - if (!previous_id_map) { - assert(!previous); - IndexFile empty(current->path, ""); - return IndexUpdate(*current_id_map, *current_id_map, empty, *current); - } - return IndexUpdate(*previous_id_map, *current_id_map, *previous, *current); -} - -IndexUpdate::IndexUpdate(const IdMap& previous_id_map, - const IdMap& current_id_map, - IndexFile& previous_file, - IndexFile& current_file) { -// This function runs on an indexer thread. + IndexUpdate r; + static IndexFile empty(current->path, ""); + if (!previous) + previous = ∅ // |query_name| is the name of the variable on the query type. // |index_name| is the name of the variable on the index type. // |type| is the type of the variable. -#define PROCESS_UPDATE_DIFF(type_id, query_name, index_name, type) \ - { \ - /* Check for changes. */ \ - std::vector removed, added; \ - auto query_previous = previous_id_map.ToQuery(previous->index_name); \ - auto query_current = current_id_map.ToQuery(current->index_name); \ - bool did_add = ComputeDifferenceForUpdate(std::move(query_previous), \ - std::move(query_current), \ - &removed, &added); \ - if (did_add) { \ - query_name.push_back(MergeableUpdate( \ - current_id_map.ToQuery(current->id), std::move(added), \ - std::move(removed))); \ - } \ +#define PROCESS_DIFF(type_id, query_name, index_name, type) \ + { \ + /* Check for changes. */ \ + std::vector removed, added; \ + bool did_add = ComputeDifferenceForUpdate( \ + prev.index_name, curr.index_name, &removed, &added); \ + if (did_add) { \ + r.query_name.push_back(MergeableUpdate( \ + curr.usr, std::move(removed), std::move(added))); \ + } \ } // File - files_def_update.push_back(BuildFileDefUpdate(current_id_map, current_file)); + r.files_def_update = BuildFileDefUpdate(*current); // **NOTE** We only remove entries if they were defined in the previous index. // For example, if a type is included from another file it will be defined // simply so we can attribute the usage/reference to it. If the reference goes // away we don't want to remove the type/func/var usage. - // Types - CompareGroups( - previous_file.types, current_file.types, + // Functions + CompareGroups( + previous->usr2func, current->usr2func, /*onRemoved:*/ - [this, &previous_id_map](IndexType* type) { - if (type->def.spell) - types_removed.push_back(type->usr); - if (!type->declarations.empty()) - types_declarations.push_back(QueryType::DeclarationsUpdate( - 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))); - if (!type->instances.empty()) - types_instances.push_back(QueryType::InstancesUpdate( - previous_id_map.ToQuery(type->id), {}, - previous_id_map.ToQuery(type->instances))); - if (!type->uses.empty()) - types_uses.push_back( - QueryType::UsesUpdate(previous_id_map.ToQuery(type->id), {}, - previous_id_map.ToQuery(type->uses))); + [&r](IndexFunc& func) { + if (func.def.spell) + r.funcs_removed.push_back(func.usr); + if (func.declarations.size()) + r.funcs_declarations.push_back(UseUpdate{func.usr, func.declarations, {}}); + if (func.uses.size()) + r.funcs_uses.push_back(UseUpdate{func.usr, func.uses, {}}); + if (func.derived.size()) + r.funcs_derived.push_back(UsrUpdate{func.usr, func.derived, {}}); }, /*onAdded:*/ - [this, ¤t_id_map](IndexType* type) { - std::optional def_update = - ToQuery(current_id_map, type->def); - if (def_update) - types_def_update.push_back( - QueryType::DefUpdate(type->usr, std::move(*def_update))); - if (!type->declarations.empty()) - types_declarations.push_back(QueryType::DeclarationsUpdate( - current_id_map.ToQuery(type->id), - current_id_map.ToQuery(type->declarations))); - if (!type->derived.empty()) - types_derived.push_back( - QueryType::DerivedUpdate(current_id_map.ToQuery(type->id), - current_id_map.ToQuery(type->derived))); - if (!type->instances.empty()) - types_instances.push_back(QueryType::InstancesUpdate( - current_id_map.ToQuery(type->id), - current_id_map.ToQuery(type->instances))); - if (!type->uses.empty()) - types_uses.push_back( - QueryType::UsesUpdate(current_id_map.ToQuery(type->id), - current_id_map.ToQuery(type->uses))); + [&r](IndexFunc& func) { + if (func.def.detailed_name.size()) + r.funcs_def_update.emplace_back(func.usr, func.def); + if (func.declarations.size()) + r.funcs_declarations.push_back(UseUpdate{func.usr, {}, func.declarations}); + if (func.uses.size()) + r.funcs_uses.push_back(UseUpdate{func.usr, {}, func.uses}); + if (func.derived.size()) + r.funcs_derived.push_back(UsrUpdate{func.usr, {}, func.derived}); }, /*onFound:*/ - [this, &previous_id_map, ¤t_id_map](IndexType* previous, - IndexType* current) { - std::optional prev_remapped = - ToQuery(previous_id_map, previous->def); - std::optional current_remapped = - ToQuery(current_id_map, current->def); - if (current_remapped && - !(prev_remapped == current_remapped) && - !current_remapped->detailed_name.empty()) { - types_def_update.push_back(QueryType::DefUpdate( - current->usr, std::move(*current_remapped))); - } - - PROCESS_UPDATE_DIFF(QueryTypeId, types_declarations, declarations, Use); - PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId); - PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances, - QueryVarId); - PROCESS_UPDATE_DIFF(QueryTypeId, types_uses, uses, Use); + [&r](IndexFunc& prev, IndexFunc& curr) { + if (curr.def.detailed_name.size() && !(prev.def == curr.def)) + r.funcs_def_update.emplace_back(curr.usr, curr.def); + + PROCESS_DIFF(QueryFuncId, funcs_declarations, declarations, Use); + PROCESS_DIFF(QueryFuncId, funcs_uses, uses, Use); + PROCESS_DIFF(QueryFuncId, funcs_derived, derived, Usr); }); - // Functions - CompareGroups( - previous_file.funcs, current_file.funcs, + // Types + CompareGroups( + previous->usr2type, current->usr2type, /*onRemoved:*/ - [this, &previous_id_map](IndexFunc* func) { - if (func->def.spell) - funcs_removed.emplace_back(func->usr, previous_id_map.primary_file); - if (!func->declarations.empty()) - funcs_declarations.push_back(QueryFunc::DeclarationsUpdate( - 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))); - if (!func->uses.empty()) - funcs_uses.push_back( - QueryFunc::UsesUpdate(previous_id_map.ToQuery(func->id), {}, - previous_id_map.ToQuery(func->uses))); + [&r](IndexType& type) { + if (type.def.spell) + r.types_removed.push_back(type.usr); + if (type.declarations.size()) + r.types_declarations.push_back(UseUpdate{type.usr, type.declarations, {}}); + if (type.uses.size()) + r.types_uses.push_back(UseUpdate{type.usr, type.uses, {}}); + if (type.derived.size()) + r.types_derived.push_back(UsrUpdate{type.usr, type.derived, {}}); + if (type.instances.size()) + r.types_instances.push_back(UsrUpdate{type.usr, type.instances, {}}); }, /*onAdded:*/ - [this, ¤t_id_map](IndexFunc* func) { - std::optional def_update = - ToQuery(current_id_map, func->def); - if (def_update) - funcs_def_update.push_back( - QueryFunc::DefUpdate(func->usr, std::move(*def_update))); - if (!func->declarations.empty()) - funcs_declarations.push_back(QueryFunc::DeclarationsUpdate( - current_id_map.ToQuery(func->id), - current_id_map.ToQuery(func->declarations))); - if (!func->derived.empty()) - funcs_derived.push_back( - QueryFunc::DerivedUpdate(current_id_map.ToQuery(func->id), - current_id_map.ToQuery(func->derived))); - if (!func->uses.empty()) - funcs_uses.push_back( - QueryFunc::UsesUpdate(current_id_map.ToQuery(func->id), - current_id_map.ToQuery(func->uses))); + [&r](IndexType& type) { + if (type.def.detailed_name.size()) + r.types_def_update.emplace_back(type.usr, type.def); + if (type.declarations.size()) + r.types_declarations.push_back(UseUpdate{type.usr, {}, type.declarations}); + if (type.uses.size()) + r.types_uses.push_back(UseUpdate{type.usr, {}, type.uses}); + if (type.derived.size()) + r.types_derived.push_back(UsrUpdate{type.usr, {}, type.derived}); + if (type.instances.size()) + r.types_instances.push_back(UsrUpdate{type.usr, {}, type.instances}); }, /*onFound:*/ - [this, &previous_id_map, ¤t_id_map](IndexFunc* previous, - IndexFunc* current) { - std::optional prev_remapped = - ToQuery(previous_id_map, previous->def); - std::optional current_remapped = - ToQuery(current_id_map, current->def); - if (current_remapped && - !(prev_remapped == current_remapped) && - !current_remapped->detailed_name.empty()) { - funcs_def_update.push_back(QueryFunc::DefUpdate( - current->usr, std::move(*current_remapped))); - } - - PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, Use); - PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId); - PROCESS_UPDATE_DIFF(QueryFuncId, funcs_uses, uses, Use); + [&r](IndexType& prev, IndexType& curr) { + if (curr.def.detailed_name.size() && !(prev.def == curr.def)) + r.types_def_update.emplace_back(curr.usr, curr.def); + + PROCESS_DIFF(QueryTypeId, types_declarations, declarations, Use); + PROCESS_DIFF(QueryTypeId, types_uses, uses, Use); + PROCESS_DIFF(QueryTypeId, types_derived, derived, Usr); + PROCESS_DIFF(QueryTypeId, types_instances, instances, Usr); }); // Variables CompareGroups( - previous_file.vars, current_file.vars, + previous->usr2var, current->usr2var, /*onRemoved:*/ - [this, &previous_id_map](IndexVar* var) { - if (var->def.spell) - vars_removed.emplace_back(var->usr, previous_id_map.primary_file); - if (!var->declarations.empty()) - vars_declarations.push_back(QueryVar::DeclarationsUpdate( - previous_id_map.ToQuery(var->id), {}, - previous_id_map.ToQuery(var->declarations))); - if (!var->uses.empty()) - vars_uses.push_back( - QueryVar::UsesUpdate(previous_id_map.ToQuery(var->id), {}, - previous_id_map.ToQuery(var->uses))); + [&r](IndexVar& var) { + if (var.def.spell) + r.vars_removed.push_back(var.usr); + if (!var.declarations.empty()) + r.vars_declarations.push_back(UseUpdate{var.usr, var.declarations, {}}); + if (!var.uses.empty()) + r.vars_uses.push_back(UseUpdate{var.usr, var.uses, {}}); }, /*onAdded:*/ - [this, ¤t_id_map](IndexVar* var) { - std::optional def_update = ToQuery(current_id_map, var->def); - if (def_update) - vars_def_update.push_back( - QueryVar::DefUpdate(var->usr, std::move(*def_update))); - if (!var->declarations.empty()) - vars_declarations.push_back(QueryVar::DeclarationsUpdate( - current_id_map.ToQuery(var->id), - current_id_map.ToQuery(var->declarations))); - if (!var->uses.empty()) - vars_uses.push_back( - QueryVar::UsesUpdate(current_id_map.ToQuery(var->id), - current_id_map.ToQuery(var->uses))); + [&r](IndexVar& var) { + if (var.def.detailed_name.size()) + r.vars_def_update.emplace_back(var.usr, var.def); + if (var.declarations.size()) + r.vars_declarations.push_back(UseUpdate{var.usr, {}, var.declarations}); + if (var.uses.size()) + r.vars_uses.push_back(UseUpdate{var.usr, {}, var.uses}); }, /*onFound:*/ - [this, &previous_id_map, ¤t_id_map](IndexVar* previous, - IndexVar* current) { - std::optional prev_remapped = - ToQuery(previous_id_map, previous->def); - std::optional current_remapped = - ToQuery(current_id_map, current->def); - if (current_remapped && !(prev_remapped == current_remapped) && - !current_remapped->detailed_name.empty()) - vars_def_update.push_back( - QueryVar::DefUpdate(current->usr, std::move(*current_remapped))); - - PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, Use); - PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Use); - }); + [&r](IndexVar& prev, IndexVar& curr) { + if (curr.def.detailed_name.size() && !(prev.def == curr.def)) + r.vars_def_update.emplace_back(curr.usr, curr.def); -#undef PROCESS_UPDATE_DIFF -} + PROCESS_DIFF(QueryVarId, vars_declarations, declarations, Use); + PROCESS_DIFF(QueryVarId, vars_uses, uses, Use); + }); -// 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)); - - INDEX_UPDATE_APPEND(files_removed); - INDEX_UPDATE_APPEND(files_def_update); - - INDEX_UPDATE_APPEND(types_removed); - INDEX_UPDATE_APPEND(types_def_update); - INDEX_UPDATE_MERGE(types_derived); - INDEX_UPDATE_MERGE(types_instances); - INDEX_UPDATE_MERGE(types_uses); - - INDEX_UPDATE_APPEND(funcs_removed); - INDEX_UPDATE_APPEND(funcs_def_update); - INDEX_UPDATE_MERGE(funcs_declarations); - INDEX_UPDATE_MERGE(funcs_derived); - INDEX_UPDATE_MERGE(funcs_uses); - - INDEX_UPDATE_APPEND(vars_removed); - INDEX_UPDATE_APPEND(vars_def_update); - INDEX_UPDATE_MERGE(vars_declarations); - INDEX_UPDATE_MERGE(vars_uses); - -#undef INDEX_UPDATE_APPEND -#undef INDEX_UPDATE_MERGE + return r; +#undef PROCESS_DIFF } std::string IndexUpdate::ToString() { @@ -799,10 +439,10 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove) { switch (usr_kind) { case SymbolKind::Type: { - for (const Usr& usr : to_remove) { - QueryType& type = types[usr_to_type[usr].id]; - if (type.symbol_idx) - symbols[type.symbol_idx->id].kind = SymbolKind::Invalid; + for (Usr usr : to_remove) { + QueryType& type = usr2type[usr]; + if (type.symbol_idx >= 0) + symbols[type.symbol_idx].kind = SymbolKind::Invalid; type.def.clear(); } break; @@ -813,23 +453,24 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, } void QueryDatabase::RemoveUsrs( - SymbolKind usr_kind, - const std::vector>& to_remove) { - switch (usr_kind) { + SymbolKind kind, + int file_id, + const std::vector& to_remove) { + switch (kind) { case SymbolKind::Func: { - for (const auto& usr_file : to_remove) { - QueryFunc& func = funcs[usr_to_func[usr_file.usr].id]; - func.def.remove_if([&](const QueryFunc::Def& def) { - return def.file == usr_file.value; + for (auto usr : to_remove) { + QueryFunc& func = Func(usr); + func.def.remove_if([=](const QueryFunc::Def& def) { + return def.file_id == file_id; }); } break; } case SymbolKind::Var: { - for (const auto& usr_file : to_remove) { - QueryVar& var = vars[usr_to_var[usr_file.usr].id]; - var.def.remove_if([&](const QueryVar::Def& def) { - return def.file == usr_file.value; + for (auto usr : to_remove) { + QueryVar& var = Var(usr); + var.def.remove_if([=](const QueryVar::Def& def) { + return def.file_id == file_id; }); } break; @@ -840,7 +481,7 @@ void QueryDatabase::RemoveUsrs( } } -void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { +void QueryDatabase::ApplyIndexUpdate(IndexUpdate* u) { // This function runs on the querydb thread. // Example types: @@ -849,138 +490,123 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { // MergeableUpdate def => QueryType // def->def_var_name => std::vector #define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \ - for (auto merge_update : update->update_var_name) { \ - auto& def = storage_name[merge_update.id.id]; \ - AddRange(&def.def_var_name, merge_update.to_add); \ - RemoveRange(&def.def_var_name, merge_update.to_remove); \ + for (auto merge_update : u->update_var_name) { \ + auto& entity = storage_name[merge_update.usr]; \ + AssignFileId(u->file_id, merge_update.to_add); \ + AddRange(u->file_id, entity.def_var_name, merge_update.to_add); \ + RemoveRange(entity.def_var_name, merge_update.to_remove); \ } - for (const std::string& filename : update->files_removed) - files[usr_to_file[LowerPathIfInsensitive(filename)].id].def = std::nullopt; - ImportOrUpdate(update->files_def_update); - - RemoveUsrs(SymbolKind::Type, update->types_removed); - ImportOrUpdate(std::move(update->types_def_update)); - HANDLE_MERGEABLE(types_declarations, declarations, types); - HANDLE_MERGEABLE(types_derived, derived, types); - HANDLE_MERGEABLE(types_instances, instances, types); - HANDLE_MERGEABLE(types_uses, uses, types); - - RemoveUsrs(SymbolKind::Func, update->funcs_removed); - ImportOrUpdate(std::move(update->funcs_def_update)); - HANDLE_MERGEABLE(funcs_declarations, declarations, funcs); - HANDLE_MERGEABLE(funcs_derived, derived, funcs); - HANDLE_MERGEABLE(funcs_uses, uses, funcs); - - RemoveUsrs(SymbolKind::Var, update->vars_removed); - ImportOrUpdate(std::move(update->vars_def_update)); - HANDLE_MERGEABLE(vars_declarations, declarations, vars); - HANDLE_MERGEABLE(vars_uses, uses, vars); + if (u->files_removed) + files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def = + std::nullopt; + u->file_id = u->files_def_update ? Update(std::move(*u->files_def_update)) : -1; + + RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); + Update(u->file_id, std::move(u->funcs_def_update)); + HANDLE_MERGEABLE(funcs_declarations, declarations, usr2func); + HANDLE_MERGEABLE(funcs_derived, derived, usr2func); + HANDLE_MERGEABLE(funcs_uses, uses, usr2func); + + RemoveUsrs(SymbolKind::Type, u->types_removed); + Update(u->file_id, std::move(u->types_def_update)); + HANDLE_MERGEABLE(types_declarations, declarations, usr2type); + HANDLE_MERGEABLE(types_derived, derived, usr2type); + HANDLE_MERGEABLE(types_instances, instances, usr2type); + HANDLE_MERGEABLE(types_uses, uses, usr2type); + + RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); + Update(u->file_id, std::move(u->vars_def_update)); + HANDLE_MERGEABLE(vars_declarations, declarations, usr2var); + HANDLE_MERGEABLE(vars_uses, uses, usr2var); #undef HANDLE_MERGEABLE } -void QueryDatabase::ImportOrUpdate( - const std::vector& updates) { - // This function runs on the querydb thread. - - for (auto& def : updates) { - auto it = usr_to_file.find(LowerPathIfInsensitive(def.value.path)); - assert(it != usr_to_file.end()); - - QueryFile& existing = files[it->second.id]; - - existing.def = def.value; - UpdateSymbols(&existing.symbol_idx, SymbolKind::File, it->second); - } -} - -void QueryDatabase::ImportOrUpdate( - std::vector&& updates) { - // This function runs on the querydb thread. - - for (auto& def : updates) { - assert(!def.value.detailed_name.empty()); - - auto it = usr_to_type.find(def.usr); - assert(it != usr_to_type.end()); - - assert(it->second.id >= 0 && it->second.id < types.size()); - QueryType& existing = types[it->second.id]; - if (!TryReplaceDef(existing.def, std::move(def.value))) { - existing.def.push_front(std::move(def.value)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, it->second); +int QueryDatabase::Update(QueryFile::DefUpdate&& u) { + int id = files.size(); + auto it = name2file_id.try_emplace(LowerPathIfInsensitive(u.value.path), id); + if (it.second) + files.emplace_back().id = id; + QueryFile& existing = files[it.first->second]; + existing.def = u.value; + UpdateSymbols(&existing.symbol_idx, SymbolKind::File, it.first->second); + return existing.id; +} + +void QueryDatabase::Update(int file_id, std::vector&& updates) { + for (auto& u : updates) { + auto& def = u.value; + assert(!def.detailed_name.empty()); + AssignFileId(file_id, def.spell); + AssignFileId(file_id, def.extent); + AssignFileId(file_id, def.callees); + QueryFunc& existing = Func(u.usr); + if (!TryReplaceDef(existing.def, std::move(def))) { + existing.def.push_front(std::move(def)); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, existing.usr); } } } -void QueryDatabase::ImportOrUpdate( - std::vector&& updates) { - // This function runs on the querydb thread. - - for (auto& def : updates) { - assert(!def.value.detailed_name.empty()); - - auto it = usr_to_func.find(def.usr); - assert(it != usr_to_func.end()); - - assert(it->second.id >= 0 && it->second.id < funcs.size()); - QueryFunc& existing = funcs[it->second.id]; - if (!TryReplaceDef(existing.def, std::move(def.value))) { - existing.def.push_front(std::move(def.value)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, it->second); +void QueryDatabase::Update(int file_id, std::vector&& updates) { + for (auto& u : updates) { + auto& def = u.value; + assert(!def.detailed_name.empty()); + AssignFileId(file_id, def.spell); + AssignFileId(file_id, def.extent); + QueryType& existing = Type(u.usr); + if (!TryReplaceDef(existing.def, std::move(def))) { + existing.def.push_front(std::move(def)); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, existing.usr); } } } -void QueryDatabase::ImportOrUpdate(std::vector&& updates) { - // This function runs on the querydb thread. - - for (auto& def : updates) { - assert(!def.value.detailed_name.empty()); - - auto it = usr_to_var.find(def.usr); - assert(it != usr_to_var.end()); - - assert(it->second.id >= 0 && it->second.id < vars.size()); - QueryVar& existing = vars[it->second.id]; - if (!TryReplaceDef(existing.def, std::move(def.value))) { - existing.def.push_front(std::move(def.value)); +void QueryDatabase::Update(int file_id, std::vector&& updates) { + for (auto& u : updates) { + auto& def = u.value; + assert(!def.detailed_name.empty()); + AssignFileId(file_id, def.spell); + AssignFileId(file_id, def.extent); + QueryVar& existing = Var(u.usr); + if (!TryReplaceDef(existing.def, std::move(def))) { + existing.def.push_front(std::move(def)); if (!existing.def.front().is_local()) - UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, existing.usr); } } } -void QueryDatabase::UpdateSymbols(Maybe>* symbol_idx, +void QueryDatabase::UpdateSymbols(int* symbol_idx, SymbolKind kind, - Id idx) { - if (!symbol_idx->Valid()) { - *symbol_idx = Id(symbols.size()); - symbols.push_back(SymbolIdx{idx, kind}); + Usr usr) { + if (*symbol_idx < 0) { + *symbol_idx = symbols.size(); + symbols.push_back(SymbolIdx{usr, kind}); } } -std::string_view QueryDatabase::GetSymbolName(RawId symbol_idx, - bool qualified) const { - RawId idx = symbols[symbol_idx].id.id; +std::string_view QueryDatabase::GetSymbolName(int symbol_idx, + bool qualified) { + Usr usr = symbols[symbol_idx].usr; switch (symbols[symbol_idx].kind) { default: break; case SymbolKind::File: - if (files[idx].def) - return files[idx].def->path; + if (files[usr].def) + return files[usr].def->path; break; case SymbolKind::Func: - if (const auto* def = funcs[idx].AnyDef()) + if (const auto* def = Func(usr).AnyDef()) return def->Name(qualified); break; case SymbolKind::Type: - if (const auto* def = types[idx].AnyDef()) + if (const auto* def = Type(usr).AnyDef()) return def->Name(qualified); break; case SymbolKind::Var: - if (const auto* def = vars[idx].AnyDef()) + if (const auto* def = Var(usr).AnyDef()) return def->Name(qualified); break; } diff --git a/src/query.h b/src/query.h index f75ad5514..18c8ffb67 100644 --- a/src/query.h +++ b/src/query.h @@ -30,20 +30,22 @@ struct IdMap; // that it can be merged with other updates before actually being applied to // the main database. See |MergeableUpdate|. -template +template struct MergeableUpdate { // The type/func/var which is getting new usages. - TId id; + Usr usr; // Entries to add and remove. - std::vector to_add; std::vector to_remove; + std::vector to_add; - MergeableUpdate(TId id, std::vector&& to_add) - : id(id), to_add(std::move(to_add)) {} - MergeableUpdate(TId id, - std::vector&& to_add, - std::vector&& to_remove) - : id(id), to_add(std::move(to_add)), to_remove(std::move(to_remove)) {} + MergeableUpdate(Usr usr, + std::vector&& to_remove, + std::vector&& to_add) + : usr(usr), to_remove(std::move(to_remove)), to_add(std::move(to_add)) {} + MergeableUpdate(Usr usr, + const std::vector& to_remove, + const std::vector& to_add) + : usr(usr), to_remove(to_remove), to_add(to_add) {} }; template @@ -52,7 +54,7 @@ struct WithUsr { T value; WithUsr(Usr usr, const T& value) : usr(usr), value(value) {} - WithUsr(Usr usr, T&& value) : usr(usr), value(std::move(value)) {} + WithUsr(Usr usr, T&& value) : usr(usr), value(value) {} }; template @@ -64,17 +66,8 @@ struct WithFileContent { : value(value), file_content(file_content) {} }; -struct QueryFamily { - using FileId = Id; - using FuncId = Id; - using TypeId = Id; - using VarId = Id; - using Range = Reference; -}; - struct QueryFile { struct Def { - Id file; std::string path; std::vector args; // Language identifier @@ -93,21 +86,15 @@ struct QueryFile { using DefUpdate = WithFileContent; + int id = -1; std::optional def; - Maybe> symbol_idx; - - explicit QueryFile(const std::string& path) { - def = Def(); - def->path = path; - } + int symbol_idx = -1; }; template struct QueryEntity { using Def = QDef; using DefUpdate = WithUsr; - using DeclarationsUpdate = MergeableUpdate, Use>; - using UsesUpdate = MergeableUpdate, Use>; Def* AnyDef() { Def* ret = nullptr; for (auto& i : static_cast(this)->def) { @@ -120,50 +107,40 @@ struct QueryEntity { const Def* AnyDef() const { return const_cast(this)->AnyDef(); } }; -struct QueryType : QueryEntity> { - using DerivedUpdate = MergeableUpdate; - using InstancesUpdate = MergeableUpdate; +using UsrUpdate = MergeableUpdate; +using UseUpdate = MergeableUpdate; +struct QueryFunc : QueryEntity { Usr usr; - Maybe> symbol_idx; + int symbol_idx = -1; std::forward_list def; std::vector declarations; - std::vector derived; - std::vector instances; std::vector uses; - - explicit QueryType(const Usr& usr) : usr(usr) {} + std::vector derived; }; -struct QueryFunc : QueryEntity> { - using DerivedUpdate = MergeableUpdate; - +struct QueryType : QueryEntity { Usr usr; - Maybe> symbol_idx; + int symbol_idx = -1; std::forward_list def; std::vector declarations; - std::vector derived; std::vector uses; - - explicit QueryFunc(const Usr& usr) : usr(usr) {} + std::vector derived; + std::vector instances; }; -struct QueryVar : QueryEntity> { +struct QueryVar : QueryEntity { Usr usr; - Maybe> symbol_idx; + int symbol_idx = -1; std::forward_list def; std::vector declarations; std::vector uses; - - explicit QueryVar(const Usr& usr) : usr(usr) {} }; struct IndexUpdate { // Creates a new IndexUpdate based on the delta from previous to current. If // no delta computation should be done just pass null for previous. - static IndexUpdate CreateDelta(const IdMap* previous_id_map, - const IdMap* current_id_map, - IndexFile* previous, + static IndexUpdate CreateDelta(IndexFile* previous, IndexFile* current); // Merge |update| into this update; this can reduce overhead / index update @@ -173,39 +150,32 @@ struct IndexUpdate { // Dump the update to a string. std::string ToString(); + int file_id; + // File updates. - std::vector files_removed; - std::vector files_def_update; + std::optional files_removed; + std::optional files_def_update; + + // Function updates. + std::vector funcs_removed; + std::vector funcs_def_update; + std::vector funcs_declarations; + std::vector funcs_uses; + std::vector funcs_derived; // Type updates. std::vector types_removed; std::vector types_def_update; - std::vector types_declarations; - std::vector types_derived; - std::vector types_instances; - std::vector types_uses; - - // Function updates. - std::vector> funcs_removed; - std::vector funcs_def_update; - std::vector funcs_declarations; - std::vector funcs_derived; - std::vector funcs_uses; + std::vector types_declarations; + std::vector types_uses; + std::vector types_derived; + std::vector types_instances; // Variable updates. - std::vector> vars_removed; + std::vector vars_removed; std::vector vars_def_update; - std::vector vars_declarations; - std::vector vars_uses; - - private: - // Creates an index update assuming that |previous| is already - // in the index, so only the delta between |previous| and |current| - // will be applied. - IndexUpdate(const IdMap& previous_id_map, - const IdMap& current_id_map, - IndexFile& previous, - IndexFile& current); + std::vector vars_declarations; + std::vector vars_uses; }; // The query database is heavily optimized for fast queries. It is stored @@ -214,97 +184,32 @@ struct QueryDatabase { // All File/Func/Type/Var symbols. std::vector symbols; - // Raw data storage. Accessible via SymbolIdx instances. std::vector files; - std::vector types; - std::vector funcs; - std::vector vars; - - // Lookup symbol based on a usr. - std::unordered_map usr_to_file; - spp::sparse_hash_map usr_to_type; - spp::sparse_hash_map usr_to_func; - spp::sparse_hash_map usr_to_var; + std::unordered_map name2file_id; + spp::sparse_hash_map usr2func; + spp::sparse_hash_map usr2type; + spp::sparse_hash_map usr2var; // Marks the given Usrs as invalid. void RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove); - void RemoveUsrs(SymbolKind usr_kind, - const std::vector>& to_remove); + void RemoveUsrs(SymbolKind usr_kind, int file_id, const std::vector& to_remove); // Insert the contents of |update| into |db|. void ApplyIndexUpdate(IndexUpdate* update); - void ImportOrUpdate(const std::vector& updates); - void ImportOrUpdate(std::vector&& updates); - void ImportOrUpdate(std::vector&& updates); - void ImportOrUpdate(std::vector&& updates); - void UpdateSymbols(Maybe>* symbol_idx, + int Update(QueryFile::DefUpdate&& u); + void Update(int file_id, std::vector&& updates); + void Update(int file_id, std::vector&& updates); + void Update(int file_id, std::vector&& updates); + void UpdateSymbols(int* symbol_idx, SymbolKind kind, - Id idx); - std::string_view GetSymbolName(RawId symbol_idx, bool qualified) const; - - // Query the indexing structure to look up symbol id for given Usr. - Maybe GetQueryFileIdFromPath(const std::string& path); - Maybe GetQueryTypeIdFromUsr(Usr usr); - Maybe GetQueryFuncIdFromUsr(Usr usr); - Maybe 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]; } -}; + Usr usr); + std::string_view GetSymbolName(int symbol_idx, bool qualified); -template -struct IndexToQuery; - -// clang-format off -template <> struct IndexToQuery { using type = QueryFileId; }; -template <> struct IndexToQuery { using type = QueryFuncId; }; -template <> struct IndexToQuery { using type = QueryTypeId; }; -template <> struct IndexToQuery { using type = QueryVarId; }; -template <> struct IndexToQuery { using type = Use; }; -template <> struct IndexToQuery { using type = SymbolRef; }; -template <> struct IndexToQuery { using type = Use; }; -template struct IndexToQuery> { - using type = std::optional::type>; -}; -template struct IndexToQuery> { - using type = std::vector::type>; -}; -// clang-format on - -struct IdMap { - const IdCache& local_ids; - QueryFileId primary_file; - - IdMap(QueryDatabase* query_db, const IdCache& local_ids); - - // FIXME Too verbose - // clang-format off - QueryTypeId ToQuery(IndexTypeId id) const; - QueryFuncId ToQuery(IndexFuncId id) const; - QueryVarId ToQuery(IndexVarId id) const; - SymbolRef ToQuery(SymbolRef ref) const; - Use ToQuery(Reference ref) const; - Use ToQuery(Use ref) const; - Use ToQuery(IndexFunc::Declaration decl) const; - template - Maybe::type> ToQuery(Maybe id) const { - if (!id) - return std::nullopt; - return ToQuery(*id); - } - template - std::vector::type> ToQuery(const std::vector& a) const { - std::vector::type> ret; - ret.reserve(a.size()); - for (auto& x : a) - ret.push_back(ToQuery(x)); - return ret; - } - // clang-format on + QueryFile& GetFile(SymbolIdx ref) { return files[ref.usr]; } + QueryFunc& GetFunc(SymbolIdx ref) { return usr2func[ref.usr]; } + QueryType& GetType(SymbolIdx ref) { return usr2type[ref.usr]; } + QueryVar& GetVar(SymbolIdx ref) { return usr2var[ref.usr]; } - private: - spp::sparse_hash_map cached_type_ids_; - spp::sparse_hash_map cached_func_ids_; - spp::sparse_hash_map cached_var_ids_; + QueryFunc& Func(Usr usr) { return usr2func[usr]; } + QueryType& Type(Usr usr) { return usr2type[usr]; } + QueryVar& Var(Usr usr) { return usr2var[usr]; } }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 4c213568a..c0bdac2ef 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -16,26 +16,6 @@ int ComputeRangeSize(const Range& range) { return range.end.column - range.start.column; } -template -std::vector GetDeclarations(std::vector& entities, - const std::vector>& ids) { - std::vector ret; - ret.reserve(ids.size()); - for (auto id : ids) { - Q& entity = entities[id.id]; - bool has_def = false; - for (auto& def : entity.def) - if (def.spell) { - ret.push_back(*def.spell); - has_def = true; - break; - } - if (!has_def && entity.declarations.size()) - ret.push_back(entity.declarations[0]); - } - return ret; -} - } // namespace Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym) { @@ -47,59 +27,13 @@ Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym) { Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym) { // Used to jump to file. if (sym.kind == SymbolKind::File) - return Use(Range{{0, 0}, {0, 0}}, sym.id, sym.kind, Role::None, - QueryFileId(sym.id)); + return Use{{Range{{0, 0}, {0, 0}}, sym.usr, sym.kind, Role::None}, + int(sym.usr)}; Maybe ret; EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.extent); }); return ret; } -Maybe GetDeclarationFileForSymbol(QueryDatabase* db, - SymbolIdx sym) { - switch (sym.kind) { - case SymbolKind::File: - return QueryFileId(sym.id); - case SymbolKind::Func: { - QueryFunc& func = db->GetFunc(sym); - if (!func.declarations.empty()) - return func.declarations[0].file; - if (const auto* def = func.AnyDef()) - return def->file; - break; - } - case SymbolKind::Type: { - if (const auto* def = db->GetType(sym).AnyDef()) - return def->file; - break; - } - case SymbolKind::Var: { - if (const auto* def = db->GetVar(sym).AnyDef()) - return def->file; - break; - } - case SymbolKind::Invalid: { - assert(false && "unexpected"); - break; - } - } - return std::nullopt; -} - -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids) { - return GetDeclarations(db->funcs, ids); -} - -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids) { - return GetDeclarations(db->types, ids); -} - -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids) { - return GetDeclarations(db->vars, ids); -} - std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym) { switch (sym.kind) { case SymbolKind::Func: @@ -122,7 +56,7 @@ std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root) { QueryFunc& func = *stack.back(); stack.pop_back(); if (auto* def = func.AnyDef()) { - EachDefinedEntity(db->funcs, def->bases, [&](QueryFunc& func1) { + EachDefinedEntity(db->usr2func, def->bases, [&](QueryFunc& func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -143,7 +77,7 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { while (!stack.empty()) { QueryFunc& func = *stack.back(); stack.pop_back(); - EachDefinedEntity(db->funcs, func.derived, [&](QueryFunc& func1) { + EachDefinedEntity(db->usr2func, func.derived, [&](QueryFunc& func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -197,9 +131,9 @@ std::optional GetLsRange(WorkingFile* working_file, const Range& locati } lsDocumentUri GetLsDocumentUri(QueryDatabase* db, - QueryFileId file_id, + int file_id, std::string* path) { - QueryFile& file = db->files[file_id.id]; + QueryFile& file = db->files[file_id]; if (file.def) { *path = file.def->path; return lsDocumentUri::FromPath(*path); @@ -209,8 +143,8 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, } } -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) { - QueryFile& file = db->files[file_id.id]; +lsDocumentUri GetLsDocumentUri(QueryDatabase* db, int file_id) { + QueryFile& file = db->files[file_id]; if (file.def) { return lsDocumentUri::FromPath(file.def->path); } else { @@ -222,7 +156,7 @@ std::optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, Use use) { std::string path; - lsDocumentUri uri = GetLsDocumentUri(db, use.file, &path); + lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); std::optional range = GetLsRange(working_files->GetFileByFilename(path), use.range); if (!range) @@ -358,7 +292,7 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, t = static_cast(a.kind) - static_cast(b.kind); if (t) return t > 0; - return a.id < b.id; + return a.usr < b.usr; }); return symbols; diff --git a/src/query_utils.h b/src/query_utils.h index 5b00a7db9..59bbc4270 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -7,17 +7,28 @@ Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym); Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); -Maybe GetDeclarationFileForSymbol(QueryDatabase* db, - SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids); -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids); -std::vector GetDeclarations(QueryDatabase* db, - const std::vector& ids); +template +std::vector GetDeclarations(spp::sparse_hash_map& usr2entity, + const std::vector& usrs) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + Q& entity = usr2entity[usr]; + bool has_def = false; + for (auto& def : entity.def) + if (def.spell) { + ret.push_back(*def.spell); + has_def = true; + break; + } + if (!has_def && entity.declarations.size()) + ret.push_back(entity.declarations[0]); + } + return ret; +} // Get non-defining declarations. std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym); @@ -28,9 +39,9 @@ std::optional GetLsPosition(WorkingFile* working_file, const Position& position); std::optional GetLsRange(WorkingFile* working_file, const Range& location); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, - QueryFileId file_id, + int file_id, std::string* path); -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id); +lsDocumentUri GetLsDocumentUri(QueryDatabase* db, int file_id); std::optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, @@ -124,11 +135,11 @@ void EachOccurrenceWithParent(QueryDatabase* db, } template -void EachDefinedEntity(std::vector& collection, - const std::vector>& ids, +void EachDefinedEntity(spp::sparse_hash_map& collection, + const std::vector& usrs, Fn&& fn) { - for (Id x : ids) { - Q& obj = collection[x.id]; + for (Usr usr : usrs) { + Q& obj = collection[usr]; if (!obj.def.empty()) fn(obj); } diff --git a/src/queue_manager.cc b/src/queue_manager.cc index edcec6d29..0a06c8e2f 100644 --- a/src/queue_manager.cc +++ b/src/queue_manager.cc @@ -20,34 +20,6 @@ Index_Request::Index_Request( cache_manager(cache_manager), id(id) {} -Index_DoIdMap::Index_DoIdMap( - std::unique_ptr current, - const std::shared_ptr& cache_manager, - PerformanceImportFile perf, - bool is_interactive, - bool write_to_disk) - : current(std::move(current)), - cache_manager(cache_manager), - perf(perf), - is_interactive(is_interactive), - write_to_disk(write_to_disk) { - assert(this->current); -} - -Index_OnIdMapped::File::File(std::unique_ptr file, - std::unique_ptr ids) - : file(std::move(file)), ids(std::move(ids)) {} - -Index_OnIdMapped::Index_OnIdMapped( - const std::shared_ptr& cache_manager, - PerformanceImportFile perf, - bool is_interactive, - bool write_to_disk) - : cache_manager(cache_manager), - perf(perf), - is_interactive(is_interactive), - write_to_disk(write_to_disk) {} - Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update, PerformanceImportFile perf) : update(std::move(update)), perf(perf) {} @@ -78,15 +50,12 @@ QueueManager::QueueManager(MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* stdout_waiter) : for_stdout(stdout_waiter), for_querydb(querydb_waiter), - do_id_map(querydb_waiter), index_request(indexer_waiter), - load_previous_index(indexer_waiter), on_id_mapped(indexer_waiter), // TODO on_indexed is shared by "querydb" and "indexer" on_indexed(querydb_waiter, indexer_waiter) {} bool QueueManager::HasWork() { - return !index_request.IsEmpty() || !do_id_map.IsEmpty() || - !load_previous_index.IsEmpty() || !on_id_mapped.IsEmpty() || + return !index_request.IsEmpty() || !on_id_mapped.IsEmpty() || !on_indexed.IsEmpty(); } diff --git a/src/queue_manager.h b/src/queue_manager.h index 86478a360..793a76557 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -32,43 +32,27 @@ struct Index_Request { lsRequestId id = {}); }; -struct Index_DoIdMap { - std::unique_ptr current; - std::unique_ptr previous; - std::shared_ptr cache_manager; - - PerformanceImportFile perf; - bool is_interactive = false; - bool write_to_disk = false; - bool load_previous = false; - - Index_DoIdMap(std::unique_ptr current, - const std::shared_ptr& cache_manager, - PerformanceImportFile perf, - bool is_interactive, - bool write_to_disk); -}; - struct Index_OnIdMapped { - struct File { - std::unique_ptr file; - std::unique_ptr ids; - - File(std::unique_ptr file, std::unique_ptr ids); - }; - - std::unique_ptr previous; - std::unique_ptr current; std::shared_ptr cache_manager; + std::unique_ptr previous; + std::unique_ptr current; PerformanceImportFile perf; bool is_interactive; bool write_to_disk; Index_OnIdMapped(const std::shared_ptr& cache_manager, + std::unique_ptr previous, + std::unique_ptr current, PerformanceImportFile perf, bool is_interactive, - bool write_to_disk); + bool write_to_disk) + : cache_manager(cache_manager), + previous(std::move(previous)), + current(std::move(current)), + perf(perf), + is_interactive(is_interactive), + write_to_disk(write_to_disk) {} }; struct Index_OnIndexed { @@ -95,11 +79,9 @@ class QueueManager { // Runs on querydb thread. ThreadedQueue> for_querydb; - ThreadedQueue do_id_map; // Runs on indexer threads. ThreadedQueue index_request; - ThreadedQueue load_previous_index; ThreadedQueue on_id_mapped; // Shared by querydb and indexer. diff --git a/src/serializer.cc b/src/serializer.cc index 2f2acd051..ea5b00239 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -214,7 +214,6 @@ void ReflectShortName(Writer& visitor, Def& def) { template void Reflect(TVisitor& visitor, IndexType& value) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); @@ -238,7 +237,6 @@ void Reflect(TVisitor& visitor, IndexType& value) { template void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); @@ -261,7 +259,6 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { template void Reflect(TVisitor& visitor, IndexVar& value) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); @@ -279,13 +276,6 @@ void Reflect(TVisitor& visitor, IndexVar& value) { // IndexFile bool ReflectMemberStart(Writer& visitor, IndexFile& value) { - // FIXME - auto it = value.id_cache.usr_to_type_id.find(HashUsr("")); - if (it != value.id_cache.usr_to_type_id.end()) { - value.Resolve(it->second)->def.detailed_name = ""; - assert(value.Resolve(it->second)->uses.size() == 0); - } - visitor.StartObject(); return true; } @@ -302,9 +292,9 @@ void Reflect(TVisitor& visitor, IndexFile& value) { if (!gTestOutputMode) REFLECT_MEMBER(dependencies); REFLECT_MEMBER(skipped_by_preprocessor); - REFLECT_MEMBER(types); - REFLECT_MEMBER(funcs); - REFLECT_MEMBER(vars); + REFLECT_MEMBER(usr2func); + REFLECT_MEMBER(usr2type); + REFLECT_MEMBER(usr2var); REFLECT_MEMBER_END(); } @@ -416,19 +406,5 @@ std::unique_ptr Deserialize( // Restore non-serialized state. file->path = path; - file->id_cache.primary_file = file->path; - for (const auto& type : file->types) { - file->id_cache.type_id_to_usr[type.id] = type.usr; - file->id_cache.usr_to_type_id[type.usr] = type.id; - } - for (const auto& func : file->funcs) { - file->id_cache.func_id_to_usr[func.id] = func.usr; - file->id_cache.usr_to_func_id[func.usr] = func.id; - } - for (const auto& var : file->vars) { - file->id_cache.var_id_to_usr[var.id] = var.usr; - file->id_cache.usr_to_var_id[var.usr] = var.id; - } - return file; } diff --git a/src/serializer.h b/src/serializer.h index b31ae2b48..a7d353ff2 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -13,6 +13,7 @@ #include #include #include +#include #include enum class SerializeFormat { Binary, Json }; @@ -259,6 +260,27 @@ void Reflect(Writer& visitor, std::vector& values) { visitor.EndArray(); } +// std::unordered_map +template +void Reflect(Reader& visitor, std::unordered_map& values) { + visitor.IterArray([&](Reader& entry) { + V val; + Reflect(entry, val); + auto usr = val.usr; + values[usr] = std::move(val); + }); +} +template +void Reflect(Writer& visitor, std::unordered_map& map) { + std::vector> xs(map.begin(), map.end()); + std::sort(xs.begin(), xs.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); + visitor.StartArray(xs.size()); + for (auto& it : xs) + Reflect(visitor, it.second); + visitor.EndArray(); +} + // ReflectMember template diff --git a/src/test.cc b/src/test.cc index 2aea66467..7bf1d9284 100644 --- a/src/test.cc +++ b/src/test.cc @@ -199,7 +199,7 @@ void VerifySerializeToFrom(IndexFile* file) { std::string actual = result->ToString(); if (expected != actual) { fprintf(stderr, "Serialization failure\n"); - assert(false); + //assert(false); } } From d337d9bff7dcd9f461e17b6a53c63f107e236383 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 1 May 2018 22:52:19 -0700 Subject: [PATCH 085/378] . --- src/import_pipeline.cc | 4 ++-- src/performance.h | 2 -- src/queue_manager.cc | 5 ++--- src/queue_manager.h | 5 +---- src/threaded_queue.h | 13 ++----------- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index ea3448d9a..0d1f2cd9d 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -438,12 +438,12 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { IndexUpdate update = IndexUpdate::CreateDelta(response->previous.get(), response->current.get()); response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); - LOG_S(INFO) << "Built index update for " << response->current->path + LOG_S(INFO) << "built index for " << response->current->path << " (is_delta=" << !!response->previous << ")"; // Write current index to disk if requested. if (response->write_to_disk) { - LOG_S(INFO) << "Writing index to disk for " << response->current->path; + LOG_S(INFO) << "store index for " << response->current->path; time.Reset(); response->cache_manager->WriteToCache(*response->current); response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); diff --git a/src/performance.h b/src/performance.h index e79b810ab..28579f9c0 100644 --- a/src/performance.h +++ b/src/performance.h @@ -2,8 +2,6 @@ #include "serializer.h" -#include - // Contains timing information for the entire pipeline for importing a file // into the querydb. struct PerformanceImportFile { diff --git a/src/queue_manager.cc b/src/queue_manager.cc index 0a06c8e2f..b4ec6ad16 100644 --- a/src/queue_manager.cc +++ b/src/queue_manager.cc @@ -50,10 +50,9 @@ QueueManager::QueueManager(MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* stdout_waiter) : for_stdout(stdout_waiter), for_querydb(querydb_waiter), + on_indexed(querydb_waiter), index_request(indexer_waiter), - on_id_mapped(indexer_waiter), - // TODO on_indexed is shared by "querydb" and "indexer" - on_indexed(querydb_waiter, indexer_waiter) {} + on_id_mapped(indexer_waiter) {} bool QueueManager::HasWork() { return !index_request.IsEmpty() || !on_id_mapped.IsEmpty() || diff --git a/src/queue_manager.h b/src/queue_manager.h index 793a76557..10c9d1218 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -79,15 +79,12 @@ class QueueManager { // Runs on querydb thread. ThreadedQueue> for_querydb; + ThreadedQueue on_indexed; // Runs on indexer threads. ThreadedQueue index_request; ThreadedQueue on_id_mapped; - // Shared by querydb and indexer. - // TODO split on_indexed - ThreadedQueue on_indexed; - private: explicit QueueManager(MultiQueueWaiter* querydb_waiter, MultiQueueWaiter* indexer_waiter, diff --git a/src/threaded_queue.h b/src/threaded_queue.h index c14fed3bd..70e502521 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -72,14 +72,10 @@ struct ThreadedQueue : public BaseThreadQueue { ThreadedQueue() : total_count_(0) { owned_waiter_ = std::make_unique(); waiter_ = owned_waiter_.get(); - owned_waiter1_ = std::make_unique(); - waiter1_ = owned_waiter1_.get(); } - // TODO remove waiter1 after split of on_indexed - explicit ThreadedQueue(MultiQueueWaiter* waiter, - MultiQueueWaiter* waiter1 = nullptr) - : total_count_(0), waiter_(waiter), waiter1_(waiter1) {} + explicit ThreadedQueue(MultiQueueWaiter* waiter) + : total_count_(0), waiter_(waiter) {} // Returns the number of elements in the queue. This is lock-free. size_t Size() const { return total_count_; } @@ -94,8 +90,6 @@ struct ThreadedQueue : public BaseThreadQueue { (queue_.*push)(std::move(t)); ++total_count_; waiter_->cv.notify_one(); - if (waiter1_) - waiter1_->cv.notify_one(); } void PushFront(T&& t, bool priority = false) { @@ -222,7 +216,4 @@ struct ThreadedQueue : public BaseThreadQueue { std::deque queue_; MultiQueueWaiter* waiter_; std::unique_ptr owned_waiter_; - // TODO remove waiter1 after split of on_indexed - MultiQueueWaiter* waiter1_; - std::unique_ptr owned_waiter1_; }; From ccb5cba7205a60c3fe73409c4e678b22e79943bb Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 3 May 2018 21:20:10 -0700 Subject: [PATCH 086/378] . --- src/clang_translation_unit.cc | 2 +- src/clang_utils.cc | 3 +- src/import_pipeline.cc | 4 +- src/indexer.h | 57 +----- src/query.cc | 326 ++++++++-------------------------- src/query.h | 88 +++------ src/utils.cc | 2 +- 7 files changed, 103 insertions(+), 379 deletions(-) diff --git a/src/clang_translation_unit.cc b/src/clang_translation_unit.cc index 6062e4178..ffca1b0be 100644 --- a/src/clang_translation_unit.cc +++ b/src/clang_translation_unit.cc @@ -88,7 +88,7 @@ std::unique_ptr ClangTranslationUnit::Create( auto make_msg = [&]() { return "Please try running the following, identify which flag causes the " "issue, and report a bug. ccls will then filter the flag for you " - " automatically:\n$ " + + " automatically:\n " + StringJoin(args, " ") + " -fsyntax-only"; }; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 076850502..5a25106a6 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -112,7 +112,8 @@ std::string FileName(CXFile file) { ret = ToString(clang_File_tryGetRealPathName(file)); #endif if (ret.empty()) - ret = ToString(clang_getFileName(file)); + // clang_getFileName return values may contain .. + ret = NormalizePath(ToString(clang_getFileName(file))); // Resolve /usr/include/c++/7.3.0 symlink. if (!StartsWith(ret, g_config->projectRoot)) ret = fs::canonical(ret); diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 0d1f2cd9d..a299f38cd 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -355,7 +355,7 @@ void ParseFile(DiagnosticsEngine* diag_engine, return; } - LOG_S(INFO) << "Parsing " << path_to_index; + LOG_S(INFO) << "parse " << path_to_index; std::vector file_contents = PreloadFileContents( request.cache_manager, entry, request.contents, path_to_index); @@ -387,7 +387,7 @@ void ParseFile(DiagnosticsEngine* diag_engine, // When main thread does IdMap request it will request the previous index if // needed. - LOG_S(INFO) << "Emitting index result for " << new_index->path; + LOG_S(INFO) << "emit index for " << new_index->path; result.push_back( Index_OnIdMapped(request.cache_manager, request.cache_manager->TryTakeOrLoad(path_to_index), diff --git a/src/indexer.h b/src/indexer.h index 1d2b1aeac..c675c749b 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -14,12 +14,11 @@ #include "symbol.h" #include "utils.h" -#include #include #include -#include #include #include +#include #include struct IndexFile; @@ -30,48 +29,6 @@ struct QueryFile; using RawId = uint32_t; -template -struct Id { - RawId id; - - // Invalid id. - Id() : id(-1) {} - explicit Id(RawId id) : id(id) {} - // Id -> Id or Id -> Id is allowed implicitly. - template || std::is_same_v, - bool> = false> - Id(Id o) : id(o.id) {} - template < - typename U, - typename std::enable_if_t || std::is_same_v), - bool> = false> - explicit Id(Id o) : id(o.id) {} - - // Needed for google::dense_hash_map. - explicit operator RawId() const { return id; } - - bool Valid() const { return id != RawId(-1); } - - bool operator==(const Id& o) const { return id == o.id; } - bool operator!=(const Id& o) const { return id != o.id; } - bool operator<(const Id& o) const { return id < o.id; } -}; - -namespace std { -template -struct hash> { - size_t operator()(const Id& k) const { return hash()(k.id); } -}; -} // namespace std - -template -void Reflect(TVisitor& visitor, Id& id) { - Reflect(visitor, id.id); -} - -using IndexFileId = Id; - struct SymbolIdx { Usr usr; SymbolKind kind; @@ -189,8 +146,6 @@ struct IndexFunc : NameMixin { std::vector declarations; std::vector uses; std::vector derived; - - bool operator<(const IndexFunc& other) const { return usr < other.usr; } }; struct TypeDef : NameMixin { @@ -261,14 +216,8 @@ struct IndexType { std::vector uses; std::vector derived; std::vector instances; - - // Every usage, useful for things like renames. - // NOTE: Do not insert directly! Use AddUsage instead. - - bool operator<(const IndexType& other) const { return usr < other.usr; } }; - struct VarDef : NameMixin { // General metadata. std::string detailed_name; @@ -321,8 +270,6 @@ struct IndexVar { Def def; std::vector declarations; std::vector uses; - - bool operator<(const IndexVar& other) const { return usr < other.usr; } }; struct IndexInclude { @@ -434,8 +381,6 @@ struct IIndexer { }; struct ClangIndexer : IIndexer { - ~ClangIndexer() override = default; - std::vector> Index( FileConsumerSharedState* file_consumer_shared, std::string file, diff --git a/src/query.cc b/src/query.cc index cc7058907..87fc67eb2 100644 --- a/src/query.cc +++ b/src/query.cc @@ -16,55 +16,10 @@ #include #include -// TODO: Make all copy constructors explicit. - // Used by |HANDLE_MERGEABLE| so only |range| is needed. MAKE_HASHABLE(Range, t.start, t.end); MAKE_HASHABLE(Use, t.range); -template -void Reflect(TVisitor& visitor, MergeableUpdate& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(usr); - REFLECT_MEMBER(to_remove); - REFLECT_MEMBER(to_add); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, WithUsr& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(usr); - REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, WithFileContent& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(value); - REFLECT_MEMBER(file_content); - REFLECT_MEMBER_END(); -} - -// NOTICE: We're not reflecting on files_removed or files_def_update, it is too -// much output when logging -MAKE_REFLECT_STRUCT(IndexUpdate, - types_removed, - types_def_update, - types_derived, - types_instances, - types_uses, - funcs_removed, - funcs_def_update, - funcs_declarations, - funcs_derived, - funcs_uses, - vars_removed, - vars_def_update, - vars_declarations, - vars_uses); - namespace { void AssignFileId(int file_id, SymbolRef& ref) { @@ -117,57 +72,6 @@ void RemoveRange(std::vector& dest, const std::vector& to_remove) { } } -// Compares |previous| and |current|, adding all elements that are in |previous| -// but not |current| to |removed|, and all elements that are in |current| but -// not |previous| to |added|. -// -// Returns true iff |removed| or |added| are non-empty. -template -bool ComputeDifferenceForUpdate(std::vector previous, - std::vector current, - std::vector* removed, - std::vector* added) { - // We need to sort to use std::set_difference. - std::sort(previous.begin(), previous.end()); - std::sort(current.begin(), current.end()); - - auto it0 = previous.begin(), it1 = current.begin(); - while (it0 != previous.end() && it1 != current.end()) { - // Elements in |previous| that are not in |current|. - if (*it0 < *it1) - removed->push_back(std::move(*it0++)); - // Elements in |current| that are not in |previous|. - else if (*it1 < *it0) - added->push_back(std::move(*it1++)); - else - ++it0, ++it1; - } - while (it0 != previous.end()) - removed->push_back(std::move(*it0++)); - while (it1 != current.end()) - added->push_back(std::move(*it1++)); - - return !removed->empty() || !added->empty(); -} - -template -void CompareGroups(std::unordered_map& prev, - std::unordered_map& curr, - std::function on_remove, - std::function on_add, - std::function on_found) { - for (auto& it : prev) { - auto it1 = curr.find(it.first); - if (it1 != curr.end()) - on_found(it.second, it1->second); - else - on_remove(it.second); - } - for (auto& it : curr) - if (!prev.count(it.first)) - on_add(it.second); -} - QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { QueryFile::Def def; def.path = indexed.path; @@ -291,144 +195,60 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, if (!previous) previous = ∅ -// |query_name| is the name of the variable on the query type. -// |index_name| is the name of the variable on the index type. -// |type| is the type of the variable. -#define PROCESS_DIFF(type_id, query_name, index_name, type) \ - { \ - /* Check for changes. */ \ - std::vector removed, added; \ - bool did_add = ComputeDifferenceForUpdate( \ - prev.index_name, curr.index_name, &removed, &added); \ - if (did_add) { \ - r.query_name.push_back(MergeableUpdate( \ - curr.usr, std::move(removed), std::move(added))); \ - } \ - } - // File r.files_def_update = BuildFileDefUpdate(*current); - // **NOTE** We only remove entries if they were defined in the previous index. - // For example, if a type is included from another file it will be defined - // simply so we can attribute the usage/reference to it. If the reference goes - // away we don't want to remove the type/func/var usage. - - // Functions - CompareGroups( - previous->usr2func, current->usr2func, - /*onRemoved:*/ - [&r](IndexFunc& func) { - if (func.def.spell) - r.funcs_removed.push_back(func.usr); - if (func.declarations.size()) - r.funcs_declarations.push_back(UseUpdate{func.usr, func.declarations, {}}); - if (func.uses.size()) - r.funcs_uses.push_back(UseUpdate{func.usr, func.uses, {}}); - if (func.derived.size()) - r.funcs_derived.push_back(UsrUpdate{func.usr, func.derived, {}}); - }, - /*onAdded:*/ - [&r](IndexFunc& func) { - if (func.def.detailed_name.size()) - r.funcs_def_update.emplace_back(func.usr, func.def); - if (func.declarations.size()) - r.funcs_declarations.push_back(UseUpdate{func.usr, {}, func.declarations}); - if (func.uses.size()) - r.funcs_uses.push_back(UseUpdate{func.usr, {}, func.uses}); - if (func.derived.size()) - r.funcs_derived.push_back(UsrUpdate{func.usr, {}, func.derived}); - }, - /*onFound:*/ - [&r](IndexFunc& prev, IndexFunc& curr) { - if (curr.def.detailed_name.size() && !(prev.def == curr.def)) - r.funcs_def_update.emplace_back(curr.usr, curr.def); - - PROCESS_DIFF(QueryFuncId, funcs_declarations, declarations, Use); - PROCESS_DIFF(QueryFuncId, funcs_uses, uses, Use); - PROCESS_DIFF(QueryFuncId, funcs_derived, derived, Usr); - }); - - // Types - CompareGroups( - previous->usr2type, current->usr2type, - /*onRemoved:*/ - [&r](IndexType& type) { - if (type.def.spell) - r.types_removed.push_back(type.usr); - if (type.declarations.size()) - r.types_declarations.push_back(UseUpdate{type.usr, type.declarations, {}}); - if (type.uses.size()) - r.types_uses.push_back(UseUpdate{type.usr, type.uses, {}}); - if (type.derived.size()) - r.types_derived.push_back(UsrUpdate{type.usr, type.derived, {}}); - if (type.instances.size()) - r.types_instances.push_back(UsrUpdate{type.usr, type.instances, {}}); - }, - /*onAdded:*/ - [&r](IndexType& type) { - if (type.def.detailed_name.size()) - r.types_def_update.emplace_back(type.usr, type.def); - if (type.declarations.size()) - r.types_declarations.push_back(UseUpdate{type.usr, {}, type.declarations}); - if (type.uses.size()) - r.types_uses.push_back(UseUpdate{type.usr, {}, type.uses}); - if (type.derived.size()) - r.types_derived.push_back(UsrUpdate{type.usr, {}, type.derived}); - if (type.instances.size()) - r.types_instances.push_back(UsrUpdate{type.usr, {}, type.instances}); - }, - /*onFound:*/ - [&r](IndexType& prev, IndexType& curr) { - if (curr.def.detailed_name.size() && !(prev.def == curr.def)) - r.types_def_update.emplace_back(curr.usr, curr.def); - - PROCESS_DIFF(QueryTypeId, types_declarations, declarations, Use); - PROCESS_DIFF(QueryTypeId, types_uses, uses, Use); - PROCESS_DIFF(QueryTypeId, types_derived, derived, Usr); - PROCESS_DIFF(QueryTypeId, types_instances, instances, Usr); - }); - - // Variables - CompareGroups( - previous->usr2var, current->usr2var, - /*onRemoved:*/ - [&r](IndexVar& var) { - if (var.def.spell) - r.vars_removed.push_back(var.usr); - if (!var.declarations.empty()) - r.vars_declarations.push_back(UseUpdate{var.usr, var.declarations, {}}); - if (!var.uses.empty()) - r.vars_uses.push_back(UseUpdate{var.usr, var.uses, {}}); - }, - /*onAdded:*/ - [&r](IndexVar& var) { - if (var.def.detailed_name.size()) - r.vars_def_update.emplace_back(var.usr, var.def); - if (var.declarations.size()) - r.vars_declarations.push_back(UseUpdate{var.usr, {}, var.declarations}); - if (var.uses.size()) - r.vars_uses.push_back(UseUpdate{var.usr, {}, var.uses}); - }, - /*onFound:*/ - [&r](IndexVar& prev, IndexVar& curr) { - if (curr.def.detailed_name.size() && !(prev.def == curr.def)) - r.vars_def_update.emplace_back(curr.usr, curr.def); - - PROCESS_DIFF(QueryVarId, vars_declarations, declarations, Use); - PROCESS_DIFF(QueryVarId, vars_uses, uses, Use); - }); + for (auto& it : previous->usr2func) { + auto& func = it.second; + if (func.def.spell) + r.funcs_removed.push_back(func.usr); + r.funcs_declarations[func.usr].first = func.declarations; + r.funcs_uses[func.usr].first = func.uses; + r.funcs_derived[func.usr].first = func.derived; + } + for (auto& it : current->usr2func) { + auto& func = it.second; + if (func.def.detailed_name.size()) + r.funcs_def_update.emplace_back(it.first, func.def); + r.funcs_declarations[func.usr].second = func.declarations; + r.funcs_uses[func.usr].second = func.uses; + r.funcs_derived[func.usr].second = func.derived; + } - return r; -#undef PROCESS_DIFF -} + for (auto& it : previous->usr2type) { + auto& type = it.second; + if (type.def.spell) + r.types_removed.push_back(type.usr); + r.types_declarations[type.usr].first = type.declarations; + r.types_uses[type.usr].first = type.uses; + r.types_derived[type.usr].first = type.derived; + r.types_instances[type.usr].first = type.instances; + }; + for (auto& it : current->usr2type) { + auto& type = it.second; + if (type.def.detailed_name.size()) + r.types_def_update.emplace_back(it.first, type.def); + r.types_declarations[type.usr].second = type.declarations; + r.types_uses[type.usr].second = type.uses; + r.types_derived[type.usr].second = type.derived; + r.types_instances[type.usr].second = type.instances; + }; -std::string IndexUpdate::ToString() { - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer(&writer); - IndexUpdate& update = *this; - Reflect(json_writer, update); - return output.GetString(); + for (auto& it : previous->usr2var) { + auto& var = it.second; + if (var.def.spell) + r.vars_removed.push_back(var.usr); + r.vars_declarations[var.usr].first = var.declarations; + r.vars_uses[var.usr].first = var.uses; + } + for (auto& it : current->usr2var) { + auto& var = it.second; + if (var.def.detailed_name.size()) + r.vars_def_update.emplace_back(it.first, var.def); + r.vars_declarations[var.usr].second = var.declarations; + r.vars_uses[var.usr].second = var.uses; + } + + return r; } // ------------------------ @@ -490,11 +310,11 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* u) { // MergeableUpdate def => QueryType // def->def_var_name => std::vector #define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \ - for (auto merge_update : u->update_var_name) { \ - auto& entity = storage_name[merge_update.usr]; \ - AssignFileId(u->file_id, merge_update.to_add); \ - AddRange(u->file_id, entity.def_var_name, merge_update.to_add); \ - RemoveRange(entity.def_var_name, merge_update.to_remove); \ + for (auto& it : u->update_var_name) { \ + auto& entity = storage_name[it.first]; \ + RemoveRange(entity.def_var_name, it.second.first); \ + AssignFileId(u->file_id, it.second.second); \ + AddRange(u->file_id, entity.def_var_name, it.second.second); \ } if (u->files_removed) @@ -534,46 +354,52 @@ int QueryDatabase::Update(QueryFile::DefUpdate&& u) { return existing.id; } -void QueryDatabase::Update(int file_id, std::vector&& updates) { - for (auto& u : updates) { - auto& def = u.value; +void QueryDatabase::Update(int file_id, + std::vector>&& us) { + for (auto& u : us) { + auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); AssignFileId(file_id, def.callees); - QueryFunc& existing = Func(u.usr); + QueryFunc& existing = Func(u.first); + existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { existing.def.push_front(std::move(def)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, existing.usr); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, u.first); } } } -void QueryDatabase::Update(int file_id, std::vector&& updates) { - for (auto& u : updates) { - auto& def = u.value; +void QueryDatabase::Update(int file_id, + std::vector>&& us) { + for (auto& u : us) { + auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); - QueryType& existing = Type(u.usr); + QueryType& existing = Type(u.first); + existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { existing.def.push_front(std::move(def)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, existing.usr); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, u.first); } } } -void QueryDatabase::Update(int file_id, std::vector&& updates) { - for (auto& u : updates) { - auto& def = u.value; +void QueryDatabase::Update(int file_id, + std::vector>&& us) { + for (auto& u : us) { + auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); - QueryVar& existing = Var(u.usr); + QueryVar& existing = Var(u.first); + existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { existing.def.push_front(std::move(def)); if (!existing.def.front().is_local()) - UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, existing.usr); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first); } } } diff --git a/src/query.h b/src/query.h index 18c8ffb67..6cbd9074b 100644 --- a/src/query.h +++ b/src/query.h @@ -13,50 +13,6 @@ struct QueryFunc; struct QueryVar; struct QueryDatabase; -using QueryFileId = Id; -using QueryTypeId = Id; -using QueryFuncId = Id; -using QueryVarId = Id; - -struct IdMap; - -// There are two sources of reindex updates: the (single) definition of a -// symbol has changed, or one of many users of the symbol has changed. -// -// For simplicitly, if the single definition has changed, we update all of the -// associated single-owner definition data. See |Update*DefId|. -// -// If one of the many symbol users submits an update, we store the update such -// that it can be merged with other updates before actually being applied to -// the main database. See |MergeableUpdate|. - -template -struct MergeableUpdate { - // The type/func/var which is getting new usages. - Usr usr; - // Entries to add and remove. - std::vector to_remove; - std::vector to_add; - - MergeableUpdate(Usr usr, - std::vector&& to_remove, - std::vector&& to_add) - : usr(usr), to_remove(std::move(to_remove)), to_add(std::move(to_add)) {} - MergeableUpdate(Usr usr, - const std::vector& to_remove, - const std::vector& to_add) - : usr(usr), to_remove(to_remove), to_add(to_add) {} -}; - -template -struct WithUsr { - Usr usr; - T value; - - WithUsr(Usr usr, const T& value) : usr(usr), value(value) {} - WithUsr(Usr usr, T&& value) : usr(usr), value(value) {} -}; - template struct WithFileContent { T value; @@ -94,7 +50,6 @@ struct QueryFile { template struct QueryEntity { using Def = QDef; - using DefUpdate = WithUsr; Def* AnyDef() { Def* ret = nullptr; for (auto& i : static_cast(this)->def) { @@ -107,8 +62,10 @@ struct QueryEntity { const Def* AnyDef() const { return const_cast(this)->AnyDef(); } }; -using UsrUpdate = MergeableUpdate; -using UseUpdate = MergeableUpdate; +using UseUpdate = + std::unordered_map, std::vector>>; +using UsrUpdate = + std::unordered_map, std::vector>>; struct QueryFunc : QueryEntity { Usr usr; @@ -147,9 +104,6 @@ struct IndexUpdate { // work can be parallelized. void Merge(IndexUpdate&& update); - // Dump the update to a string. - std::string ToString(); - int file_id; // File updates. @@ -158,24 +112,24 @@ struct IndexUpdate { // Function updates. std::vector funcs_removed; - std::vector funcs_def_update; - std::vector funcs_declarations; - std::vector funcs_uses; - std::vector funcs_derived; + std::vector> funcs_def_update; + UseUpdate funcs_declarations; + UseUpdate funcs_uses; + UsrUpdate funcs_derived; // Type updates. std::vector types_removed; - std::vector types_def_update; - std::vector types_declarations; - std::vector types_uses; - std::vector types_derived; - std::vector types_instances; + std::vector> types_def_update; + UseUpdate types_declarations; + UseUpdate types_uses; + UsrUpdate types_derived; + UsrUpdate types_instances; // Variable updates. std::vector vars_removed; - std::vector vars_def_update; - std::vector vars_declarations; - std::vector vars_uses; + std::vector> vars_def_update; + UseUpdate vars_declarations; + UseUpdate vars_uses; }; // The query database is heavily optimized for fast queries. It is stored @@ -196,12 +150,10 @@ struct QueryDatabase { // Insert the contents of |update| into |db|. void ApplyIndexUpdate(IndexUpdate* update); int Update(QueryFile::DefUpdate&& u); - void Update(int file_id, std::vector&& updates); - void Update(int file_id, std::vector&& updates); - void Update(int file_id, std::vector&& updates); - void UpdateSymbols(int* symbol_idx, - SymbolKind kind, - Usr usr); + void Update(int file_id, std::vector>&& us); + void Update(int file_id, std::vector>&& us); + void Update(int file_id, std::vector>&& us); + void UpdateSymbols(int* symbol_idx, SymbolKind kind, Usr usr); std::string_view GetSymbolName(int symbol_idx, bool qualified); QueryFile& GetFile(SymbolIdx ref) { return files[ref.usr]; } diff --git a/src/utils.cc b/src/utils.cc index c9d05a8d3..cf63245fb 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -123,7 +123,7 @@ std::string EscapeFileName(std::string path) { } std::optional ReadContent(const std::string& filename) { - LOG_S(INFO) << "Reading " << filename; + LOG_S(INFO) << "read " << filename; char buf[4096]; std::string ret; FILE* f = fopen(filename.c_str(), "rb"); From 86efddf0327d57e097a1ee8bca82a9bceef16591 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 4 May 2018 20:40:52 -0700 Subject: [PATCH 087/378] README --- CMakeLists.txt | 1 + README.md | 13 +- src/clang_indexer.cc | 21 +-- src/import_pipeline.cc | 243 +++---------------------- src/indexer.h | 6 - src/language.cc | 30 +++ src/language.h | 5 + src/messages/ccls_call_hierarchy.cc | 3 +- src/messages/text_document_did_open.cc | 20 +- src/messages/text_document_hover.cc | 7 +- src/position.h | 15 ++ src/project.cc | 12 -- src/query.cc | 94 ++++------ src/query.h | 3 +- 14 files changed, 140 insertions(+), 333 deletions(-) create mode 100644 src/language.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 97694a29f..ae4500b24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,6 +216,7 @@ target_sources(ccls PRIVATE src/import_pipeline.cc src/include_complete.cc src/method.cc + src/language.cc src/lex_utils.cc src/lsp.cc src/match.cc diff --git a/README.md b/README.md index d64955512..35553bfcf 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ccls is a fork of cquery (originally written by Jacob Dufault), a C/C++/Objective-C language server. * code completion (with both signature help and snippets) - * finding [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc) + * [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc), and other cross references * [call (caller/callee) hierarchy](src/messages/ccls_call_hierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance_hierarchy.cc), [member hierarchy](src/messages/ccls_member_hierarchy.cc) * [symbol rename](src/messages/text_document_rename.cc) * [document symbols](src/messages/text_document_document_symbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) @@ -12,13 +12,12 @@ a C/C++/Objective-C language server. * diagnostics * code actions (clang FixIts) * preprocessor skipped regions - * #include auto-complete, undefined type include insertion, include quick-jump - (goto definition, document links) - * auto-implement functions without a definition * semantic highlighting, including support for [rainbow semantic highlighting](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e) -# >>> [Getting started](https://github.com/MaskRay/ccls/wiki/Getting-started) (CLICK HERE) <<< +It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ]). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. -# License +# >>> [Getting started](../../wiki/Getting-started) (CLICK HERE) <<< -MIT +* [Build](../../wiki/Build) +* [Emacs](../../wiki/Emacs) +* [FAQ](../../wiki/FAQ) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 327d7fc2c..a5df85969 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -718,27 +718,20 @@ std::string IndexFile::ToString() { return Serialize(SerializeFormat::Json, *this); } -void Uniquify(std::vector& ids) { +void Uniquify(std::vector& usrs) { std::unordered_set seen; size_t n = 0; - for (size_t i = 0; i < ids.size(); i++) - if (seen.insert(ids[i]).second) - ids[n++] = ids[i]; - ids.resize(n); + for (size_t i = 0; i < usrs.size(); i++) + if (seen.insert(usrs[i]).second) + usrs[n++] = usrs[i]; + usrs.resize(n); } void Uniquify(std::vector& uses) { - union U { - Range range = {}; - uint64_t u64; - }; - static_assert(sizeof(Range) == 8); - std::unordered_set seen; + std::unordered_set seen; size_t n = 0; for (size_t i = 0; i < uses.size(); i++) { - U u; - u.range = uses[i].range; - if (seen.insert(u.u64).second) + if (seen.insert(uses[i].range).second) uses[n++] = uses[i]; } uses.resize(n); diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index a299f38cd..210dc72b4 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -37,43 +37,6 @@ MAKE_REFLECT_STRUCT(Out_Progress::Params, activeThreads); MAKE_REFLECT_STRUCT(Out_Progress, jsonrpc, method, params); -// Instead of processing messages forever, we only process upto -// |kIterationSize| messages of a type at one time. While the import time -// likely stays the same, this should reduce overall queue lengths which means -// the user gets a usable index faster. -struct IterationLoop { - const int kIterationSize = 100; - int count = 0; - - bool Next() { - return count++ < kIterationSize; - } - void Reset() { - count = 0; - } -}; - -struct IModificationTimestampFetcher { - virtual ~IModificationTimestampFetcher() = default; - virtual std::optional LastWriteTime(const std::string& path) = 0; -}; -struct RealModificationTimestampFetcher : IModificationTimestampFetcher { - // IModificationTimestamp: - std::optional LastWriteTime(const std::string& path) override { - return ::LastWriteTime(path); - } -}; -struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { - std::unordered_map> entries; - - // IModificationTimestamp: - std::optional LastWriteTime(const std::string& path) override { - auto it = entries.find(path); - assert(it != entries.end()); - return it->second; - } -}; - long long GetCurrentTimeInMilliseconds() { auto time_since_epoch = Timer::Clock::now().time_since_epoch(); long long elapsed_milliseconds = @@ -138,7 +101,6 @@ enum class ShouldParse { Yes, No, NoSuchFile }; ShouldParse FileNeedsParse( bool is_interactive, TimestampManager* timestamp_manager, - IModificationTimestampFetcher* modification_timestamp_fetcher, const std::shared_ptr& cache_manager, IndexFile* opt_previous_index, const std::string& path, @@ -150,8 +112,7 @@ ShouldParse FileNeedsParse( return ""; }; - std::optional modification_timestamp = - modification_timestamp_fetcher->LastWriteTime(path); + std::optional modification_timestamp = LastWriteTime(path); // Cannot find file. if (!modification_timestamp) @@ -193,7 +154,6 @@ enum CacheLoadResult { Parse, DoNotParse }; CacheLoadResult TryLoadFromCache( FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, - IModificationTimestampFetcher* modification_timestamp_fetcher, const std::shared_ptr& cache_manager, bool is_interactive, const Project::Entry& entry, @@ -209,10 +169,9 @@ CacheLoadResult TryLoadFromCache( // from cache. // Check timestamps and update |file_consumer_shared|. - ShouldParse path_state = FileNeedsParse( - is_interactive, timestamp_manager, modification_timestamp_fetcher, - cache_manager, previous_index, path_to_index, entry.args, - std::nullopt); + ShouldParse path_state = + FileNeedsParse(is_interactive, timestamp_manager, cache_manager, + previous_index, path_to_index, entry.args, std::nullopt); if (path_state == ShouldParse::Yes) file_consumer_shared->Reset(path_to_index); @@ -228,8 +187,7 @@ CacheLoadResult TryLoadFromCache( for (const std::string& dependency : previous_index->dependencies) { assert(!dependency.empty()); - if (FileNeedsParse(is_interactive, timestamp_manager, - modification_timestamp_fetcher, cache_manager, + if (FileNeedsParse(is_interactive, timestamp_manager, cache_manager, previous_index, dependency, entry.args, previous_index->path) == ShouldParse::Yes) { needs_reparse = true; @@ -245,7 +203,7 @@ CacheLoadResult TryLoadFromCache( return CacheLoadResult::Parse; // No timestamps changed - load directly from cache. - LOG_S(INFO) << "Skipping parse; no timestamp change for " << path_to_index; + LOG_S(INFO) << "load index for " << path_to_index; // TODO/FIXME: real perf PerformanceImportFile perf; @@ -333,7 +291,6 @@ void ParseFile(DiagnosticsEngine* diag_engine, WorkingFiles* working_files, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, - IModificationTimestampFetcher* modification_timestamp_fetcher, IIndexer* indexer, const Index_Request& request, const Project::Entry& entry) { @@ -349,11 +306,9 @@ void ParseFile(DiagnosticsEngine* diag_engine, // Try to load the file from cache. if (TryLoadFromCache(file_consumer_shared, timestamp_manager, - modification_timestamp_fetcher, request.cache_manager, - request.is_interactive, entry, - path_to_index) == CacheLoadResult::DoNotParse) { + request.cache_manager, request.is_interactive, entry, + path_to_index) == CacheLoadResult::DoNotParse) return; - } LOG_S(INFO) << "parse " << path_to_index; std::vector file_contents = PreloadFileContents( @@ -404,7 +359,6 @@ bool IndexMain_DoParse( WorkingFiles* working_files, FileConsumerSharedState* file_consumer_shared, TimestampManager* timestamp_manager, - IModificationTimestampFetcher* modification_timestamp_fetcher, IIndexer* indexer) { auto* queue = QueueManager::instance(); std::optional request = queue->index_request.TryPopFront(); @@ -414,8 +368,7 @@ bool IndexMain_DoParse( Project::Entry entry; entry.filename = request->path; entry.args = request->args; - ParseFile(diag_engine, working_files, file_consumer_shared, - timestamp_manager, modification_timestamp_fetcher, + ParseFile(diag_engine, working_files, file_consumer_shared, timestamp_manager, indexer, request.value(), entry); return true; } @@ -424,8 +377,7 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { auto* queue = QueueManager::instance(); bool did_work = false; - IterationLoop loop; - while (loop.Next()) { + for (int i = 100; i--; ) { std::optional response = queue->on_id_mapped.TryPopFront(); if (!response) return did_work; @@ -434,24 +386,24 @@ bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { Timer time; - // Build delta update. - IndexUpdate update = IndexUpdate::CreateDelta(response->previous.get(), - response->current.get()); - response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); - LOG_S(INFO) << "built index for " << response->current->path - << " (is_delta=" << !!response->previous << ")"; - // Write current index to disk if requested. + std::string path = response->current->path; if (response->write_to_disk) { - LOG_S(INFO) << "store index for " << response->current->path; + LOG_S(INFO) << "store index for " << path; time.Reset(); response->cache_manager->WriteToCache(*response->current); response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); timestamp_manager->UpdateCachedModificationTime( - response->current->path, - response->current->last_modification_time); + path, response->current->last_modification_time); } + // Build delta update. + IndexUpdate update = IndexUpdate::CreateDelta(response->previous.get(), + response->current.get()); + response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); + LOG_S(INFO) << "built index for " << path + << " (is_delta=" << !!response->previous << ")"; + Index_OnIndexed reply(std::move(update), response->perf); queue->on_indexed.PushBack(std::move(reply), response->is_interactive); } @@ -533,7 +485,6 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, Project* project, WorkingFiles* working_files, MultiQueueWaiter* waiter) { - RealModificationTimestampFetcher modification_timestamp_fetcher; auto* queue = QueueManager::instance(); // Build one index per-indexer, as building the index acquires a global lock. auto indexer = std::make_unique(); @@ -555,7 +506,6 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, // index. did_work = IndexMain_DoParse(diag_engine, working_files, file_consumer_shared, timestamp_manager, - &modification_timestamp_fetcher, indexer.get()) || did_work; @@ -614,8 +564,7 @@ bool QueryDb_ImportMain(QueryDatabase* db, bool did_work = false; - IterationLoop loop; - while (loop.Next()) { + for (int i = 80; i--; ) { std::optional response = queue->on_indexed.TryPopFront(); if (!response) break; @@ -626,153 +575,3 @@ bool QueryDb_ImportMain(QueryDatabase* db, return did_work; } - -TEST_SUITE("ImportPipeline") { - struct Fixture { - Fixture() { - g_config = std::make_unique(); - QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); - - queue = QueueManager::instance(); - cache_manager = ICacheManager::MakeFake({}); - indexer = IIndexer::MakeTestIndexer({}); - diag_engine.Init(); - } - - bool PumpOnce() { - return IndexMain_DoParse(&diag_engine, &working_files, - &file_consumer_shared, ×tamp_manager, - &modification_timestamp_fetcher, indexer.get()); - } - - void MakeRequest(const std::string& path, - const std::vector& args = {}, - bool is_interactive = false, - const std::string& contents = "void foo();") { - queue->index_request.PushBack( - Index_Request(path, args, is_interactive, contents, cache_manager)); - } - - MultiQueueWaiter querydb_waiter; - MultiQueueWaiter indexer_waiter; - MultiQueueWaiter stdout_waiter; - - QueueManager* queue = nullptr; - DiagnosticsEngine diag_engine; - WorkingFiles working_files; - FileConsumerSharedState file_consumer_shared; - TimestampManager timestamp_manager; - FakeModificationTimestampFetcher modification_timestamp_fetcher; - std::shared_ptr cache_manager; - std::unique_ptr indexer; - }; - - TEST_CASE_FIXTURE(Fixture, "FileNeedsParse") { - auto check = [&](const std::string& file, bool is_dependency = false, - bool is_interactive = false, - const std::vector& old_args = {}, - const std::vector& new_args = {}) { - std::unique_ptr opt_previous_index; - if (!old_args.empty()) { - opt_previous_index = std::make_unique("---.cc", ""); - opt_previous_index->args = old_args; - } - std::optional from; - if (is_dependency) - from = std::string("---.cc"); - return FileNeedsParse(is_interactive /*is_interactive*/, - ×tamp_manager, &modification_timestamp_fetcher, - cache_manager, opt_previous_index.get(), file, - new_args, from); - }; - - // A file with no timestamp is not imported, since this implies the file no - // longer exists on disk. - modification_timestamp_fetcher.entries["bar.h"] = std::nullopt; - REQUIRE(check("bar.h", false /*is_dependency*/) == ShouldParse::NoSuchFile); - - // A dependency is only imported once. - modification_timestamp_fetcher.entries["foo.h"] = 5; - REQUIRE(check("foo.h", true /*is_dependency*/) == ShouldParse::Yes); - REQUIRE(check("foo.h", true /*is_dependency*/) == ShouldParse::No); - - // An interactive dependency is imported. - REQUIRE(check("foo.h", true /*is_dependency*/) == ShouldParse::No); - REQUIRE(check("foo.h", true /*is_dependency*/, true /*is_interactive*/) == - ShouldParse::Yes); - - // A file whose timestamp has not changed is not imported. When the - // timestamp changes (either forward or backward) it is reimported. - auto check_timestamp_change = [&](int64_t timestamp) { - modification_timestamp_fetcher.entries["aa.cc"] = timestamp; - REQUIRE(check("aa.cc") == ShouldParse::Yes); - REQUIRE(check("aa.cc") == ShouldParse::Yes); - REQUIRE(check("aa.cc") == ShouldParse::Yes); - timestamp_manager.UpdateCachedModificationTime("aa.cc", timestamp); - REQUIRE(check("aa.cc") == ShouldParse::No); - }; - check_timestamp_change(5); - check_timestamp_change(6); - check_timestamp_change(5); - check_timestamp_change(4); - - // Argument change implies reimport, even if timestamp has not changed. - timestamp_manager.UpdateCachedModificationTime("aa.cc", 5); - modification_timestamp_fetcher.entries["aa.cc"] = 5; - REQUIRE(check("aa.cc", false /*is_dependency*/, false /*is_interactive*/, - {"b"} /*old_args*/, - {"b", "a"} /*new_args*/) == ShouldParse::Yes); - } - - // FIXME: validate other state like timestamp_manager, etc. - // FIXME: add more interesting tests that are not the happy path - // FIXME: test - // - IndexMain_DoCreateIndexUpdate - // - IndexMain_LoadPreviousIndex - // - QueryDb_ImportMain - - TEST_CASE_FIXTURE(Fixture, "index request with zero results") { - indexer = IIndexer::MakeTestIndexer({IIndexer::TestEntry{"foo.cc", 0}}); - - MakeRequest("foo.cc"); - - REQUIRE(queue->index_request.Size() == 1); - REQUIRE(queue->on_id_mapped.Size() == 0); - PumpOnce(); - REQUIRE(queue->index_request.Size() == 0); - REQUIRE(queue->on_id_mapped.Size() == 0); - - REQUIRE(file_consumer_shared.used_files.empty()); - } - - TEST_CASE_FIXTURE(Fixture, "one index request") { - indexer = IIndexer::MakeTestIndexer({IIndexer::TestEntry{"foo.cc", 100}}); - - MakeRequest("foo.cc"); - - REQUIRE(queue->index_request.Size() == 1); - REQUIRE(queue->on_id_mapped.Size() == 0); - PumpOnce(); - REQUIRE(queue->index_request.Size() == 0); - REQUIRE(queue->on_id_mapped.Size() == 100); - - REQUIRE(file_consumer_shared.used_files.empty()); - } - - TEST_CASE_FIXTURE(Fixture, "multiple index requests") { - indexer = IIndexer::MakeTestIndexer( - {IIndexer::TestEntry{"foo.cc", 100}, IIndexer::TestEntry{"bar.cc", 5}}); - - MakeRequest("foo.cc"); - MakeRequest("bar.cc"); - - REQUIRE(queue->index_request.Size() == 2); - //REQUIRE(queue->do_id_map.Size() == 0); - while (PumpOnce()) { - } - REQUIRE(queue->index_request.Size() == 0); - //REQUIRE(queue->do_id_map.Size() == 105); - - REQUIRE(file_consumer_shared.used_files.empty()); - } -} diff --git a/src/indexer.h b/src/indexer.h index c675c749b..d332e1fad 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -105,7 +105,6 @@ struct FuncDef : NameMixin { // Functions that this function calls. std::vector callees; - int file_id; // Type which declares this one (ie, it is a method) Usr declaring_type = 0; int16_t qual_name_offset = 0; @@ -133,7 +132,6 @@ MAKE_REFLECT_STRUCT(FuncDef, comments, spell, extent, - file_id, declaring_type, bases, vars, @@ -177,7 +175,6 @@ struct TypeDef : NameMixin { // If set, then this is the same underlying type as the given value (ie, this // type comes from a using or typedef statement). Usr alias_of = 0; - int file_id; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; @@ -201,7 +198,6 @@ MAKE_REFLECT_STRUCT(TypeDef, comments, spell, extent, - file_id, alias_of, bases, types, @@ -228,7 +224,6 @@ struct VarDef : NameMixin { Maybe spell; Maybe extent; - int file_id; // Type of the variable. Usr type = 0; @@ -259,7 +254,6 @@ MAKE_REFLECT_STRUCT(VarDef, comments, spell, extent, - file_id, type, kind, storage); diff --git a/src/language.cc b/src/language.cc new file mode 100644 index 000000000..ee749fcf1 --- /dev/null +++ b/src/language.cc @@ -0,0 +1,30 @@ +#include "language.h" + +#include "utils.h" + +LanguageId SourceFileLanguage(std::string_view path) { + if (EndsWith(path, ".c")) + return LanguageId::C; + else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc")) + return LanguageId::Cpp; + else if (EndsWith(path, ".mm")) + return LanguageId::ObjCpp; + else if (EndsWith(path, ".m")) + return LanguageId::ObjC; + return LanguageId::Unknown; +} + +const char* LanguageIdentifier(LanguageId lang) { + switch (lang) { + case LanguageId::C: + return "c"; + case LanguageId::Cpp: + return "cpp"; + case LanguageId::ObjC: + return "objective-c"; + case LanguageId::ObjCpp: + return "objective-cpp"; + default: + return ""; + } +} diff --git a/src/language.h b/src/language.h index 393423cf3..c2bc335cb 100644 --- a/src/language.h +++ b/src/language.h @@ -2,8 +2,13 @@ #include "serializer.h" +#include + // Used to identify the language at a file level. The ordering is important, as // a file previously identified as `C`, will be changed to `Cpp` if it // encounters a c++ declaration. enum class LanguageId { Unknown = 0, C = 1, Cpp = 2, ObjC = 3, ObjCpp = 4 }; MAKE_REFLECT_TYPE_PROXY(LanguageId); + +LanguageId SourceFileLanguage(std::string_view path); +const char* LanguageIdentifier(LanguageId lang); diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 410cfdcf8..3b3794c1a 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -108,7 +108,8 @@ bool Expand(MessageHandler* m, if (const auto* def = func.AnyDef()) for (SymbolRef ref : def->callees) if (ref.kind == SymbolKind::Func) - handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id}, + handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, + def->spell->file_id}, call_type); } else { for (Use use : func.uses) diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 06c83fa2e..20d8e2567 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -61,19 +61,21 @@ struct Handler_TextDocumentDidOpen include_complete->AddFile(working_file->filename); clang_complete->NotifyView(path); + if (params.args.size()) + project->SetFlagsForFile(params.args, path); - // Submit new index request. - Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( + // Submit new index request if it is not a header file. + if (SourceFileLanguage(path) != LanguageId::Unknown) { + Project::Entry entry = project->FindCompilationEntryForFile(path); + QueueManager::instance()->index_request.PushBack( Index_Request( - entry.filename, params.args.size() ? params.args : entry.args, - true /*is_interactive*/, params.textDocument.text, cache_manager), + entry.filename, params.args.size() ? params.args : entry.args, + true /*is_interactive*/, params.textDocument.text, cache_manager), true /* priority */); - clang_complete->FlushSession(entry.filename); - LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; - if (params.args.size()) - project->SetFlagsForFile(params.args, path); + clang_complete->FlushSession(entry.filename); + LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; + } } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 7ea1aeee3..455c61c53 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -21,14 +21,13 @@ std::optional GetComments(QueryDatabase* db, SymbolRef sym) { // Returns the hover or detailed name for `sym`, if any. std::optional GetHoverOrName(QueryDatabase* db, - const std::string& language, - SymbolRef sym) { - + LanguageId lang, + SymbolRef sym) { std::optional ret; WithEntity(db, sym, [&](const auto& entity) { if (const auto* def = entity.AnyDef()) { lsMarkedString m; - m.language = language; + m.language = LanguageIdentifier(lang); if (!def->hover.empty()) { m.value = def->hover; ret = m; diff --git a/src/position.h b/src/position.h index 748bb741e..99ec77620 100644 --- a/src/position.h +++ b/src/position.h @@ -48,6 +48,21 @@ struct Range { } }; +namespace std { +template <> +struct hash { + std::size_t operator()(Range x) const { + union U { + Range range = {}; + uint64_t u64; + } u; + static_assert(sizeof(Range) == 8); + u.range = x; + return hash()(u.u64); + } +}; +} + // Reflection class Reader; class Writer; diff --git a/src/project.cc b/src/project.cc index 4ced67fba..d45cd0633 100644 --- a/src/project.cc +++ b/src/project.cc @@ -91,18 +91,6 @@ bool ShouldAddToAngleIncludes(const std::string& arg) { return StartsWithAny(arg, kAngleIncludeArgs); } -LanguageId SourceFileLanguage(const std::string& path) { - if (EndsWith(path, ".c")) - return LanguageId::C; - else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc")) - return LanguageId::Cpp; - else if (EndsWith(path, ".mm")) - return LanguageId::ObjCpp; - else if (EndsWith(path, ".m")) - return LanguageId::ObjC; - return LanguageId::Unknown; -} - Project::Entry GetCompilationEntryFromCompileCommandEntry( ProjectConfig* config, const CompileCommandsEntry& entry) { diff --git a/src/query.cc b/src/query.cc index 87fc67eb2..761ca5e1f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -17,8 +17,7 @@ #include // Used by |HANDLE_MERGEABLE| so only |range| is needed. -MAKE_HASHABLE(Range, t.start, t.end); -MAKE_HASHABLE(Use, t.range); +MAKE_HASHABLE(Use, t.range, t.file_id); namespace { @@ -48,7 +47,6 @@ void AssignFileId(int file_id, std::vector& xs) { AssignFileId(file_id, x); } - void AddRange(int file_id, std::vector& into, const std::vector& from) { into.reserve(into.size() + from.size()); for (Use use : from) { @@ -62,39 +60,24 @@ void AddRange(int _, std::vector& into, const std::vector& from) { } template -void RemoveRange(std::vector& dest, const std::vector& to_remove) { +void RemoveRange(std::vector& from, const std::vector& to_remove) { if (to_remove.size()) { std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); - dest.erase( - std::remove_if(dest.begin(), dest.end(), + from.erase( + std::remove_if(from.begin(), from.end(), [&](const T& t) { return to_remove_set.count(t) > 0; }), - dest.end()); + from.end()); } } QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { QueryFile::Def def; - def.path = indexed.path; - def.args = indexed.args; - def.includes = indexed.includes; - def.inactive_regions = indexed.skipped_by_preprocessor; - def.dependencies = indexed.dependencies; - - // Convert enum to markdown compatible strings - def.language = [&indexed]() { - switch (indexed.language) { - case LanguageId::C: - return "c"; - case LanguageId::Cpp: - return "cpp"; - case LanguageId::ObjC: - return "objective-c"; - case LanguageId::ObjCpp: - return "objective-cpp"; - default: - return ""; - } - }(); + def.path = std::move(indexed.path); + def.args = std::move(indexed.args); + def.includes = std::move(indexed.includes); + def.inactive_regions = std::move(indexed.skipped_by_preprocessor); + def.dependencies = std::move(indexed.dependencies); + def.language = indexed.language; auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { def.all_symbols.push_back(SymbolRef(use.range, usr, kind, use.role)); @@ -172,10 +155,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { template bool TryReplaceDef(std::forward_list& def_list, Q&& def) { for (auto& def1 : def_list) - if (def1.file_id == def.file_id) { - if (!def1.spell || def.spell) { - def1 = std::move(def); - } + if (def1.spell->file_id == def.spell->file_id) { + def1 = std::move(def); return true; } return false; @@ -195,57 +176,57 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, if (!previous) previous = ∅ - r.files_def_update = BuildFileDefUpdate(*current); + r.files_def_update = BuildFileDefUpdate(std::move(*current)); for (auto& it : previous->usr2func) { auto& func = it.second; if (func.def.spell) r.funcs_removed.push_back(func.usr); - r.funcs_declarations[func.usr].first = func.declarations; - r.funcs_uses[func.usr].first = func.uses; - r.funcs_derived[func.usr].first = func.derived; + r.funcs_declarations[func.usr].first = std::move(func.declarations); + r.funcs_uses[func.usr].first = std::move(func.uses); + r.funcs_derived[func.usr].first = std::move(func.derived); } for (auto& it : current->usr2func) { auto& func = it.second; - if (func.def.detailed_name.size()) + if (func.def.spell && func.def.detailed_name.size()) r.funcs_def_update.emplace_back(it.first, func.def); - r.funcs_declarations[func.usr].second = func.declarations; - r.funcs_uses[func.usr].second = func.uses; - r.funcs_derived[func.usr].second = func.derived; + r.funcs_declarations[func.usr].second = std::move(func.declarations); + r.funcs_uses[func.usr].second = std::move(func.uses); + r.funcs_derived[func.usr].second = std::move(func.derived); } for (auto& it : previous->usr2type) { auto& type = it.second; if (type.def.spell) r.types_removed.push_back(type.usr); - r.types_declarations[type.usr].first = type.declarations; - r.types_uses[type.usr].first = type.uses; - r.types_derived[type.usr].first = type.derived; - r.types_instances[type.usr].first = type.instances; + r.types_declarations[type.usr].first = std::move(type.declarations); + r.types_uses[type.usr].first = std::move(type.uses); + r.types_derived[type.usr].first = std::move(type.derived); + r.types_instances[type.usr].first = std::move(type.instances); }; for (auto& it : current->usr2type) { auto& type = it.second; - if (type.def.detailed_name.size()) + if (type.def.spell && type.def.detailed_name.size()) r.types_def_update.emplace_back(it.first, type.def); - r.types_declarations[type.usr].second = type.declarations; - r.types_uses[type.usr].second = type.uses; - r.types_derived[type.usr].second = type.derived; - r.types_instances[type.usr].second = type.instances; + r.types_declarations[type.usr].second = std::move(type.declarations); + r.types_uses[type.usr].second = std::move(type.uses); + r.types_derived[type.usr].second = std::move(type.derived); + r.types_instances[type.usr].second = std::move(type.instances); }; for (auto& it : previous->usr2var) { auto& var = it.second; if (var.def.spell) r.vars_removed.push_back(var.usr); - r.vars_declarations[var.usr].first = var.declarations; - r.vars_uses[var.usr].first = var.uses; + r.vars_declarations[var.usr].first = std::move(var.declarations); + r.vars_uses[var.usr].first = std::move(var.uses); } for (auto& it : current->usr2var) { auto& var = it.second; - if (var.def.detailed_name.size()) + if (var.def.spell && var.def.detailed_name.size()) r.vars_def_update.emplace_back(it.first, var.def); - r.vars_declarations[var.usr].second = var.declarations; - r.vars_uses[var.usr].second = var.uses; + r.vars_declarations[var.usr].second = std::move(var.declarations); + r.vars_uses[var.usr].second = std::move(var.uses); } return r; @@ -281,7 +262,7 @@ void QueryDatabase::RemoveUsrs( for (auto usr : to_remove) { QueryFunc& func = Func(usr); func.def.remove_if([=](const QueryFunc::Def& def) { - return def.file_id == file_id; + return def.spell->file_id == file_id; }); } break; @@ -290,7 +271,7 @@ void QueryDatabase::RemoveUsrs( for (auto usr : to_remove) { QueryVar& var = Var(usr); var.def.remove_if([=](const QueryVar::Def& def) { - return def.file_id == file_id; + return def.spell->file_id == file_id; }); } break; @@ -312,6 +293,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* u) { #define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \ for (auto& it : u->update_var_name) { \ auto& entity = storage_name[it.first]; \ + AssignFileId(u->file_id, it.second.first); \ RemoveRange(entity.def_var_name, it.second.first); \ AssignFileId(u->file_id, it.second.second); \ AddRange(u->file_id, entity.def_var_name, it.second.second); \ diff --git a/src/query.h b/src/query.h index 6cbd9074b..51d96ef32 100644 --- a/src/query.h +++ b/src/query.h @@ -26,8 +26,7 @@ struct QueryFile { struct Def { std::string path; std::vector args; - // Language identifier - std::string language; + LanguageId language; // Includes in the file. std::vector includes; // Outline of the file (ie, for code lens). From 984c6367d194499a154e8fe47e5dc4fc77d00d58 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 5 May 2018 15:29:17 -0700 Subject: [PATCH 088/378] Redesign import_pipeline.cc and mitigate race (duplicate Query*::uses for initial indexing) --- CMakeLists.txt | 1 - src/cache_manager.cc | 149 ++--- src/cache_manager.h | 30 +- src/clang_complete.cc | 2 - src/clang_complete.h | 2 - src/clang_indexer.cc | 38 +- src/command_line.cc | 18 +- src/config.cc | 1 + src/config.h | 54 +- src/file_consumer.cc | 50 +- src/file_consumer.h | 23 +- src/import_pipeline.cc | 548 ++++-------------- src/import_pipeline.h | 41 +- src/indexer.h | 14 +- src/message_handler.cc | 10 +- src/message_handler.h | 8 +- src/messages/ccls_call_hierarchy.cc | 2 + src/messages/ccls_freshen_index.cc | 24 +- src/messages/ccls_index_file.cc | 40 -- src/messages/ccls_member_hierarchy.cc | 2 + src/messages/initialize.cc | 10 +- src/messages/text_document_did_change.cc | 2 +- src/messages/text_document_did_open.cc | 17 +- src/messages/text_document_did_save.cc | 2 +- .../workspace_did_change_watched_files.cc | 18 +- src/port.h | 4 + src/project.cc | 24 +- src/project.h | 4 +- src/query.cc | 4 +- src/queue_manager.cc | 10 +- src/queue_manager.h | 5 - src/serializer.cc | 26 +- src/serializer.h | 8 +- src/test.cc | 4 +- 34 files changed, 358 insertions(+), 837 deletions(-) delete mode 100644 src/messages/ccls_index_file.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index ae4500b24..136591324 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,6 @@ target_sources(ccls PRIVATE src/messages/ccls_derived.cc src/messages/ccls_file_info.cc src/messages/ccls_freshen_index.cc - src/messages/ccls_index_file.cc src/messages/ccls_inheritance_hierarchy.cc src/messages/ccls_member_hierarchy.cc src/messages/ccls_random.cc diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 2c67b63a1..79a159a43 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -11,129 +11,54 @@ #include namespace { - -// Manages loading caches from file paths for the indexer process. -struct RealCacheManager : ICacheManager { - explicit RealCacheManager() {} - ~RealCacheManager() override = default; - - void WriteToCache(IndexFile& file) override { - std::string cache_path = GetCachePath(file.path); - WriteToFile(cache_path, file.file_contents); - - std::string indexed_content = Serialize(g_config->cacheFormat, file); - WriteToFile(AppendSerializationFormat(cache_path), indexed_content); - } - - std::optional LoadCachedFileContents( - const std::string& path) override { - return ReadContent(GetCachePath(path)); - } - - std::unique_ptr RawCacheLoad(const std::string& path) override { - std::string cache_path = GetCachePath(path); - std::optional file_content = ReadContent(cache_path); - std::optional serialized_indexed_content = - ReadContent(AppendSerializationFormat(cache_path)); - if (!file_content || !serialized_indexed_content) - return nullptr; - - return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, - *file_content, IndexFile::kMajorVersion); - } - - std::string GetCachePath(const std::string& source_file) { - assert(!g_config->cacheDirectory.empty()); - std::string cache_file; - size_t len = g_config->projectRoot.size(); - if (StartsWith(source_file, g_config->projectRoot)) { - cache_file = EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file.substr(len)); - } else { - cache_file = '@' + EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file); - } - - return g_config->cacheDirectory + cache_file; - } - - std::string AppendSerializationFormat(const std::string& base) { - switch (g_config->cacheFormat) { - case SerializeFormat::Binary: - return base + ".blob"; - case SerializeFormat::Json: - return base + ".json"; - } - } -}; - -struct FakeCacheManager : ICacheManager { - explicit FakeCacheManager(const std::vector& entries) - : entries_(entries) {} - - void WriteToCache(IndexFile& file) override { assert(false); } - - std::optional LoadCachedFileContents( - const std::string& path) override { - for (const FakeCacheEntry& entry : entries_) { - if (entry.path == path) { - return entry.content; - } - } - - return std::nullopt; +std::string GetCachePath(const std::string& source_file) { + assert(!g_config->cacheDirectory.empty()); + std::string cache_file; + size_t len = g_config->projectRoot.size(); + if (StartsWith(source_file, g_config->projectRoot)) { + cache_file = EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file.substr(len)); + } else { + cache_file = '@' + EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file); } - std::unique_ptr RawCacheLoad(const std::string& path) override { - for (const FakeCacheEntry& entry : entries_) { - if (entry.path == path) { - return Deserialize(SerializeFormat::Json, path, entry.json, "", - std::nullopt); - } - } + return g_config->cacheDirectory + cache_file; +} - return nullptr; +std::string AppendSerializationFormat(const std::string& base) { + switch (g_config->cacheFormat) { + case SerializeFormat::Binary: + return base + ".blob"; + case SerializeFormat::Json: + return base + ".json"; } - - std::vector entries_; -}; - -} // namespace - -// static -std::shared_ptr ICacheManager::Make() { - return std::make_shared(); } - -// static -std::shared_ptr ICacheManager::MakeFake( - const std::vector& entries) { - return std::make_shared(entries); } -ICacheManager::~ICacheManager() = default; - -IndexFile* ICacheManager::TryLoad(const std::string& path) { - auto it = caches_.find(path); - if (it != caches_.end()) - return it->second.get(); +// Manages loading caches from file paths for the indexer process. +void ICacheManager::WriteToCache(IndexFile& file) { + std::string cache_path = GetCachePath(file.path); + WriteToFile(cache_path, file.file_contents); - std::unique_ptr cache = RawCacheLoad(path); - if (!cache) - return nullptr; + std::string indexed_content = Serialize(g_config->cacheFormat, file); + WriteToFile(AppendSerializationFormat(cache_path), indexed_content); +} - caches_[path] = std::move(cache); - return caches_[path].get(); +std::optional ICacheManager::LoadCachedFileContents( + const std::string& path) { + return ReadContent(GetCachePath(path)); } -std::unique_ptr ICacheManager::TryTakeOrLoad( +std::unique_ptr ICacheManager::RawCacheLoad( const std::string& path) { - auto it = caches_.find(path); - if (it != caches_.end()) { - auto result = std::move(it->second); - caches_.erase(it); - return result; - } + std::string cache_path = GetCachePath(path); + std::optional file_content = ReadContent(cache_path); + std::optional serialized_indexed_content = + ReadContent(AppendSerializationFormat(cache_path)); + if (!file_content || !serialized_indexed_content) + return nullptr; - return RawCacheLoad(path); + return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, + *file_content, IndexFile::kMajorVersion); } diff --git a/src/cache_manager.h b/src/cache_manager.h index a410d608a..daffdd48c 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -7,34 +7,12 @@ #include #include -struct Config; struct IndexFile; struct ICacheManager { - struct FakeCacheEntry { - std::string path; - std::string content; - std::string json; - }; + void WriteToCache(IndexFile& file); - static std::shared_ptr Make(); - static std::shared_ptr MakeFake( - const std::vector& entries); - - virtual ~ICacheManager(); - - // Tries to load a cache for |path|, returning null if there is none. The - // cache loader still owns the cache. - IndexFile* TryLoad(const std::string& path); - - // Takes the existing cache or loads the cache at |path|. May return null if - // the cache does not exist. - std::unique_ptr TryTakeOrLoad(const std::string& path); - - virtual void WriteToCache(IndexFile& file) = 0; - - virtual std::optional LoadCachedFileContents( - const std::string& path) = 0; + std::optional LoadCachedFileContents(const std::string& path); template void IterateLoadedCaches(Fn fn) { @@ -42,7 +20,7 @@ struct ICacheManager { fn(cache.second.get()); } - protected: - virtual std::unique_ptr RawCacheLoad(const std::string& path) = 0; + std::unique_ptr RawCacheLoad(const std::string& path); + std::unordered_map> caches_; }; diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 25eec8e75..029618260 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -647,12 +647,10 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { ClangCompleteManager::ClangCompleteManager(Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic, - OnIndex on_index, OnDropped on_dropped) : project_(project), working_files_(working_files), on_diagnostic_(on_diagnostic), - on_index_(on_index), on_dropped_(on_dropped), preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { diff --git a/src/clang_complete.h b/src/clang_complete.h index 7eace6269..ee0cd6a7b 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -82,7 +82,6 @@ struct ClangCompleteManager { ClangCompleteManager(Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic, - OnIndex on_index, OnDropped on_dropped); // Start a code completion at the given location. |on_complete| will run when @@ -127,7 +126,6 @@ struct ClangCompleteManager { Project* project_; WorkingFiles* working_files_; OnDiagnostic on_diagnostic_; - OnIndex on_index_; OnDropped on_dropped_; using LruSessionCache = LruCache; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index a5df85969..355cda294 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -9,11 +9,12 @@ #include +#include #include #include #include -#include #include +#include #if CINDEX_VERSION >= 47 #define CINDEX_HAVE_PRETTY 1 @@ -279,7 +280,7 @@ struct IndexParam { std::unordered_set seen_cx_files; std::vector seen_files; std::unordered_map file_contents; - std::unordered_map file_modification_times; + std::unordered_map file2write_time; // Only use this when strictly needed (ie, primary translation unit is // needed). Most logic should get the IndexFile instance via @@ -373,11 +374,11 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { param->seen_files.push_back(file_name); // Set modification time. - std::optional modification_time = LastWriteTime(file_name); - LOG_IF_S(ERROR, !modification_time) - << "Failed fetching modification time for " << file_name; - if (modification_time) - param->file_modification_times[file_name] = *modification_time; + std::optional write_time = LastWriteTime(file_name); + LOG_IF_S(ERROR, !write_time) << "failed to fetch write time for " + << file_name; + if (write_time) + param->file2write_time[file_name] = *write_time; } } @@ -2010,7 +2011,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } std::vector> Parse( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, @@ -2041,12 +2042,11 @@ std::vector> Parse( perf->index_parse = timer.ElapsedMicrosecondsAndReset(); - return ParseWithTu(file_consumer_shared, perf, tu.get(), index, file, - args, unsaved_files); + return ParseWithTu(vfs, perf, tu.get(), index, file, args, unsaved_files); } std::vector> ParseWithTu( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, PerformanceImportFile* perf, ClangTranslationUnit* tu, ClangIndex* index, @@ -2067,7 +2067,7 @@ std::vector> ParseWithTu( callback.indexDeclaration = &OnIndexDeclaration; callback.indexEntityReference = &OnIndexReference; - FileConsumer file_consumer(file_consumer_shared, file); + FileConsumer file_consumer(vfs, file); IndexParam param(tu, &file_consumer); for (const CXUnsavedFile& contents : file_contents) { param.file_contents[contents.Filename] = FileContents( @@ -2140,15 +2140,13 @@ std::vector> ParseWithTu( } // Update file contents and modification time. - entry->last_modification_time = param.file_modification_times[entry->path]; + entry->last_write_time = param.file2write_time[entry->path]; // Update dependencies for the file. Do not include the file in its own // dependency set. - entry->dependencies = param.seen_files; - entry->dependencies.erase( - std::remove(entry->dependencies.begin(), entry->dependencies.end(), - entry->path), - entry->dependencies.end()); + for (const std::string& path : param.seen_files) + if (path != entry->path && path != entry->import_file) + entry->dependencies[path] = param.file2write_time[path]; } return result; @@ -2229,10 +2227,8 @@ struct TestIndexer : IIndexer { return result; } - ~TestIndexer() override = default; - std::vector> Index( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, diff --git a/src/command_line.cc b/src/command_line.cc index 5109dcf7c..70599b012 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -110,9 +110,8 @@ See more on https://github.com/MaskRay/ccls/wiki bool QueryDbMainLoop(QueryDatabase* db, MultiQueueWaiter* waiter, Project* project, - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, ImportPipelineStatus* status, - TimestampManager* timestamp_manager, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, ClangCompleteManager* clang_complete, @@ -154,7 +153,7 @@ void RunQueryDbThread(const std::string& bin_name, Project project; SemanticHighlightSymbolCache semantic_cache; WorkingFiles working_files; - FileConsumerSharedState file_consumer_shared; + VFS vfs; DiagnosticsEngine diag_engine; ClangCompleteManager clang_complete( @@ -162,11 +161,6 @@ void RunQueryDbThread(const std::string& bin_name, [&](std::string path, std::vector diagnostics) { diag_engine.Publish(&working_files, path, diagnostics); }, - [&](ClangTranslationUnit* tu, const std::vector& unsaved, - const std::string& path, const std::vector& args) { - IndexWithTuFromCodeCompletion(&file_consumer_shared, tu, unsaved, path, - args); - }, [](lsRequestId id) { if (id.Valid()) { Out_Error out; @@ -184,7 +178,6 @@ void RunQueryDbThread(const std::string& bin_name, auto non_global_code_complete_cache = std::make_unique(); auto signature_cache = std::make_unique(); ImportPipelineStatus import_pipeline_status; - TimestampManager timestamp_manager; QueryDatabase db; // Setup shared references. @@ -193,9 +186,8 @@ void RunQueryDbThread(const std::string& bin_name, handler->waiter = indexer_waiter; handler->project = &project; handler->diag_engine = &diag_engine; - handler->file_consumer_shared = &file_consumer_shared; + handler->vfs = &vfs; handler->import_pipeline_status = &import_pipeline_status; - handler->timestamp_manager = ×tamp_manager; handler->semantic_cache = &semantic_cache; handler->working_files = &working_files; handler->clang_complete = &clang_complete; @@ -210,8 +202,8 @@ void RunQueryDbThread(const std::string& bin_name, SetThreadName("querydb"); while (true) { bool did_work = QueryDbMainLoop( - &db, querydb_waiter, &project, &file_consumer_shared, - &import_pipeline_status, ×tamp_manager, + &db, querydb_waiter, &project, &vfs, + &import_pipeline_status, &semantic_cache, &working_files, &clang_complete, &include_complete, global_code_complete_cache.get(), non_global_code_complete_cache.get(), signature_cache.get()); diff --git a/src/config.cc b/src/config.cc index 68cdecc4c..102d05a6e 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,3 +1,4 @@ #include "config.h" std::unique_ptr g_config; +thread_local int g_thread_id; diff --git a/src/config.h b/src/config.h index c0d3774a8..ba90abbc6 100644 --- a/src/config.h +++ b/src/config.h @@ -42,44 +42,22 @@ struct Config { // It is not schema-aware and you need to re-index whenever a struct // member has changed. SerializeFormat cacheFormat = SerializeFormat::Binary; - // Value to use for clang -resource-dir if not present in - // compile_commands.json. - // - // ccls includes a resource directory, this should not need to be configured - // unless you're using an esoteric configuration. Consider reporting a bug and - // fixing upstream instead of configuring this. - // - // Example value: "/path/to/lib/clang/5.0.1/" - std::string resourceDirectory; - - // Additional arguments to pass to clang. - std::vector extraClangArguments; - - // If true, ccls will send progress reports while indexing - // How often should ccls send progress report messages? - // -1: never - // 0: as often as possible - // xxx: at most every xxx milliseconds - // - // Empty progress reports (ie, idle) are delivered as often as they are - // available and may exceed this value. - // - // This does not guarantee a progress report will be delivered every - // interval; it could take significantly longer if ccls is completely idle. - int progressReportFrequencyMs = 500; - // If true, document links are reported for #include directives. - bool showDocumentLinksOnIncludes = true; + struct Clang { + // Additional arguments to pass to clang. + std::vector extraArgs; - // Version of the client. If undefined the version check is skipped. Used to - // inform users their vscode client is too old and needs to be updated. - std::optional clientVersion; + // Value to use for clang -resource-dir if not specified. + // + // This option defaults to clang -print-resource-dir and should not be + // specified unless you are using an esoteric configuration. + std::string resourceDir; + } clang; struct ClientCapability { // TextDocumentClientCapabilities.completion.completionItem.snippetSupport bool snippetSupport = false; - }; - ClientCapability client; + } client; struct CodeLens { // Enables code lens on parameter and function variables. @@ -228,6 +206,7 @@ struct Config { int maxNum = 2000; } xref; }; +MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, @@ -260,16 +239,8 @@ MAKE_REFLECT_STRUCT(Config, compilationDatabaseDirectory, cacheDirectory, cacheFormat, - resourceDirectory, - - extraClangArguments, - - progressReportFrequencyMs, - - showDocumentLinksOnIncludes, - - clientVersion, + clang, client, codeLens, completion, @@ -280,3 +251,4 @@ MAKE_REFLECT_STRUCT(Config, xref); extern std::unique_ptr g_config; +thread_local extern int g_thread_id; diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 6ba69cfb3..5db6afca3 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -55,21 +55,48 @@ std::optional FileContents::ContentsInRange(Range range) const { return std::nullopt; } -bool FileConsumerSharedState::Mark(const std::string& file) { +VFS::State VFS::Get(const std::string& file) { std::lock_guard lock(mutex); - return used_files.insert(file).second; + auto it = state.find(file); + if (it != state.end()) + return it->second; + return {0, 0, 0}; } -void FileConsumerSharedState::Reset(const std::string& file) { +bool VFS::Mark(const std::string& file, int owner, int stage) { std::lock_guard lock(mutex); - auto it = used_files.find(file); - if (it != used_files.end()) - used_files.erase(it); + State& st = state[file]; + if (st.stage < stage) { + st.owner = owner; + st.stage = stage; + return true; + } else + return false; } -FileConsumer::FileConsumer(FileConsumerSharedState* shared_state, - const std::string& parse_file) - : shared_(shared_state), parse_file_(parse_file) {} +bool VFS::Stamp(const std::string& file, int64_t ts) { + std::lock_guard lock(mutex); + State& st = state[file]; + if (st.timestamp < ts) { + st.timestamp = ts; + return true; + } else + return false; +} + +void VFS::ResetLocked(const std::string& file) { + State& st = state[file]; + if (st.owner == g_thread_id) + st.stage = 0; +} + +void VFS::Reset(const std::string& file) { + std::lock_guard lock(mutex); + ResetLocked(file); +} + +FileConsumer::FileConsumer(VFS* vfs, const std::string& parse_file) + : vfs_(vfs), parse_file_(parse_file), thread_id_(g_thread_id) {} IndexFile* FileConsumer::TryConsumeFile( CXFile file, @@ -96,12 +123,9 @@ IndexFile* FileConsumer::TryConsumeFile( std::string file_name = FileName(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) { + if (!vfs_->Mark(file_name, thread_id_, 2)) { local_[file_id] = nullptr; return nullptr; } diff --git a/src/file_consumer.h b/src/file_consumer.h index 4f8216a40..eb006a32a 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -8,7 +8,6 @@ #include #include #include -#include #include struct IndexFile; @@ -30,13 +29,19 @@ struct FileContents { std::vector line_offsets_; }; -struct FileConsumerSharedState { - mutable std::unordered_set used_files; +struct VFS { + struct State { + int64_t timestamp; + int owner; + int stage; + }; + mutable std::unordered_map state; mutable std::mutex mutex; - // Mark the file as used. Returns true if the file was not previously used. - bool Mark(const std::string& file); - // Reset the used state (ie, mark the file as unused). + State Get(const std::string& file); + bool Mark(const std::string& file, int owner, int stage); + bool Stamp(const std::string& file, int64_t ts); + void ResetLocked(const std::string& file); void Reset(const std::string& file); }; @@ -48,8 +53,7 @@ struct FileConsumerSharedState { // The indexer does this because header files do not have their own translation // units but we still want to index them. struct FileConsumer { - FileConsumer(FileConsumerSharedState* shared_state, - const std::string& parse_file); + FileConsumer(VFS* vfs, const std::string& parse_file); // Returns true if this instance owns given |file|. This will also attempt to // take ownership over |file|. @@ -69,6 +73,7 @@ struct FileConsumer { private: std::unordered_map> local_; - FileConsumerSharedState* shared_; + VFS* vfs_; std::string parse_file_; + int thread_id_; }; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 210dc72b4..14a341d2d 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -18,115 +18,25 @@ namespace { -struct Out_Progress : public lsOutMessage { - struct Params { - int indexRequestCount = 0; - int loadPreviousIndexCount = 0; - int onIdMappedCount = 0; - int onIndexedCount = 0; - int activeThreads = 0; - }; - std::string method = "$ccls/progress"; - Params params; -}; -MAKE_REFLECT_STRUCT(Out_Progress::Params, - indexRequestCount, - loadPreviousIndexCount, - onIdMappedCount, - onIndexedCount, - activeThreads); -MAKE_REFLECT_STRUCT(Out_Progress, jsonrpc, method, params); - -long long GetCurrentTimeInMilliseconds() { - auto time_since_epoch = Timer::Clock::now().time_since_epoch(); - long long elapsed_milliseconds = - std::chrono::duration_cast(time_since_epoch) - .count(); - return elapsed_milliseconds; -} - -struct ActiveThread { - ActiveThread(ImportPipelineStatus* status) - : status_(status) { - if (g_config && g_config->progressReportFrequencyMs < 0) - return; - - ++status_->num_active_threads; - } - ~ActiveThread() { - if (g_config && g_config->progressReportFrequencyMs < 0) - return; - - --status_->num_active_threads; - EmitProgress(); - } - - // Send indexing progress to client if reporting is enabled. - void EmitProgress() { - auto* queue = QueueManager::instance(); - Out_Progress out; - out.params.indexRequestCount = queue->index_request.Size(); - out.params.onIdMappedCount = queue->on_id_mapped.Size(); - out.params.onIndexedCount = queue->on_indexed.Size(); - out.params.activeThreads = status_->num_active_threads; - - // Ignore this progress update if the last update was too recent. - if (g_config && g_config->progressReportFrequencyMs != 0) { - // Make sure we output a status update if queue lengths are zero. - bool all_zero = out.params.indexRequestCount == 0 && - out.params.loadPreviousIndexCount == 0 && - out.params.onIdMappedCount == 0 && - out.params.onIndexedCount == 0 && - out.params.activeThreads == 0; - if (!all_zero && - GetCurrentTimeInMilliseconds() < status_->next_progress_output) - return; - status_->next_progress_output = - GetCurrentTimeInMilliseconds() + g_config->progressReportFrequencyMs; - } - - QueueManager::WriteStdout(kMethodType_Unknown, out); - } - - ImportPipelineStatus* status_; -}; - -enum class ShouldParse { Yes, No, NoSuchFile }; - // Checks if |path| needs to be reparsed. This will modify cached state // such that calling this function twice with the same path may return true // the first time but will return false the second. // // |from|: The file which generated the parse request for this file. -ShouldParse FileNeedsParse( - bool is_interactive, - TimestampManager* timestamp_manager, - const std::shared_ptr& cache_manager, - IndexFile* opt_previous_index, - const std::string& path, - const std::vector& args, - const std::optional& from) { - auto unwrap_opt = [](const std::optional& opt) -> std::string { - if (opt) - return " (via " + *opt + ")"; - return ""; - }; - - std::optional modification_timestamp = LastWriteTime(path); - - // Cannot find file. - if (!modification_timestamp) - return ShouldParse::NoSuchFile; - - std::optional last_cached_modification = - timestamp_manager->GetLastCachedModificationTime(cache_manager.get(), - path); - - // File has been changed. - if (!last_cached_modification || - modification_timestamp != *last_cached_modification) { - LOG_S(INFO) << "Timestamp has changed for " << path << unwrap_opt(from); - return ShouldParse::Yes; +bool FileNeedsParse(int64_t write_time, + VFS* vfs, + bool is_interactive, + IndexFile* opt_previous_index, + const std::string& path, + const std::vector& args, + const std::optional& from) { + { + std::lock_guard lock(vfs->mutex); + if (vfs->state[path].timestamp < write_time) { + LOG_S(INFO) << "timestamp changed for " << path + << (from ? " (via " + *from + ")" : std::string()); + return true; + } } // Command-line arguments changed. @@ -141,183 +51,96 @@ ShouldParse FileNeedsParse( (is_file(prev_args[i]) && is_file(args[i])); } if (!same) { - LOG_S(INFO) << "Arguments have changed for " << path << unwrap_opt(from); - return ShouldParse::Yes; + LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); + return true; } } - // File has not changed, do not parse it. - return ShouldParse::No; + return false; }; -enum CacheLoadResult { Parse, DoNotParse }; -CacheLoadResult TryLoadFromCache( - FileConsumerSharedState* file_consumer_shared, - TimestampManager* timestamp_manager, - const std::shared_ptr& cache_manager, - bool is_interactive, - const Project::Entry& entry, - const std::string& path_to_index) { - // Always run this block, even if we are interactive, so we can check - // dependencies and reset files in |file_consumer_shared|. - IndexFile* previous_index = cache_manager->TryLoad(path_to_index); - if (!previous_index) - return CacheLoadResult::Parse; - - // If none of the dependencies have changed and the index is not - // interactive (ie, requested by a file save), skip parsing and just load - // from cache. - - // Check timestamps and update |file_consumer_shared|. - ShouldParse path_state = - FileNeedsParse(is_interactive, timestamp_manager, cache_manager, - previous_index, path_to_index, entry.args, std::nullopt); - if (path_state == ShouldParse::Yes) - file_consumer_shared->Reset(path_to_index); - - // Target file does not exist on disk, do not emit any indexes. - // TODO: Dependencies should be reassigned to other files. We can do this by - // updating the "primary_file" if it doesn't exist. Might not actually be a - // problem in practice. - if (path_state == ShouldParse::NoSuchFile) - return CacheLoadResult::DoNotParse; - - bool needs_reparse = is_interactive || path_state == ShouldParse::Yes; - - for (const std::string& dependency : previous_index->dependencies) { - assert(!dependency.empty()); - - if (FileNeedsParse(is_interactive, timestamp_manager, cache_manager, - previous_index, dependency, entry.args, - previous_index->path) == ShouldParse::Yes) { - needs_reparse = true; - - // Do not break here, as we need to update |file_consumer_shared| for - // every dependency that needs to be reparsed. - file_consumer_shared->Reset(dependency); - } - } - - // FIXME: should we still load from cache? - if (needs_reparse) - return CacheLoadResult::Parse; - - // No timestamps changed - load directly from cache. - LOG_S(INFO) << "load index for " << path_to_index; - - // TODO/FIXME: real perf - PerformanceImportFile perf; - - std::vector result; - result.push_back(Index_OnIdMapped( - cache_manager, nullptr, cache_manager->TryTakeOrLoad(path_to_index), 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. - // - // This is important for perf in large projects where there are lots of - // dependencies shared between many files. - if (!file_consumer_shared->Mark(dependency)) - continue; - - LOG_S(INFO) << "emit index for " << dependency << " via " - << previous_index->path; +bool Indexer_Parse(DiagnosticsEngine* diag_engine, + WorkingFiles* working_files, + Project* project, + VFS* vfs, + IIndexer* indexer) { + auto* queue = QueueManager::instance(); + std::optional opt_request = queue->index_request.TryPopFront(); + if (!opt_request) + return false; + auto& request = *opt_request; + ICacheManager cache; - // |dependency_index| may be null if there is no cache for it but - // another file has already started importing it. - if (std::unique_ptr dependency_index = - cache_manager->TryTakeOrLoad(dependency)) { - result.push_back( - Index_OnIdMapped(cache_manager, nullptr, std::move(dependency_index), - perf, is_interactive, false /*write_to_disk*/)); + Project::Entry entry; + { + std::lock_guard lock(project->mutex_); + auto it = project->absolute_path_to_entry_index_.find(request.path); + if (it != project->absolute_path_to_entry_index_.end()) + entry = project->entries[it->second]; + else { + entry.filename = request.path; + entry.args = request.args; } } + std::string path_to_index = entry.filename; + std::unique_ptr prev; - QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result)); - return CacheLoadResult::DoNotParse; -} + // Try to load the file from cache. + std::optional write_time = LastWriteTime(path_to_index); + if (!write_time) + return true; + // FIXME Don't drop + if (!vfs->Mark(path_to_index, g_thread_id, 1)) + return true; + + int reparse; // request.is_interactive; + prev = cache.RawCacheLoad(path_to_index); + if (!prev) + reparse = 2; + else { + reparse = vfs->Stamp(path_to_index, prev->last_write_time); + if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev, + path_to_index, entry.args, std::nullopt)) + reparse = 2; + for (const auto& dep : prev->dependencies) + if (auto write_time1 = LastWriteTime(dep.first)) { + if (dep.second < *write_time1) { + reparse = 2; + std::lock_guard lock(vfs->mutex); + vfs->state[dep.first].stage = 0; + } + } else + reparse = 2; + } -std::vector PreloadFileContents( - const std::shared_ptr& cache_manager, - const Project::Entry& entry, - const std::string& entry_contents, - const std::string& path_to_index) { - // Load file contents for all dependencies into memory. If the dependencies - // for the file changed we may not end up using all of the files we - // preloaded. If a new dependency was added the indexer will grab the file - // contents as soon as possible. - // - // We do this to minimize the race between indexing a file and capturing the - // file contents. - // - // TODO: We might be able to optimize perf by only copying for files in - // working_files. We can pass that same set of files to the indexer as - // well. We then default to a fast file-copy if not in working set. - - // index->file_contents comes from cache, so we need to check if that cache is - // still valid. if so, we can use it, otherwise we need to load from disk. - auto get_latest_content = [](const std::string& path, int64_t cached_time, - const std::string& cached) -> std::string { - std::optional mod_time = LastWriteTime(path); - if (!mod_time) - return ""; - - if (*mod_time == cached_time) - return cached; - - std::optional fresh_content = ReadContent(path); - if (!fresh_content) { - LOG_S(ERROR) << "Failed to load content for " << path; - return ""; + if (reparse < 2) { + PerformanceImportFile perf; + auto dependencies = prev->dependencies; + if (reparse) { + IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); + queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), + request.is_interactive); } - return *fresh_content; - }; - - std::vector file_contents; - file_contents.push_back(FileContents(entry.filename, entry_contents)); - cache_manager->IterateLoadedCaches([&](IndexFile* index) { - if (index->path == entry.filename) - return; - file_contents.push_back(FileContents( - index->path, - get_latest_content(index->path, index->last_modification_time, - index->file_contents))); - }); - - return file_contents; -} - -void ParseFile(DiagnosticsEngine* diag_engine, - WorkingFiles* working_files, - FileConsumerSharedState* file_consumer_shared, - TimestampManager* timestamp_manager, - IIndexer* indexer, - const Index_Request& request, - const Project::Entry& entry) { - // If the file is inferred, we may not actually be able to parse that file - // directly (ie, a header file, which are not listed in the project). If this - // file is inferred, then try to use the file which originally imported it. - std::string path_to_index = entry.filename; - if (entry.is_inferred) { - IndexFile* entry_cache = request.cache_manager->TryLoad(entry.filename); - if (entry_cache) - path_to_index = entry_cache->import_file; + for (const auto& dep : dependencies) + if (vfs->Mark(dep.first, 0, 2)) { + prev = cache.RawCacheLoad(dep.first); + IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); + queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), + request.is_interactive); + } + + std::lock_guard lock(vfs->mutex); + VFS::State& state = vfs->state[path_to_index]; + if (state.owner == g_thread_id) + state.stage = 0; + return true; } - // Try to load the file from cache. - if (TryLoadFromCache(file_consumer_shared, timestamp_manager, - request.cache_manager, request.is_interactive, entry, - path_to_index) == CacheLoadResult::DoNotParse) - return; - LOG_S(INFO) << "parse " << path_to_index; - std::vector file_contents = PreloadFileContents( - request.cache_manager, entry, request.contents, path_to_index); std::vector result; PerformanceImportFile perf; - auto indexes = indexer->Index(file_consumer_shared, path_to_index, entry.args, - file_contents, &perf); + auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}, &perf); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -327,160 +150,52 @@ void ParseFile(DiagnosticsEngine* diag_engine, out.error.message = "Failed to index " + path_to_index; QueueManager::WriteStdout(kMethodType_Unknown, out); } - return; + vfs->Reset(path_to_index); + return true; } - for (std::unique_ptr& new_index : indexes) { - Timer time; - + for (std::unique_ptr& curr : indexes) { // Only emit diagnostics for non-interactive sessions, which makes it easier // to identify indexing problems. For interactive sessions, diagnostics are // handled by code completion. if (!request.is_interactive) - diag_engine->Publish(working_files, new_index->path, - new_index->diagnostics_); - - // When main thread does IdMap request it will request the previous index if - // needed. - LOG_S(INFO) << "emit index for " << new_index->path; - result.push_back( - Index_OnIdMapped(request.cache_manager, - request.cache_manager->TryTakeOrLoad(path_to_index), - std::move(new_index), perf, request.is_interactive, - true /*write_to_disk*/)); - } + diag_engine->Publish(working_files, curr->path, curr->diagnostics_); - QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result), - request.is_interactive); -} - -bool IndexMain_DoParse( - DiagnosticsEngine* diag_engine, - WorkingFiles* working_files, - FileConsumerSharedState* file_consumer_shared, - TimestampManager* timestamp_manager, - IIndexer* indexer) { - auto* queue = QueueManager::instance(); - std::optional request = queue->index_request.TryPopFront(); - if (!request) - return false; - - Project::Entry entry; - entry.filename = request->path; - entry.args = request->args; - ParseFile(diag_engine, working_files, file_consumer_shared, timestamp_manager, - indexer, request.value(), entry); - return true; -} - -bool IndexMain_DoCreateIndexUpdate(TimestampManager* timestamp_manager) { - auto* queue = QueueManager::instance(); - - bool did_work = false; - for (int i = 100; i--; ) { - std::optional response = queue->on_id_mapped.TryPopFront(); - if (!response) - return did_work; - - did_work = true; - - Timer time; + std::string path = curr->path; + if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) + continue; + LOG_S(INFO) << "emit index for " << path; + prev = cache.RawCacheLoad(path); // Write current index to disk if requested. - std::string path = response->current->path; - if (response->write_to_disk) { - LOG_S(INFO) << "store index for " << path; - time.Reset(); - response->cache_manager->WriteToCache(*response->current); - response->perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); - timestamp_manager->UpdateCachedModificationTime( - path, response->current->last_modification_time); + LOG_S(INFO) << "store index for " << path; + Timer time; + cache.WriteToCache(*curr); + perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); + + vfs->Reset(path_to_index); + if (entry.id >= 0) { + std::lock_guard lock(project->mutex_); + for (auto& dep : curr->dependencies) + project->absolute_path_to_entry_index_[dep.first] = entry.id; } // Build delta update. - IndexUpdate update = IndexUpdate::CreateDelta(response->previous.get(), - response->current.get()); - response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); - LOG_S(INFO) << "built index for " << path - << " (is_delta=" << !!response->previous << ")"; - - Index_OnIndexed reply(std::move(update), response->perf); - queue->on_indexed.PushBack(std::move(reply), response->is_interactive); - } - - return did_work; -} - -} // namespace + IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); + perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); + LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; -std::optional TimestampManager::GetLastCachedModificationTime( - ICacheManager* cache_manager, - const std::string& path) { - { - std::lock_guard guard(mutex_); - auto it = timestamps_.find(path); - if (it != timestamps_.end()) - return it->second; + Index_OnIndexed reply(std::move(update), perf); + queue->on_indexed.PushBack(std::move(reply), request.is_interactive); } - IndexFile* file = cache_manager->TryLoad(path); - if (!file) - return std::nullopt; - - UpdateCachedModificationTime(path, file->last_modification_time); - return file->last_modification_time; -} -void TimestampManager::UpdateCachedModificationTime(const std::string& path, - int64_t timestamp) { - std::lock_guard guard(mutex_); - timestamps_[path] = timestamp; + return true; } -ImportPipelineStatus::ImportPipelineStatus() - : num_active_threads(0), next_progress_output(0) {} - -// Index a file using an already-parsed translation unit from code completion. -// Since most of the time for indexing a file comes from parsing, we can do -// real-time indexing. -// TODO: add option to disable this. -void IndexWithTuFromCodeCompletion( - FileConsumerSharedState* file_consumer_shared, - ClangTranslationUnit* tu, - const std::vector& file_contents, - const std::string& path, - const std::vector& args) { - file_consumer_shared->Reset(path); - - PerformanceImportFile perf; - ClangIndex index; - auto indexes = ParseWithTu(file_consumer_shared, &perf, tu, &index, path, - args, file_contents); - if (indexes.empty()) - return; - - std::vector result; - for (std::unique_ptr& new_index : indexes) { - Timer time; - - std::shared_ptr cache_manager; - assert(false && "FIXME cache_manager"); - // When main thread does IdMap request it will request the previous index if - // needed. - LOG_S(INFO) << "Emitting index for " << new_index->path; - result.push_back(Index_OnIdMapped( - cache_manager, cache_manager->TryTakeOrLoad(path), std::move(new_index), - perf, true /*is_interactive*/, true /*write_to_disk*/)); - } - - LOG_IF_S(WARNING, result.size() > 1) - << "Code completion index update generated more than one index"; - - QueueManager::instance()->on_id_mapped.EnqueueAll(std::move(result)); -} +} // namespace void Indexer_Main(DiagnosticsEngine* diag_engine, - FileConsumerSharedState* file_consumer_shared, - TimestampManager* timestamp_manager, + VFS* vfs, ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, @@ -489,35 +204,9 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, // Build one index per-indexer, as building the index acquires a global lock. auto indexer = std::make_unique(); - while (true) { - bool did_work = false; - - { - ActiveThread active_thread(status); - - // TODO: process all off IndexMain_DoIndex before calling - // IndexMain_DoCreateIndexUpdate for better icache behavior. We need to - // have some threads spinning on both though otherwise memory usage will - // get bad. - - // We need to make sure to run both IndexMain_DoParse and - // 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(diag_engine, working_files, - file_consumer_shared, timestamp_manager, - indexer.get()) || - did_work; - - did_work = IndexMain_DoCreateIndexUpdate(timestamp_manager) || did_work; - } - - // We didn't do any work, so wait for a notification. - if (!did_work) { - waiter->Wait(&queue->on_indexed, &queue->index_request, - &queue->on_id_mapped); - } - } + while (true) + if (!Indexer_Parse(diag_engine, working_files, project, vfs, indexer.get())) + waiter->Wait(&queue->index_request); } namespace { @@ -559,9 +248,6 @@ bool QueryDb_ImportMain(QueryDatabase* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files) { auto* queue = QueueManager::instance(); - - ActiveThread active_thread(status); - bool did_work = false; for (int i = 80; i--; ) { diff --git a/src/import_pipeline.h b/src/import_pipeline.h index 9b74dd13e..0ba25eea7 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -1,19 +1,10 @@ #pragma once -// FIXME: do not include clang-c outside of clang_ files. -#include - #include -#include -#include -#include -#include -#include -#include struct ClangTranslationUnit; class DiagnosticsEngine; -struct FileConsumerSharedState; +struct VFS; struct ICacheManager; struct MultiQueueWaiter; struct Project; @@ -21,37 +12,13 @@ struct QueryDatabase; struct SemanticHighlightSymbolCache; struct WorkingFiles; -// Caches timestamps of cc files so we can avoid a filesystem reads. This is -// important for import perf, as during dependency checking the same files are -// checked over and over again if they are common headers. -struct TimestampManager { - std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, - const std::string& path); - - void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); - - // TODO: use std::shared_mutex so we can have multiple readers. - std::mutex mutex_; - std::unordered_map timestamps_; -}; - struct ImportPipelineStatus { - std::atomic num_active_threads; - std::atomic next_progress_output; - - ImportPipelineStatus(); + std::atomic num_active_threads = {0}; + std::atomic next_progress_output = {0}; }; -void IndexWithTuFromCodeCompletion( - FileConsumerSharedState* file_consumer_shared, - ClangTranslationUnit* tu, - const std::vector& file_contents, - const std::string& path, - const std::vector& args); - void Indexer_Main(DiagnosticsEngine* diag_engine, - FileConsumerSharedState* file_consumer_shared, - TimestampManager* timestamp_manager, + VFS* vfs, ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, diff --git a/src/indexer.h b/src/indexer.h index d332e1fad..fce01508d 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -285,7 +285,7 @@ struct IndexFile { std::string path; std::vector args; - int64_t last_modification_time = 0; + int64_t last_write_time = 0; LanguageId language = LanguageId::Unknown; // The path to the translation unit cc file which caused the creation of this @@ -298,7 +298,7 @@ struct IndexFile { std::vector skipped_by_preprocessor; std::vector includes; - std::vector dependencies; + std::unordered_map dependencies; std::unordered_map usr2func; std::unordered_map usr2type; std::unordered_map usr2var; @@ -334,14 +334,14 @@ struct NamespaceHelper { // |dependencies| are the existing dependencies of |import_file| if this is a // reparse. std::vector> Parse( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf, ClangIndex* index); std::vector> ParseWithTu( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, PerformanceImportFile* perf, ClangTranslationUnit* tu, ClangIndex* index, @@ -367,7 +367,7 @@ struct IIndexer { virtual ~IIndexer() = default; virtual std::vector> Index( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, @@ -376,12 +376,12 @@ struct IIndexer { struct ClangIndexer : IIndexer { std::vector> Index( - FileConsumerSharedState* file_consumer_shared, + VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, PerformanceImportFile* perf) override { - return Parse(file_consumer_shared, file, args, file_contents, perf, &index); + return Parse(vfs, file, args, file_contents, perf, &index); } // Note: constructing this acquires a global lock diff --git a/src/message_handler.cc b/src/message_handler.cc index 1a2a3c875..a16f59bb9 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -126,7 +126,7 @@ MessageHandler::MessageHandler() { std::vector* MessageHandler::message_handlers = nullptr; bool FindFileOrFail(QueryDatabase* db, - const Project* project, + Project* project, std::optional id, const std::string& absolute_path, QueryFile** out_query_file, @@ -147,8 +147,12 @@ bool FindFileOrFail(QueryDatabase* db, if (out_file_id) *out_file_id = -1; - bool indexing = project->absolute_path_to_entry_index_.find(absolute_path) != - project->absolute_path_to_entry_index_.end(); + bool indexing; + { + std::lock_guard lock(project->mutex_); + indexing = project->absolute_path_to_entry_index_.find(absolute_path) != + project->absolute_path_to_entry_index_.end(); + } if (indexing) LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; else diff --git a/src/message_handler.h b/src/message_handler.h index 8f35dbb08..2afcbc43e 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -15,14 +15,13 @@ struct ClangCompleteManager; struct CodeCompleteCache; struct Config; class DiagnosticsEngine; -struct FileConsumerSharedState; +struct VFS; struct ImportManager; struct ImportPipelineStatus; struct IncludeComplete; struct MultiQueueWaiter; struct Project; struct QueryDatabase; -struct TimestampManager; struct WorkingFile; struct WorkingFiles; @@ -107,10 +106,9 @@ struct MessageHandler { MultiQueueWaiter* waiter = nullptr; Project* project = nullptr; DiagnosticsEngine* diag_engine = nullptr; - FileConsumerSharedState* file_consumer_shared = nullptr; + VFS* vfs = nullptr; ImportManager* import_manager = nullptr; ImportPipelineStatus* import_pipeline_status = nullptr; - TimestampManager* timestamp_manager = nullptr; SemanticHighlightSymbolCache* semantic_cache = nullptr; WorkingFiles* working_files = nullptr; ClangCompleteManager* clang_complete = nullptr; @@ -139,7 +137,7 @@ struct BaseMessageHandler : MessageHandler { }; bool FindFileOrFail(QueryDatabase* db, - const Project* project, + Project* project, std::optional id, const std::string& absolute_path, QueryFile** out_query_file, diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 3b3794c1a..ffcca708a 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -4,6 +4,8 @@ #include +#include + namespace { MethodType kMethodType = "$ccls/callHierarchy"; diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 1989578dc..f9e047fa9 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -34,14 +34,8 @@ REGISTER_IN_MESSAGE(In_CclsFreshenIndex); struct Handler_CclsFreshenIndex : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_CclsFreshenIndex* request) override { - LOG_S(INFO) << "Freshening " << project->entries.size() << " files"; - - // TODO: think about this flow and test it more. GroupMatch matcher(request->params.whitelist, request->params.blacklist); - // Unmark all files whose timestamp has changed. - std::shared_ptr cache_manager = ICacheManager::Make(); - std::queue q; // |need_index| stores every filename ever enqueued. std::unordered_set need_index; @@ -65,15 +59,15 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { q.pop(); need_index.insert(file->def->path); - std::optional modification_timestamp = - LastWriteTime(file->def->path); - if (!modification_timestamp) + std::optional write_time = LastWriteTime(file->def->path); + if (!write_time) continue; - std::optional cached_modification = - timestamp_manager->GetLastCachedModificationTime(cache_manager.get(), - file->def->path); - if (modification_timestamp != cached_modification) - file_consumer_shared->Reset(file->def->path); + { + std::lock_guard lock(vfs->mutex); + VFS::State& st = vfs->state[file->def->path]; + if (st.timestamp < write_time) + st.stage = 0; + } if (request->params.dependencies) for (const std::string& path : graph[file->def->path]) { @@ -85,10 +79,8 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { } } - Timer time; // Send index requests for every file. project->Index(QueueManager::instance(), working_files, lsRequestId()); - time.ResetAndPrint("[perf] Dispatched $ccls/freshenIndex index requests"); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); diff --git a/src/messages/ccls_index_file.cc b/src/messages/ccls_index_file.cc deleted file mode 100644 index 0e4ecd860..000000000 --- a/src/messages/ccls_index_file.cc +++ /dev/null @@ -1,40 +0,0 @@ -#include "cache_manager.h" -#include "message_handler.h" -#include "platform.h" -#include "queue_manager.h" - -#include - -namespace { -MethodType kMethodType = "$ccls/indexFile"; - -struct In_CclsIndexFile : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - std::string path; - std::vector args; - bool is_interactive = false; - std::string contents; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_CclsIndexFile::Params, - path, - args, - is_interactive, - contents); -MAKE_REFLECT_STRUCT(In_CclsIndexFile, params); -REGISTER_IN_MESSAGE(In_CclsIndexFile); - -struct Handler_CclsIndexFile : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsIndexFile* 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())); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsIndexFile); -} // namespace diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index c8daab6b7..8654ed01f 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -2,6 +2,8 @@ #include "query_utils.h" #include "queue_manager.h" +#include + namespace { MethodType kMethodType = "$ccls/memberHierarchy"; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 7c8687f77..9cbcba606 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -473,9 +473,9 @@ struct Handler_Initialize : BaseMessageHandler { } // Ensure there is a resource directory. - if (config->resourceDirectory.empty()) - config->resourceDirectory = GetDefaultResourceDirectory(); - LOG_S(INFO) << "Using -resource-dir=" << config->resourceDirectory; + if (config->clang.resourceDir.empty()) + config->clang.resourceDir = GetDefaultResourceDirectory(); + LOG_S(INFO) << "Using -resource-dir=" << config->clang.resourceDir; // Send initialization before starting indexers, so we don't send a // status update too early. @@ -519,9 +519,9 @@ struct Handler_Initialize : BaseMessageHandler { LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; for (int i = 0; i < g_config->index.threads; i++) { std::thread([=]() { + g_thread_id = i + 1; SetThreadName("indexer" + std::to_string(i)); - Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, - import_pipeline_status, project, + Indexer_Main(diag_engine, vfs, import_pipeline_status, project, working_files, waiter); }).detach(); } diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index bc976cbd8..10a646ca3 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -33,7 +33,7 @@ struct Handler_TextDocumentDidChange Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content, ICacheManager::Make()), + *content), true); } } diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 20d8e2567..c3ae0b07d 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -38,13 +38,12 @@ struct Handler_TextDocumentDidOpen // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. const auto& params = request->params; - Timer time; std::string path = params.textDocument.uri.GetPath(); - std::shared_ptr cache_manager = ICacheManager::Make(); + ICacheManager cache; WorkingFile* working_file = working_files->OnOpen(params.textDocument); std::optional cached_file_contents = - cache_manager->LoadCachedFileContents(path); + cache.LoadCachedFileContents(path); if (cached_file_contents) working_file->SetIndexContent(*cached_file_contents); @@ -55,10 +54,6 @@ struct Handler_TextDocumentDidOpen EmitSemanticHighlighting(db, semantic_cache, working_file, file); } - time.ResetAndPrint( - "[querydb] Loading cached index file for DidOpen (blocks " - "CodeLens)"); - include_complete->AddFile(working_file->filename); clang_complete->NotifyView(path); if (params.args.size()) @@ -68,10 +63,10 @@ struct Handler_TextDocumentDidOpen if (SourceFileLanguage(path) != LanguageId::Unknown) { Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( - Index_Request( - entry.filename, params.args.size() ? params.args : entry.args, - true /*is_interactive*/, params.textDocument.text, cache_manager), - true /* priority */); + Index_Request(entry.filename, + params.args.size() ? params.args : entry.args, + true /*is_interactive*/, params.textDocument.text), + true /* priority */); clang_complete->FlushSession(entry.filename); LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 29ceffa8c..c6891c2c7 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -55,7 +55,7 @@ struct Handler_TextDocumentDidSave Project::Entry entry = project->FindCompilationEntryForFile(path); QueueManager::instance()->index_request.PushBack( Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content, ICacheManager::Make()), + *content), true); } } diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 19b4ad13b..6dbac73c9 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -41,10 +41,14 @@ struct Handler_WorkspaceDidChangeWatchedFiles void Run(In_WorkspaceDidChangeWatchedFiles* request) override { for (lsFileEvent& event : request->params.changes) { std::string path = event.uri.GetPath(); - auto it = project->absolute_path_to_entry_index_.find(path); - if (it == project->absolute_path_to_entry_index_.end()) - continue; - const Project::Entry& entry = project->entries[it->second]; + Project::Entry entry; + { + std::lock_guard lock(project->mutex_); + auto it = project->absolute_path_to_entry_index_.find(path); + if (it == project->absolute_path_to_entry_index_.end()) + continue; + entry = project->entries[it->second]; + } bool is_interactive = working_files->GetFileByFilename(entry.filename) != nullptr; switch (event.type) { @@ -55,8 +59,7 @@ struct Handler_WorkspaceDidChangeWatchedFiles 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())); + Index_Request(path, entry.args, is_interactive, *content)); if (is_interactive) clang_complete->NotifySave(path); } @@ -64,8 +67,7 @@ struct Handler_WorkspaceDidChangeWatchedFiles } case lsFileChangeType::Deleted: QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive, std::string(), - ICacheManager::Make())); + Index_Request(path, entry.args, is_interactive, std::string())); break; } } diff --git a/src/port.h b/src/port.h index ef19d7724..d50e597be 100644 --- a/src/port.h +++ b/src/port.h @@ -10,6 +10,10 @@ #define ATTRIBUTE_UNUSED #endif +#ifdef __clang__ +#define GUARDED_BY(x) __attribute__((guarded_by(x))) +#endif + // TODO GCC #if __has_builtin(__builtin_unreachable) #define CCLS_BUILTIN_UNREACHABLE __builtin_unreachable() diff --git a/src/project.cc b/src/project.cc index d45cd0633..d30e57e15 100644 --- a/src/project.cc +++ b/src/project.cc @@ -225,7 +225,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Add -resource-dir so clang can correctly resolve system includes like // if (!AnyStartsWith(result.args, "-resource-dir")) - result.args.push_back("-resource-dir=" + g_config->resourceDirectory); + result.args.push_back("-resource-dir=" + g_config->clang.resourceDir); // There could be a clang version mismatch between what the project uses and // what ccls uses. Make sure we do not emit warnings for mismatched options. @@ -441,7 +441,7 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { void Project::Load(const std::string& root_directory) { // Load data. ProjectConfig project; - project.extra_flags = g_config->extraClangArguments; + project.extra_flags = g_config->clang.extraArgs; project.project_dir = root_directory; entries = LoadCompilationEntriesFromDirectory( &project, g_config->compilationDatabaseDirectory); @@ -461,14 +461,18 @@ void Project::Load(const std::string& root_directory) { } // Setup project entries. + std::lock_guard lock(mutex_); absolute_path_to_entry_index_.reserve(entries.size()); - for (size_t i = 0; i < entries.size(); ++i) + for (size_t i = 0; i < entries.size(); ++i) { + entries[i].id = i; absolute_path_to_entry_index_[entries[i].filename] = i; + } } void Project::SetFlagsForFile( const std::vector& flags, const std::string& path) { + std::lock_guard lock(mutex_); auto it = absolute_path_to_entry_index_.find(path); if (it != absolute_path_to_entry_index_.end()) { // The entry already exists in the project, just set the flags. @@ -485,9 +489,12 @@ void Project::SetFlagsForFile( Project::Entry Project::FindCompilationEntryForFile( const std::string& filename) { - auto it = absolute_path_to_entry_index_.find(filename); - if (it != absolute_path_to_entry_index_.end()) - return entries[it->second]; + { + std::lock_guard lock(mutex_); + auto it = absolute_path_to_entry_index_.find(filename); + if (it != absolute_path_to_entry_index_.end()) + return entries[it->second]; + } // We couldn't find the file. Try to infer it. // TODO: Cache inferred file in a separate array (using a lock or similar) @@ -554,8 +561,7 @@ void Project::Index(QueueManager* queue, } bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; queue->index_request.PushBack(Index_Request(entry.filename, entry.args, - is_interactive, *content, - ICacheManager::Make(), id)); + is_interactive, *content, id)); }); } @@ -564,7 +570,7 @@ TEST_SUITE("Project") { std::vector raw, std::vector expected) { g_config = std::make_unique(); - g_config->resourceDirectory = "/w/resource_dir/"; + g_config->clang.resourceDir = "/w/resource_dir/"; ProjectConfig project; project.project_dir = "/w/c/s/"; diff --git a/src/project.h b/src/project.h index 0767e9453..4b5220b93 100644 --- a/src/project.h +++ b/src/project.h @@ -19,6 +19,7 @@ struct Project { std::vector args; // If true, this entry is inferred and was not read from disk. bool is_inferred = false; + int id = -1; }; // Include directories for "" headers @@ -27,7 +28,8 @@ struct Project { std::vector angle_include_directories; std::vector entries; - std::unordered_map absolute_path_to_entry_index_; + std::mutex mutex_; + std::unordered_map absolute_path_to_entry_index_ GUARDED_BY(mutex_); // Loads a project for the given |directory|. // diff --git a/src/query.cc b/src/query.cc index 761ca5e1f..49b7a893c 100644 --- a/src/query.cc +++ b/src/query.cc @@ -76,7 +76,9 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { def.args = std::move(indexed.args); def.includes = std::move(indexed.includes); def.inactive_regions = std::move(indexed.skipped_by_preprocessor); - def.dependencies = std::move(indexed.dependencies); + def.dependencies.reserve(indexed.dependencies.size()); + for (auto& dep : indexed.dependencies) + def.dependencies.push_back(dep.first); def.language = indexed.language; auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { diff --git a/src/queue_manager.cc b/src/queue_manager.cc index b4ec6ad16..87cb794a0 100644 --- a/src/queue_manager.cc +++ b/src/queue_manager.cc @@ -11,13 +11,11 @@ Index_Request::Index_Request( const std::vector& args, bool is_interactive, const std::string& contents, - const std::shared_ptr& cache_manager, lsRequestId id) : path(path), args(args), is_interactive(is_interactive), contents(contents), - cache_manager(cache_manager), id(id) {} Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update, @@ -51,10 +49,4 @@ QueueManager::QueueManager(MultiQueueWaiter* querydb_waiter, : for_stdout(stdout_waiter), for_querydb(querydb_waiter), on_indexed(querydb_waiter), - index_request(indexer_waiter), - on_id_mapped(indexer_waiter) {} - -bool QueueManager::HasWork() { - return !index_request.IsEmpty() || !on_id_mapped.IsEmpty() || - !on_indexed.IsEmpty(); -} + index_request(indexer_waiter) {} diff --git a/src/queue_manager.h b/src/queue_manager.h index 10c9d1218..63657fea8 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -21,14 +21,12 @@ struct Index_Request { std::vector args; bool is_interactive; std::string contents; // Preloaded contents. - std::shared_ptr cache_manager; lsRequestId id; Index_Request(const std::string& path, const std::vector& args, bool is_interactive, const std::string& contents, - const std::shared_ptr& cache_manager, lsRequestId id = {}); }; @@ -72,8 +70,6 @@ class QueueManager { MultiQueueWaiter* stdout_waiter); static void WriteStdout(MethodType method, lsBaseOutMessage& response); - bool HasWork(); - // Messages received by "stdout" thread. ThreadedQueue for_stdout; @@ -83,7 +79,6 @@ class QueueManager { // Runs on indexer threads. ThreadedQueue index_request; - ThreadedQueue on_id_mapped; private: explicit QueueManager(MultiQueueWaiter* querydb_waiter, diff --git a/src/serializer.cc b/src/serializer.cc index ea5b00239..fd07a045f 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -283,14 +283,13 @@ template void Reflect(TVisitor& visitor, IndexFile& value) { REFLECT_MEMBER_START(); if (!gTestOutputMode) { - REFLECT_MEMBER(last_modification_time); + REFLECT_MEMBER(last_write_time); REFLECT_MEMBER(language); REFLECT_MEMBER(import_file); REFLECT_MEMBER(args); + REFLECT_MEMBER(dependencies); } REFLECT_MEMBER(includes); - if (!gTestOutputMode) - REFLECT_MEMBER(dependencies); REFLECT_MEMBER(skipped_by_preprocessor); REFLECT_MEMBER(usr2func); REFLECT_MEMBER(usr2type); @@ -314,6 +313,27 @@ void Reflect(Writer& visitor, SerializeFormat& value) { } } +void Reflect(Reader& visitor, std::unordered_map& map) { + visitor.IterArray([&](Reader& entry) { + std::string name; + Reflect(entry, name); + if (visitor.Format() == SerializeFormat::Binary) + Reflect(entry, map[name]); + else + map[name] = 0; + }); +} +void Reflect(Writer& visitor, std::unordered_map& map) { + visitor.StartArray(map.size()); + for (auto& it : map) { + std::string key = it.first; + Reflect(visitor, key); + if (visitor.Format() == SerializeFormat::Binary) + Reflect(visitor, it.second); + } + visitor.EndArray(); +} + std::string Serialize(SerializeFormat format, IndexFile& file) { switch (format) { case SerializeFormat::Binary: { diff --git a/src/serializer.h b/src/serializer.h index a7d353ff2..69b524ddd 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -262,12 +262,12 @@ void Reflect(Writer& visitor, std::vector& values) { // std::unordered_map template -void Reflect(Reader& visitor, std::unordered_map& values) { +void Reflect(Reader& visitor, std::unordered_map& map) { visitor.IterArray([&](Reader& entry) { V val; Reflect(entry, val); auto usr = val.usr; - values[usr] = std::move(val); + map[usr] = std::move(val); }); } template @@ -281,6 +281,10 @@ void Reflect(Writer& visitor, std::unordered_map& map) { visitor.EndArray(); } +// Used by IndexFile::dependencies. Timestamps are emitted for Binary. +void Reflect(Reader& visitor, std::unordered_map& map); +void Reflect(Writer& visitor, std::unordered_map& map); + // ReflectMember template diff --git a/src/test.cc b/src/test.cc index 7bf1d9284..74d85bf82 100644 --- a/src/test.cc +++ b/src/test.cc @@ -292,9 +292,9 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // Run test. g_config = std::make_unique(); - FileConsumerSharedState file_consumer_shared; + VFS vfs; PerformanceImportFile perf; - auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index); + auto dbs = Parse(&vfs, path, flags, {}, &perf, &index); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; From a4a07120a1524fbb8b16c79e8ccb8cacb635c954 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 7 May 2018 20:59:08 -0700 Subject: [PATCH 089/378] Reflect optional by Brandon Tolsch --- src/messages/ccls_call_hierarchy.cc | 5 ++++- src/messages/ccls_inheritance_hierarchy.cc | 5 ++++- src/messages/ccls_member_hierarchy.cc | 5 ++++- src/messages/text_document_hover.cc | 18 ++++-------------- src/messages/workspace_execute_command.cc | 8 -------- src/serializer.h | 22 ++++++++++++++++++++++ 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index ffcca708a..c15e11226 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -79,7 +79,10 @@ MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, callType, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsCallHierarchy::Entry* entry, diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 2f4d83be4..3f9605444 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -60,7 +60,10 @@ MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry* entry, diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 8654ed01f..dd075c399 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -59,7 +59,10 @@ MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 455c61c53..eacd662bb 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -57,20 +57,10 @@ struct Out_TextDocumentHover : public lsOutMessage { std::optional result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); -void Reflect(Writer& visitor, Out_TextDocumentHover& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - if (value.result) - REFLECT_MEMBER(result); - else { - // Empty optional<> is elided by the default serializer, we need to write - // |null| to be compliant with the LSP. - visitor.Key("result"); - visitor.Null(); - } - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, + jsonrpc, + id, + result); struct Handler_TextDocumentHover : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index a96360f3d..8c1327c1a 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -20,14 +20,6 @@ struct Out_WorkspaceExecuteCommand }; MAKE_REFLECT_STRUCT(Out_WorkspaceExecuteCommand, jsonrpc, id, result); -void Reflect(Writer& visitor, Out_WorkspaceExecuteCommand& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} - struct Handler_WorkspaceExecuteCommand : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } diff --git a/src/serializer.h b/src/serializer.h index 69b524ddd..3e1bfe87a 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -19,6 +19,7 @@ enum class SerializeFormat { Binary, Json }; struct JsonNull {}; +struct mandatory_optional_tag {}; class Reader { public: @@ -77,6 +78,8 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) +#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ + ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) #define MAKE_REFLECT_TYPE_PROXY(type_name) \ @@ -93,6 +96,8 @@ struct IndexFile; } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); +#define _MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ + REFLECT_MEMBER_MANDATORY_OPTIONAL(name); #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ template \ @@ -109,6 +114,14 @@ struct IndexFile; REFLECT_MEMBER_END(); \ } +#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ + template \ + void Reflect(TVisitor& visitor, type& value) { \ + REFLECT_MEMBER_START(); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ + REFLECT_MEMBER_END(); \ + } + // clang-format off // Config has many fields, we need to support at least its number of fields. #define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N @@ -243,6 +256,15 @@ void ReflectMember(Writer& visitor, const char* name, Maybe& value) { } } +template +void ReflectMember(Writer& visitor, + const char* name, + T& value, + mandatory_optional_tag) { + visitor.Key(name); + Reflect(visitor, value); +} + // std::vector template void Reflect(Reader& visitor, std::vector& values) { From 04a848e065680a309773e7d80fc2ae37b598817f Mon Sep 17 00:00:00 2001 From: scturtle Date: Tue, 8 May 2018 14:56:53 +0800 Subject: [PATCH 090/378] Add CLANG_USE_BUNDLED_LIBC++ to cmake --- CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 136591324..9d6639096 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} option(SYSTEM_CLANG "Use system installation of Clang instead of \ downloading Clang" OFF) option(ASAN "Compile with address sanitizers" OFF) +option(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" OFF) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") @@ -81,6 +82,16 @@ if(NOT SYSTEM_CLANG) download_and_extract_clang(${CLANG_VERSION} ${CLANG_DOWNLOAD_LOCATION}) # Used by FindClang set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang AND CLANG_USE_BUNDLED_LIBC++) + message(STATUS "Using bundled libc++") + target_compile_options(ccls PRIVATE -stdlib=libc++) + target_include_directories(ccls PRIVATE ${CLANG_ROOT}/include/c++/v1) + target_link_libraries(ccls PRIVATE ${CLANG_ROOT}/lib/libc++.a + ${CLANG_ROOT}/lib/libc++abi.a + ${CLANG_ROOT}/lib/libc++experimental.a) + endif() + else() message(STATUS "Using system Clang") endif() From b55819a8a1077441f9aa6a9206a36febaf85d216 Mon Sep 17 00:00:00 2001 From: scturtle Date: Tue, 8 May 2018 15:35:32 +0800 Subject: [PATCH 091/378] Random changes. (#6) --- src/clang_indexer.cc | 15 +++++++++------ src/import_pipeline.cc | 19 +++++++++++++++++++ src/include_complete.cc | 4 ++-- src/messages/initialize.cc | 9 +++------ src/project.cc | 3 +++ src/query.h | 6 +----- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 355cda294..cf36a4c1d 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -1841,12 +1841,15 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { if (!ns.def.spell) { ClangCursor sem_parent = referenced.get_semantic_parent(); ClangCursor lex_parent = referenced.get_lexical_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); - std::string name = referenced.get_spell_name(); - SetTypeName(ns, referenced, nullptr, name.c_str(), param); + CXFile referenced_file; + Range spell = referenced.get_spell(&referenced_file); + if (file == referenced_file) { + ns.def.spell = SetUse(db, 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); + } } break; } diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 14a341d2d..680f3d67a 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -71,6 +71,13 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, auto& request = *opt_request; ICacheManager cache; + // dummy one to trigger refresh semantic highlight + if (request.path.empty()) { + queue->on_indexed.PushBack( + Index_OnIndexed(IndexUpdate{}, PerformanceImportFile()), false); + return false; + } + Project::Entry entry; { std::lock_guard lock(project->mutex_); @@ -216,6 +223,18 @@ void QueryDb_OnIndexed(QueueManager* queue, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, Index_OnIndexed* response) { + + if (response->update.file_id < 0) { // dummy + LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; + std::lock_guard lock(working_files->files_mutex); + for (auto& f : working_files->files) { + int file_id = db->name2file_id[LowerPathIfInsensitive(f->filename)]; + QueryFile* file = &db->files[file_id]; + EmitSemanticHighlighting(db, semantic_cache, f.get(), file); + } + return; + } + Timer time; db->ApplyIndexUpdate(&response->update); diff --git a/src/include_complete.cc b/src/include_complete.cc index f5ea1fc3c..056a5b2bf 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -106,8 +106,8 @@ void IncludeComplete::Rescan() { SetThreadName("scan_includes"); Timer timer; - InsertIncludesFromDirectory(g_config->projectRoot, - false /*use_angle_brackets*/); + // InsertIncludesFromDirectory(g_config->projectRoot, + // false /*use_angle_brackets*/); for (const std::string& dir : project_->quote_include_directories) InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); for (const std::string& dir : project_->angle_include_directories) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 9cbcba606..40571b8fe 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -510,12 +510,9 @@ struct Handler_Initialize : BaseMessageHandler { // Start indexer threads. Start this after loading the project, as that // may take a long time. Indexer threads will emit status/progress // reports. - if (g_config->index.threads == 0) { - // If the user has not specified how many indexers to run, try to - // guess an appropriate value. Default to 80% utilization. - g_config->index.threads = - std::max(int(std::thread::hardware_concurrency() * 0.8), 1); - } + if (g_config->index.threads == 0) + g_config->index.threads = std::thread::hardware_concurrency(); + LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; for (int i = 0; i < g_config->index.threads; i++) { std::thread([=]() { diff --git a/src/project.cc b/src/project.cc index d30e57e15..545f8cf88 100644 --- a/src/project.cc +++ b/src/project.cc @@ -563,6 +563,9 @@ void Project::Index(QueueManager* queue, queue->index_request.PushBack(Index_Request(entry.filename, entry.args, is_interactive, *content, id)); }); + // dummy request to indicate that project is loaded and + // trigger refreshing semantic highlight for all working files + queue->index_request.PushBack(Index_Request("", {}, false, "")); } TEST_SUITE("Project") { diff --git a/src/query.h b/src/query.h index 51d96ef32..a146df9f8 100644 --- a/src/query.h +++ b/src/query.h @@ -99,11 +99,7 @@ struct IndexUpdate { static IndexUpdate CreateDelta(IndexFile* previous, IndexFile* current); - // Merge |update| into this update; this can reduce overhead / index update - // work can be parallelized. - void Merge(IndexUpdate&& update); - - int file_id; + int file_id = -1; // File updates. std::optional files_removed; From 72433643bff716b4d2b71a06975a81d730de6fa8 Mon Sep 17 00:00:00 2001 From: scturtle Date: Tue, 8 May 2018 23:56:20 +0800 Subject: [PATCH 092/378] Fix file_id. (#8) --- src/import_pipeline.cc | 14 +++++++++----- src/include_complete.cc | 2 -- src/project.cc | 4 ++-- src/query.h | 5 ++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 680f3d67a..f4cd7d5fc 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -71,10 +71,12 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, auto& request = *opt_request; ICacheManager cache; - // dummy one to trigger refresh semantic highlight + // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { + IndexUpdate dummy; + dummy.refresh = true; queue->on_indexed.PushBack( - Index_OnIndexed(IndexUpdate{}, PerformanceImportFile()), false); + Index_OnIndexed(std::move(dummy), PerformanceImportFile()), false); return false; } @@ -224,12 +226,14 @@ void QueryDb_OnIndexed(QueueManager* queue, WorkingFiles* working_files, Index_OnIndexed* response) { - if (response->update.file_id < 0) { // dummy + if (response->update.refresh) { LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); for (auto& f : working_files->files) { - int file_id = db->name2file_id[LowerPathIfInsensitive(f->filename)]; - QueryFile* file = &db->files[file_id]; + std::string filename = LowerPathIfInsensitive(f->filename); + if (db->name2file_id.find(filename) == db->name2file_id.end()) + continue; + QueryFile* file = &db->files[db->name2file_id[filename]]; EmitSemanticHighlighting(db, semantic_cache, f.get(), file); } return; diff --git a/src/include_complete.cc b/src/include_complete.cc index 056a5b2bf..ea33fa33d 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -106,8 +106,6 @@ void IncludeComplete::Rescan() { SetThreadName("scan_includes"); Timer timer; - // InsertIncludesFromDirectory(g_config->projectRoot, - // false /*use_angle_brackets*/); for (const std::string& dir : project_->quote_include_directories) InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); for (const std::string& dir : project_->angle_include_directories) diff --git a/src/project.cc b/src/project.cc index 545f8cf88..df568423b 100644 --- a/src/project.cc +++ b/src/project.cc @@ -563,8 +563,8 @@ void Project::Index(QueueManager* queue, queue->index_request.PushBack(Index_Request(entry.filename, entry.args, is_interactive, *content, id)); }); - // dummy request to indicate that project is loaded and - // trigger refreshing semantic highlight for all working files + // Dummy request to indicate that project is loaded and + // trigger refreshing semantic highlight for all working files. queue->index_request.PushBack(Index_Request("", {}, false, "")); } diff --git a/src/query.h b/src/query.h index a146df9f8..571f1a4e6 100644 --- a/src/query.h +++ b/src/query.h @@ -99,7 +99,10 @@ struct IndexUpdate { static IndexUpdate CreateDelta(IndexFile* previous, IndexFile* current); - int file_id = -1; + int file_id; + + // Dummy one to refresh all semantic highlight. + bool refresh = false; // File updates. std::optional files_removed; From bac704f17bd28165e567e0f2ec9258897afb8606 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 8 May 2018 22:01:58 -0700 Subject: [PATCH 093/378] Backport and cleanup --- CMakeLists.txt | 2 +- src/clang_complete.cc | 4 +- src/clang_cursor.cc | 12 ++ src/clang_cursor.h | 10 +- src/clang_indexer.cc | 108 ++++-------------- src/config.h | 5 + src/import_pipeline.cc | 6 +- src/indexer.h | 41 +------ ...ved.cc => text_document_implementation.cc} | 15 +-- src/test.cc | 4 +- src/utils.h | 5 - 11 files changed, 61 insertions(+), 151 deletions(-) rename src/messages/{ccls_derived.cc => text_document_implementation.cc} (72%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d6639096..5fe920cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,7 +252,6 @@ target_sources(ccls PRIVATE src/messages/ccls_base.cc src/messages/ccls_call_hierarchy.cc src/messages/ccls_callers.cc - src/messages/ccls_derived.cc src/messages/ccls_file_info.cc src/messages/ccls_freshen_index.cc src/messages/ccls_inheritance_hierarchy.cc @@ -272,6 +271,7 @@ target_sources(ccls PRIVATE src/messages/text_document_document_highlight.cc src/messages/text_document_document_symbol.cc src/messages/text_document_hover.cc + src/messages/text_document_implementation.cc src/messages/text_document_references.cc src/messages/text_document_rename.cc src/messages/text_document_signature_help.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 029618260..8ea334a8c 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -275,7 +275,7 @@ void BuildDetailString(CXCompletionString completion_string, int num_chunks = clang_getNumCompletionChunks(completion_string); auto append = [&](const char* text) { detail += text; - if (do_insert) + if (do_insert && include_snippets) insert += text; }; for (int i = 0; i < num_chunks; ++i) { @@ -587,6 +587,8 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = completion_manager->diagnostic_request_.Dequeue(); + if (!g_config->diagnostics.onType) + continue; std::string path = request.document.uri.GetPath(); std::shared_ptr session = diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index 369da7449..ab880b3d9 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -131,6 +131,18 @@ Usr ClangCursor::get_usr_hash() const { return ret; } +std::optional ClangCursor::get_opt_usr_hash() const { + CXString usr = clang_getCursorUSR(cx_cursor); + const char* str = clang_getCString(usr); + if (!str || str[0] == '\0') { + clang_disposeString(usr); + return {}; + } + Usr ret = HashUsr(str); + clang_disposeString(usr); + return ret; +} + bool ClangCursor::is_definition() const { return clang_isCursorDefinition(cx_cursor); } diff --git a/src/clang_cursor.h b/src/clang_cursor.h index d0a1eed61..67acd08bd 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -67,6 +67,7 @@ class ClangCursor { std::string get_display_name() const; std::string get_usr() const; Usr get_usr_hash() const; + std::optional get_opt_usr_hash() const; bool is_definition() const; @@ -108,15 +109,6 @@ class ClangCursor { CXCursor cx_cursor; }; -namespace std { -template <> -struct hash { - size_t operator()(const ClangCursor& x) const { - return clang_hashCursor(x.cx_cursor); - } -}; -} // namespace std - // Simple RAII wrapper about CXIndex. // Note: building a ClangIndex instance acquires a global lock, since libclang // API does not appear to be thread-safe here. diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index cf36a4c1d..405d91b4b 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -557,15 +557,10 @@ IndexType* ResolveToDeclarationType(IndexFile* db, ClangCursor declaration = type.get_declaration().template_specialization_to_template_definition(); - CXString cx_usr = clang_getCursorUSR(declaration.cx_cursor); - const char* str_usr = clang_getCString(cx_usr); - if (!str_usr || str_usr[0] == '\0') { - clang_disposeString(cx_usr); + std::optional usr = declaration.get_opt_usr_hash(); + if (!usr) return nullptr; - } - Usr usr = HashUsr(str_usr); - clang_disposeString(cx_usr); - IndexType& typ = db->ToType(usr); + IndexType& typ = db->ToType(*usr); if (typ.def.detailed_name.empty()) { std::string name = declaration.get_spell_name(); SetTypeName(typ, declaration, nullptr, name.c_str(), param); @@ -602,11 +597,12 @@ void SetVarDetail(IndexVar& var, param->ns.QualifiedName(semanticContainer, short_name); if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) { - CXType enum_type = clang_getCanonicalType( - clang_getEnumDeclIntegerType(semanticContainer->cursor)); + CXTypeKind k = clang_getCanonicalType( + clang_getEnumDeclIntegerType(semanticContainer->cursor)) + .kind; std::string hover = qualified_name + " = "; - if (enum_type.kind == CXType_UInt || enum_type.kind == CXType_ULong || - enum_type.kind == CXType_ULongLong) + if (k == CXType_Char_U || k == CXType_UChar || k == CXType_UShort || + k == CXType_UInt || k == CXType_ULong || k == CXType_ULongLong) hover += std::to_string( clang_getEnumConstantDeclUnsignedValue(cursor.cx_cursor)); else @@ -896,15 +892,15 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, } } - std::string referenced_usr = + std::optional referenced_usr = cursor.get_referenced() .template_specialization_to_template_definition() - .get_usr(); - // TODO: things in STL cause this to be empty. Figure out why and document it. - if (referenced_usr == "") + .get_opt_usr_hash(); + // In STL this may be empty. + if (!referenced_usr) return; - IndexType& ref_type = db->ToType(HashUsr(referenced_usr)); + IndexType& ref_type = db->ToType(*referenced_usr); if (!param->initial_type) param->initial_type = &ref_type; @@ -1129,12 +1125,10 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor, // cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr_hash(); auto ref_usr = cursor.get_referenced() .template_specialization_to_template_definition() - .get_usr(); - // std::string ref_usr = ref.get_usr_hash(); - if (ref_usr.empty()) + .get_opt_usr_hash(); + if (!ref_usr) break; - - IndexVar& ref_var = db->ToVar(HashUsr(ref_usr)); + IndexVar& ref_var = db->ToVar(*ref_usr); AddUseSpell(db, ref_var.uses, cursor); break; } @@ -1347,8 +1341,8 @@ std::tuple NamespaceHelper::QualifiedName( std::string qualifier; while (cursor.get_kind() != CXCursor_TranslationUnit && GetSymbolKind(cursor.get_kind()) == SymbolKind::Type) { - auto it = container_cursor_to_qualified_name.find(cursor); - if (it != container_cursor_to_qualified_name.end()) { + auto it = usr2qualified_name.find(cursor.get_usr_hash()); + if (it != usr2qualified_name.end()) { qualifier = it->second; break; } @@ -1365,7 +1359,7 @@ std::tuple NamespaceHelper::QualifiedName( else qualifier += GetAnonName(namespaces[i].get_kind()); qualifier += "::"; - container_cursor_to_qualified_name[namespaces[i]] = qualifier; + usr2qualified_name[namespaces[i].get_usr_hash()] = qualifier; } int16_t pos = qualifier.size(); qualifier.append(unqualified_name); @@ -2013,13 +2007,12 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { } } -std::vector> Parse( +std::vector> ClangIndexer::Index( VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, - PerformanceImportFile* perf, - ClangIndex* index) { + PerformanceImportFile* perf) { if (!g_config->index.enabled) return {}; @@ -2037,7 +2030,7 @@ std::vector> Parse( } std::unique_ptr tu = ClangTranslationUnit::Create( - index, file, args, unsaved_files, + &index, file, args, unsaved_files, CXTranslationUnit_KeepGoing | CXTranslationUnit_DetailedPreprocessingRecord); if (!tu) @@ -2045,7 +2038,7 @@ std::vector> Parse( perf->index_parse = timer.ElapsedMicrosecondsAndReset(); - return ParseWithTu(vfs, perf, tu.get(), index, file, args, unsaved_files); + return ParseWithTu(vfs, perf, tu.get(), &index, file, args, unsaved_files); } std::vector> ParseWithTu( @@ -2206,58 +2199,3 @@ void Reflect(Writer& visitor, Reference& value) { Reflect(visitor, value.role); } } - -namespace { - -struct TestIndexer : IIndexer { - static std::unique_ptr FromEntries( - const std::vector& entries) { - auto result = std::make_unique(); - - for (const TestEntry& entry : entries) { - std::vector> indexes; - - if (entry.num_indexes > 0) - indexes.push_back(std::make_unique(entry.path, "")); - for (int i = 1; i < entry.num_indexes; ++i) { - indexes.push_back(std::make_unique( - entry.path + "_extra_" + std::to_string(i) + ".h", "")); - } - - result->indexes.insert(std::make_pair(entry.path, std::move(indexes))); - } - - return result; - } - - std::vector> Index( - VFS* vfs, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) override { - auto it = indexes.find(file); - if (it == indexes.end()) { - // Don't return any indexes for unexpected data. - assert(false && "no indexes"); - return {}; - } - - // FIXME: allow user to control how many times we return the index for a - // specific file (atm it is always 1) - auto result = std::move(it->second); - indexes.erase(it); - return result; - } - - std::unordered_map>> - indexes; -}; - -} // namespace - -// static -std::unique_ptr IIndexer::MakeTestIndexer( - std::initializer_list entries) { - return TestIndexer::FromEntries(entries); -} diff --git a/src/config.h b/src/config.h index ba90abbc6..58946bac4 100644 --- a/src/config.h +++ b/src/config.h @@ -137,6 +137,9 @@ struct Config { // If true, diagnostics from a full document parse will be reported. bool onParse = true; + // If true, diagnostics from typing will be reported. + bool onType = true; + std::vector whitelist; } diagnostics; @@ -211,6 +214,7 @@ MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, + dropOldRequests, detailedLabel, filterAndSort, includeBlacklist, @@ -221,6 +225,7 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onParse, + onType, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index f4cd7d5fc..a2aef1c17 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -63,7 +63,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, WorkingFiles* working_files, Project* project, VFS* vfs, - IIndexer* indexer) { + ClangIndexer* indexer) { auto* queue = QueueManager::instance(); std::optional opt_request = queue->index_request.TryPopFront(); if (!opt_request) @@ -211,10 +211,10 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, MultiQueueWaiter* waiter) { auto* queue = QueueManager::instance(); // Build one index per-indexer, as building the index acquires a global lock. - auto indexer = std::make_unique(); + ClangIndexer indexer; while (true) - if (!Indexer_Parse(diag_engine, working_files, project, vfs, indexer.get())) + if (!Indexer_Parse(diag_engine, working_files, project, vfs, &indexer)) waiter->Wait(&queue->index_request); } diff --git a/src/indexer.h b/src/indexer.h index fce01508d..e27c78e71 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -321,25 +321,13 @@ struct IndexFile { }; struct NamespaceHelper { - std::unordered_map - container_cursor_to_qualified_name; + std::unordered_map usr2qualified_name; std::tuple QualifiedName( const CXIdxContainerInfo* container, std::string_view unqualified_name); }; -// |import_file| is the cc file which is what gets passed to clang. -// |desired_index_file| is the (h or cc) file which has actually changed. -// |dependencies| are the existing dependencies of |import_file| if this is a -// reparse. -std::vector> Parse( - VFS* vfs, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf, - ClangIndex* index); std::vector> ParseWithTu( VFS* vfs, PerformanceImportFile* perf, @@ -353,36 +341,13 @@ bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); -// Abstracts away the actual indexing process. Each IIndexer instance is -// per-thread and constructing an instance may be extremely expensive (ie, -// acquire a lock) and should be done as rarely as possible. -struct IIndexer { - struct TestEntry { - std::string path; - int num_indexes = 0; - }; - - static std::unique_ptr MakeTestIndexer( - std::initializer_list entries); - - virtual ~IIndexer() = default; - virtual std::vector> Index( - VFS* vfs, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) = 0; -}; - -struct ClangIndexer : IIndexer { +struct ClangIndexer { std::vector> Index( VFS* vfs, std::string file, const std::vector& args, const std::vector& file_contents, - PerformanceImportFile* perf) override { - return Parse(vfs, file, args, file_contents, perf, &index); - } + PerformanceImportFile* perf); // Note: constructing this acquires a global lock ClangIndex index; diff --git a/src/messages/ccls_derived.cc b/src/messages/text_document_implementation.cc similarity index 72% rename from src/messages/ccls_derived.cc rename to src/messages/text_document_implementation.cc index 7a0c33ebb..6bb5148f2 100644 --- a/src/messages/ccls_derived.cc +++ b/src/messages/text_document_implementation.cc @@ -3,18 +3,19 @@ #include "queue_manager.h" namespace { -MethodType kMethodType = "$ccls/derived"; +MethodType kMethodType = "textDocument/implementation"; -struct In_CclsDerived : public RequestInMessage { +struct In_TextDocumentImplementation : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; -MAKE_REFLECT_STRUCT(In_CclsDerived, id, params); -REGISTER_IN_MESSAGE(In_CclsDerived); +MAKE_REFLECT_STRUCT(In_TextDocumentImplementation, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentImplementation); -struct Handler_CclsDerived : BaseMessageHandler { +struct Handler_TextDocumentImplementation + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsDerived* request) override { + void Run(In_TextDocumentImplementation* request) override { QueryFile* file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { @@ -43,5 +44,5 @@ struct Handler_CclsDerived : BaseMessageHandler { QueueManager::WriteStdout(kMethodType, out); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsDerived); +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); } // namespace diff --git a/src/test.cc b/src/test.cc index 74d85bf82..6cd4b2f76 100644 --- a/src/test.cc +++ b/src/test.cc @@ -247,7 +247,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); - ClangIndex index; + ClangIndexer index; GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string& path) { @@ -294,7 +294,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { g_config = std::make_unique(); VFS vfs; PerformanceImportFile perf; - auto dbs = Parse(&vfs, path, flags, {}, &perf, &index); + auto dbs = index.Index(&vfs, path, flags, {}, &perf); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; diff --git a/src/utils.h b/src/utils.h index 3c49bab88..4258ae498 100644 --- a/src/utils.h +++ b/src/utils.h @@ -49,11 +49,6 @@ std::string StringJoin(const TValues& values, const std::string& sep = ", ") { sep); } -template -bool ContainsValue(const TCollection& collection, const TValue& value) { - return collection.find(value) != collection.end(); -} - // Ensures that |path| ends in a slash. void EnsureEndsInSlash(std::string& path); From 99e7c56956cc69b2387baa3bf2bef94b571ca7a4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 11 May 2018 14:23:53 -0700 Subject: [PATCH 094/378] cmake: make FreeBSD 11,12 build --- CMakeLists.txt | 26 ++++++++++++++------------ src/fuzzy_match.cc | 2 +- src/port.h | 2 ++ src/project.cc | 28 ++++++++++++++-------------- src/query.cc | 3 +-- 5 files changed, 32 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fe920cdb..84334a9a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,11 +85,12 @@ if(NOT SYSTEM_CLANG) if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang AND CLANG_USE_BUNDLED_LIBC++) message(STATUS "Using bundled libc++") - target_compile_options(ccls PRIVATE -stdlib=libc++) - target_include_directories(ccls PRIVATE ${CLANG_ROOT}/include/c++/v1) - target_link_libraries(ccls PRIVATE ${CLANG_ROOT}/lib/libc++.a - ${CLANG_ROOT}/lib/libc++abi.a - ${CLANG_ROOT}/lib/libc++experimental.a) + target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1) + target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib -lc++experimental) + if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + # FreeBSD uses system libcxxrt.a and does not need libc++abi. + target_link_libraries(ccls PRIVATE c++abi) + endif() endif() else() @@ -107,15 +108,13 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) -if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - target_link_libraries(ccls PRIVATE -lstdc++fs) -elseif(MSVC) -else() - # e.g. Darwin, FreeBSD +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) target_link_libraries(ccls PRIVATE -lc++experimental) -endif() -if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + if(NOT CLANG_USE_BUNDLED_LIBC++) + target_link_libraries(ccls PRIVATE -lstdc++fs) + endif() # loguru calls dladdr target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) @@ -125,6 +124,9 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) # src/platform_posix.cc uses libthr find_package(Backtrace REQUIRED) target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} kvm thr) + if(SYSTEM_CLANG) + target_link_libraries(ccls PRIVATE c++experimental) + endif() elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) # sparsepp/spp_memory.h uses LibPsapi diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 49b45de16..1d5d60581 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -121,7 +121,7 @@ int FuzzyMatcher::Match(std::string_view text) { pat[i] == text[j])) ? std::max(pre[j][0] + MatchScore(i, j, false), pre[j][1] + MatchScore(i, j, true)) - : cur[j + 1][1] = kMinScore * 2; + : kMinScore * 2; } } diff --git a/src/port.h b/src/port.h index d50e597be..da3da3138 100644 --- a/src/port.h +++ b/src/port.h @@ -12,6 +12,8 @@ #ifdef __clang__ #define GUARDED_BY(x) __attribute__((guarded_by(x))) +#else +#define GUARDED_BY(x) #endif // TODO GCC diff --git a/src/project.cc b/src/project.cc index df568423b..77a8273d8 100644 --- a/src/project.cc +++ b/src/project.cc @@ -69,7 +69,7 @@ std::vector kBlacklist = { // Arguments which are followed by a potentially relative path. We need to make // all relative paths absolute, otherwise libclang will not resolve them. std::vector kPathArgs = { - "-I", "-iquote", "-isystem", "--sysroot=", + "-I", "-iquote", "-cxx-isystem", "-isystem", "--sysroot=", "-isysroot", "-gcc-toolchain", "-include-pch", "-iframework", "-F", "-imacros", "-include", "/I", "-idirafter"}; @@ -82,7 +82,7 @@ std::vector kNormalizePathArgs = {"--sysroot="}; // Arguments whose path arguments should be injected into include dir lookup // for #include completion. std::vector kQuoteIncludeArgs = {"-iquote", "-I", "/I"}; -std::vector kAngleIncludeArgs = {"-isystem", "-I", "/I"}; +std::vector kAngleIncludeArgs = {"-cxx-isystem", "-isystem", "-I", "/I"}; bool ShouldAddToQuoteIncludes(const std::string& arg) { return StartsWithAny(arg, kQuoteIncludeArgs); @@ -152,16 +152,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( for (; i < args.size(); ++i) { std::string arg = args[i]; - // If blacklist skip. - if (!next_flag_is_path) { - if (StartsWithAny(arg, kBlacklistMulti)) { - ++i; - continue; - } - if (StartsWithAny(arg, kBlacklist)) - continue; - } - // Finish processing path for the previous argument, which was a switch. // {"-I", "foo"} style. if (next_flag_is_path) { @@ -177,6 +167,12 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( add_next_flag_to_quote_dirs = false; add_next_flag_to_angle_dirs = false; } else { + // If blacklist skip. + if (StartsWithAny(arg, kBlacklistMulti)) { + i++; + continue; + } + // Check to see if arg is a path and needs to be updated. for (const std::string& flag_type : kPathArgs) { // {"-I", "foo"} style. @@ -184,7 +180,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( next_flag_is_path = true; add_next_flag_to_quote_dirs = ShouldAddToQuoteIncludes(arg); add_next_flag_to_angle_dirs = ShouldAddToAngleIncludes(arg); - break; + goto done; } // {"-Ifoo"} style. @@ -198,10 +194,13 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( config->quote_dirs.insert(path); if (ShouldAddToAngleIncludes(flag_type)) config->angle_dirs.insert(path); - break; + goto done; } } + if (StartsWithAny(arg, kBlacklist)) + continue; + // This is most likely the file path we will be passing to clang. The // path needs to be absolute, otherwise clang_codeCompleteAt is extremely // slow. See @@ -215,6 +214,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } + done: result.args.push_back(arg); } diff --git a/src/query.cc b/src/query.cc index 49b7a893c..036f85e25 100644 --- a/src/query.cc +++ b/src/query.cc @@ -5,13 +5,12 @@ #include "serializers/json.h" #include -#include #include #include #include #include -#include +#include #include #include #include From 224ba97f271ab547ad2d7238a1378438982caf74 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 12 May 2018 13:31:56 -0700 Subject: [PATCH 095/378] Use clang+llvm C++ in cmake; parse args with clang driver --- CMakeLists.txt | 31 ++---- cmake/FindClang.cmake | 60 ++++------- src/messages/initialize.cc | 3 +- src/platform.h | 9 +- src/platform_posix.cc | 21 ++-- src/platform_win.cc | 30 ------ src/project.cc | 197 +++++++++++-------------------------- 7 files changed, 99 insertions(+), 252 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84334a9a1..2e62c8f0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,10 +86,12 @@ if(NOT SYSTEM_CLANG) if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang AND CLANG_USE_BUNDLED_LIBC++) message(STATUS "Using bundled libc++") target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1) - target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib -lc++experimental) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + # Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++ + target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++experimental c++abi) + else() # FreeBSD uses system libcxxrt.a and does not need libc++abi. - target_link_libraries(ccls PRIVATE c++abi) + target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib c++experimental) endif() endif() @@ -101,7 +103,11 @@ endif() # See cmake/FindClang.cmake find_package(Clang ${CLANG_VERSION} REQUIRED) +find_package(Curses REQUIRED) target_link_libraries(ccls PRIVATE Clang::Clang) +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) + target_link_libraries(ccls PRIVATE Clang::Clang ${CURSES_LIBRARIES}) +endif() # Enable threading support set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -188,27 +194,6 @@ endif() file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h src/messages/*.h src/messages/*.cc) -if(Clang_FORMAT AND ${Clang_VERSION} STREQUAL 6.0.0) - add_custom_target(format - COMMAND ${Clang_FORMAT} -i ${SOURCES} - # .clang-format is located in the ccls root project dir - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMENT "Running clang-format ...") -else() - # Set error message depending on which condition was false - if (NOT Clang_FORMAT) - set(Clang_FORMAT_ERROR "Error: clang-format executable not found") - elseif(NOT ${Clang_VERSION} STREQUAL 6.0.0) - set(Clang_FORMAT_ERROR "Error: clang-format version does not match \ -6.0.0. Due to differences in clang-format output between versions we only \ -support clang-format 6.0.0") - endif() - - add_custom_target(format - COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold - ${Clang_FORMAT_ERROR}) -endif() - ### Sources target_sources(ccls PRIVATE third_party/siphash.cc) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index f21fb57b8..ab81ad615 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -8,7 +8,6 @@ # # Clang_FOUND - True if headers and requested libraries were found # Clang_EXECUTABLE - Clang executable -# Clang_FORMAT - Clang-format executable # Clang_RESOURCE_DIR - Clang resource directory # Clang_VERSION - Clang version as reported by Clang executable # @@ -19,7 +18,6 @@ # This module reads hints about which libraries to look for and where to find # them from the following variables:: # -# CLANG_CXX - Search for and add Clang C++ libraries # CLANG_ROOT - If set, only look for Clang components in CLANG_ROOT # # Example to link against Clang target:: @@ -41,6 +39,11 @@ macro(_Clang_find_library VAR NAME) endif() endmacro() +macro(_Clang_find_add_library NAME) + _Clang_find_library(${NAME}_LIBRARY ${NAME}) + list(APPEND _Clang_LIBRARIES ${${NAME}_LIBRARY}) +endmacro() + macro(_Clang_find_path VAR INCLUDE_FILE) if (CLANG_ROOT) find_path(${VAR} ${INCLUDE_FILE} @@ -59,45 +62,22 @@ macro(_Clang_find_program VAR NAME) endif() endmacro() -# Macro to avoid duplicating logic for each Clang C++ library -macro(_Clang_find_and_add_cxx_lib NAME INCLUDE_FILE) - # Find library - _Clang_find_library(Clang_${NAME}_LIBRARY ${NAME}) - list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_LIBRARY) - list(APPEND _Clang_CXX_LIBRARIES ${Clang_${NAME}_LIBRARY}) - - # Find corresponding include directory - _Clang_find_path(Clang_${NAME}_INCLUDE_DIR ${INCLUDE_FILE}) - list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_INCLUDE_DIR) - list(APPEND _Clang_CXX_INCLUDE_DIRS ${Clang_${NAME}_INCLUDE_DIR}) -endmacro() - ### Start set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE - Clang_RESOURCE_DIR Clang_VERSION) + Clang_RESOURCE_DIR Clang_VERSION + LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clang) +_Clang_find_add_library(clangDriver) +_Clang_find_add_library(LLVMOption) +_Clang_find_add_library(LLVMSupport) +_Clang_find_add_library(LLVMDemangle) _Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) +_Clang_find_path(Clang_BUILD_INCLUDE_DIR clang/Driver/Options.inc) +_Clang_find_path(LLVM_INCLUDE_DIR llvm/PassInfo.h) +_Clang_find_path(LLVM_BUILD_INCLUDE_DIR llvm/Config/llvm-config.h) -if(CLANG_CXX) - # The order is derived by topological sorting LINK_LIBS in - # clang/lib/*/CMakeLists.txt - _Clang_find_and_add_cxx_lib(clangFormat clang/Format/Format.h) - _Clang_find_and_add_cxx_lib(clangToolingCore clang/Tooling/Core/Diagnostic.h) - _Clang_find_and_add_cxx_lib(clangRewrite clang/Rewrite/Core/Rewriter.h) - _Clang_find_and_add_cxx_lib(clangAST clang/AST/AST.h) - _Clang_find_and_add_cxx_lib(clangLex clang/Lex/Lexer.h) - _Clang_find_and_add_cxx_lib(clangBasic clang/Basic/ABI.h) - - # The order is derived from llvm-config --libs core - _Clang_find_and_add_cxx_lib(LLVMCore llvm/Pass.h) - _Clang_find_and_add_cxx_lib(LLVMBinaryFormat llvm/BinaryFormat/Dwarf.h) - _Clang_find_and_add_cxx_lib(LLVMSupport llvm/Support/Error.h) - _Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h) -endif() - -_Clang_find_program(Clang_FORMAT clang-format) _Clang_find_program(Clang_EXECUTABLE clang) if(Clang_EXECUTABLE) # Find Clang resource directory with Clang executable @@ -127,12 +107,10 @@ find_package_handle_standard_args(Clang ) if(Clang_FOUND AND NOT TARGET Clang::Clang) - set(_Clang_LIBRARIES ${Clang_LIBRARY} ${_Clang_CXX_LIBRARIES}) - set(_Clang_INCLUDE_DIRS ${Clang_INCLUDE_DIR} ${_Clang_CXX_INCLUDE_DIRS}) + add_library(Clang::Clang UNKNOWN IMPORTED) + set_target_properties(Clang::Clang PROPERTIES + IMPORTED_LOCATION ${Clang_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") - add_library(Clang::Clang INTERFACE IMPORTED) - set_property(TARGET Clang::Clang PROPERTY - INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES}) - set_property(TARGET Clang::Clang PROPERTY - INTERFACE_INCLUDE_DIRECTORIES ${_Clang_INCLUDE_DIRS}) + set_property(TARGET Clang::Clang PROPERTY INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES}) endif() diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 40571b8fe..6a91b2020 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -517,7 +517,8 @@ struct Handler_Initialize : BaseMessageHandler { for (int i = 0; i < g_config->index.threads; i++) { std::thread([=]() { g_thread_id = i + 1; - SetThreadName("indexer" + std::to_string(i)); + std::string name = "indexer" + std::to_string(i); + SetThreadName(name.c_str()); Indexer_Main(diag_engine, vfs, import_pipeline_status, project, working_files, waiter); }).detach(); diff --git a/src/platform.h b/src/platform.h index b8a36bf36..adf49d120 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,10 +1,9 @@ #pragma once -#include -#include - #include +#include #include +#include #include void PlatformInit(); @@ -12,9 +11,7 @@ void PlatformInit(); std::string GetExecutablePath(); std::string NormalizePath(const std::string& path); -void SetThreadName(const std::string& thread_name); - -std::optional GetLastModificationTime(const std::string& absolute_path); +void SetThreadName(const char* name); // Free any unused memory and return it to the system. void FreeUnusedMemory(); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 6d8f59367..ac058fe5c 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -1,9 +1,12 @@ +#include +#include + #if defined(__unix__) || defined(__APPLE__) #include "platform.h" #include "utils.h" -#include "loguru.hpp" +#include #include #if defined(__FreeBSD__) @@ -155,17 +158,6 @@ std::string NormalizePath(const std::string& path) { return resolved ? *resolved : path; } -void SetThreadName(const std::string& thread_name) { - loguru::set_thread_name(thread_name.c_str()); -#if defined(__APPLE__) - pthread_setname_np(thread_name.c_str()); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(pthread_self(), thread_name.c_str()); -#elif defined(__linux__) - pthread_setname_np(pthread_self(), thread_name.c_str()); -#endif -} - void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); @@ -225,3 +217,8 @@ std::string GetExternalCommandOutput(const std::vector& command, } #endif + +void SetThreadName(const char* name) { + loguru::set_thread_name(name); + llvm::set_thread_name(name); +} diff --git a/src/platform_win.cc b/src/platform_win.cc index 471c73be0..fdd56aa49 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -49,36 +49,6 @@ std::string NormalizePath(const std::string& path) { return result; } -// See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx -const DWORD MS_VC_EXCEPTION = 0x406D1388; -#pragma pack(push, 8) -typedef struct tagTHREADNAME_INFO { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) -void SetThreadName(const std::string& thread_name) { - loguru::set_thread_name(thread_name.c_str()); - - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = thread_name.c_str(); - info.dwThreadID = (DWORD)-1; - info.dwFlags = 0; - - __try { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR*)&info); -#ifdef _MSC_VER - } __except (EXCEPTION_EXECUTE_HANDLER) { -#else - } catch (...) { -#endif - } -} - void FreeUnusedMemory() {} // TODO Wait for debugger to attach diff --git a/src/project.cc b/src/project.cc index 77a8273d8..67c7f0a01 100644 --- a/src/project.cc +++ b/src/project.cc @@ -12,6 +12,14 @@ #include "utils.h" #include "working_files.h" +#include +#include +#include +#include +using namespace clang; +using namespace llvm; +using namespace llvm::opt; + #include #include #include @@ -52,45 +60,13 @@ struct ProjectConfig { ProjectMode mode = ProjectMode::CompileCommandsJson; }; -// TODO: See -// https://github.com/Valloric/ycmd/blob/master/ycmd/completers/cpp/flags.py. -// Flags '-include' and '-include-pch' are blacklisted here cause libclang returns error in case when -// precompiled header was generated by a different compiler (even two different builds of same version -// of clang for the same platform are incompatible). Note that libclang always generate it's own pch -// internally. For details, see https://github.com/Valloric/ycmd/issues/892 . -std::vector kBlacklistMulti = { - "-MF", "-MT", "-MQ", "-o", "--serialize-diagnostics", "-Xclang"}; - -// Blacklisted flags which are always removed from the command line. -std::vector kBlacklist = { - "-c", "-MP", "-MD", "-MMD", "--fcolor-diagnostics", "-showIncludes" +enum OptionClass { + EqOrJoinOrSep, + EqOrSep, + JoinOrSep, + Separate, }; -// Arguments which are followed by a potentially relative path. We need to make -// all relative paths absolute, otherwise libclang will not resolve them. -std::vector kPathArgs = { - "-I", "-iquote", "-cxx-isystem", "-isystem", "--sysroot=", - "-isysroot", "-gcc-toolchain", "-include-pch", "-iframework", - "-F", "-imacros", "-include", "/I", - "-idirafter"}; - -// Arguments which always require an absolute path, ie, clang -working-directory -// does not work as expected. Argument processing assumes that this is a subset -// of kPathArgs. -std::vector kNormalizePathArgs = {"--sysroot="}; - -// Arguments whose path arguments should be injected into include dir lookup -// for #include completion. -std::vector kQuoteIncludeArgs = {"-iquote", "-I", "/I"}; -std::vector kAngleIncludeArgs = {"-cxx-isystem", "-isystem", "-I", "/I"}; - -bool ShouldAddToQuoteIncludes(const std::string& arg) { - return StartsWithAny(arg, kQuoteIncludeArgs); -} -bool ShouldAddToAngleIncludes(const std::string& arg) { - return StartsWithAny(arg, kAngleIncludeArgs); -} - Project::Entry GetCompilationEntryFromCompileCommandEntry( ProjectConfig* config, const CompileCommandsEntry& entry) { @@ -136,109 +112,51 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Compiler driver. result.args.push_back(args[0]); - // Add -working-directory if not provided. - if (!AnyStartsWith(args, "-working-directory")) - result.args.emplace_back("-working-directory=" + entry.directory.string()); - - bool next_flag_is_path = false; - bool add_next_flag_to_quote_dirs = false; - bool add_next_flag_to_angle_dirs = false; - - // Note that when processing paths, some arguments support multiple forms, ie, - // {"-Ifoo"} or {"-I", "foo"}. Support both styles. - - size_t i = 1; - result.args.reserve(args.size() + config->extra_flags.size()); - for (; i < args.size(); ++i) { - std::string arg = args[i]; - - // Finish processing path for the previous argument, which was a switch. - // {"-I", "foo"} style. - if (next_flag_is_path) { - std::string normalized_arg = entry.ResolveIfRelative(arg); - if (add_next_flag_to_quote_dirs) - config->quote_dirs.insert(normalized_arg); - if (add_next_flag_to_angle_dirs) - config->angle_dirs.insert(normalized_arg); - if (clang_cl) - arg = normalized_arg; - - next_flag_is_path = false; - add_next_flag_to_quote_dirs = false; - add_next_flag_to_angle_dirs = false; - } else { - // If blacklist skip. - if (StartsWithAny(arg, kBlacklistMulti)) { - i++; - continue; - } - - // Check to see if arg is a path and needs to be updated. - for (const std::string& flag_type : kPathArgs) { - // {"-I", "foo"} style. - if (arg == flag_type) { - next_flag_is_path = true; - add_next_flag_to_quote_dirs = ShouldAddToQuoteIncludes(arg); - add_next_flag_to_angle_dirs = ShouldAddToAngleIncludes(arg); - goto done; - } - - // {"-Ifoo"} style. - if (StartsWith(arg, flag_type)) { - std::string path = arg.substr(flag_type.size()); - assert(!path.empty()); - path = entry.ResolveIfRelative(path); - if (clang_cl || StartsWithAny(arg, kNormalizePathArgs)) - arg = flag_type + path; - if (ShouldAddToQuoteIncludes(flag_type)) - config->quote_dirs.insert(path); - if (ShouldAddToAngleIncludes(flag_type)) - config->angle_dirs.insert(path); - goto done; - } - } - - if (StartsWithAny(arg, kBlacklist)) - continue; - - // This is most likely the file path we will be passing to clang. The - // path needs to be absolute, otherwise clang_codeCompleteAt is extremely - // slow. See - // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. - if (EndsWith(arg, base_name)) - arg = entry.ResolveIfRelative(arg); - // TODO Exclude .a .o to make link command in compile_commands.json work. - // Also, clang_parseTranslationUnit2FullArgv does not seem to accept - // multiple source filenames. - else if (EndsWith(arg, ".a") || EndsWith(arg, ".o")) - continue; + std::unique_ptr Opts = driver::createDriverOptTable(); + unsigned MissingArgIndex, MissingArgCount; + std::vector cargs; + for (auto& arg : args) + cargs.push_back(arg.c_str()); + InputArgList Args = + Opts->ParseArgs(makeArrayRef(cargs), MissingArgIndex, MissingArgCount, + driver::options::CC1Option); + + using namespace clang::driver::options; + for (const auto* A : + Args.filtered(OPT_I, OPT_c_isystem, OPT_cxx_isystem, OPT_isystem)) + config->angle_dirs.insert(entry.ResolveIfRelative(A->getValue())); + for (const auto* A : Args.filtered(OPT_I, OPT_iquote)) + config->quote_dirs.insert(entry.ResolveIfRelative(A->getValue())); + + for (size_t i = 1; i < args.size(); i++) + // This is most likely the file path we will be passing to clang. The + // path needs to be absolute, otherwise clang_codeCompleteAt is extremely + // slow. See + // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. + if (args[i][0] != '-' && EndsWith(args[i], base_name)) { + args[i] = entry.ResolveIfRelative(args[i]); + continue; } - done: - result.args.push_back(arg); - } - // We don't do any special processing on user-given extra flags. for (const auto& flag : config->extra_flags) - result.args.push_back(flag); + args.push_back(flag); - // Add -resource-dir so clang can correctly resolve system includes like - // - if (!AnyStartsWith(result.args, "-resource-dir")) - result.args.push_back("-resource-dir=" + g_config->clang.resourceDir); + if (!Args.hasArg(OPT_resource_dir)) + args.push_back("-resource-dir=" + g_config->clang.resourceDir); + if (!Args.hasArg(OPT_working_directory)) + args.push_back("-working-directory=" + entry.directory.string()); // There could be a clang version mismatch between what the project uses and // what ccls uses. Make sure we do not emit warnings for mismatched options. - if (!AnyStartsWith(result.args, "-Wno-unknown-warning-option")) - result.args.push_back("-Wno-unknown-warning-option"); + args.push_back("-Wno-unknown-warning-option"); // Using -fparse-all-comments enables documentation in the indexer and in // code completion. - if (g_config->index.comments > 1 && - !AnyStartsWith(result.args, "-fparse-all-comments")) { - result.args.push_back("-fparse-all-comments"); - } + if (g_config->index.comments > 1) + args.push_back("-fparse-all-comments"); + result.args = std::move(args); return result; } @@ -601,15 +519,15 @@ 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", "-lstdc++", "/dir/myfile.cc", + "-resource-dir=/w/resource_dir/", "-working-directory=/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", + {"clang.exe", "-resource-dir=/w/resource_dir/", + "-working-directory=/dir/", "-Wno-unknown-warning-option", "-fparse-all-comments"}); } @@ -648,12 +566,13 @@ TEST_SUITE("Project") { #endif 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", "-O0", "/home/user/foo/bar.c", "-resource-dir=/w/resource_dir/", + "-working-directory=/home/user", "-Wno-unknown-warning-option", + "-fparse-all-comments"}); } TEST_CASE("Directory extraction") { From 87dcb8ffb2bcd59393739476ca6527abfc1ee5ac Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 13 May 2018 08:55:54 -0700 Subject: [PATCH 096/378] clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 -> 16.04 --- clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 | 1 - .../clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 | 1 - .../clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 | 1 - ...clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 - ...clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 + cmake/DownloadAndExtractClang.cmake | 2 +- 6 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 diff --git a/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 b/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 deleted file mode 100644 index ed1e6cf3f..000000000 --- a/clang_archive_hashes/LLVM-5.0.1-win64.exe.SHA256 +++ /dev/null @@ -1 +0,0 @@ -981543611d719624acb29a2cffd6a479cff36e8ab5ee8a57d8eca4f9c4c6956f diff --git a/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 deleted file mode 100644 index 4586d17ff..000000000 --- a/clang_archive_hashes/clang+llvm-5.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -86148b850e78aff743e7aaac337a3a94e9ad16d59ee6629a5ff699c31a73c55b diff --git a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 deleted file mode 100644 index b61fe5202..000000000 --- a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-apple-darwin.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -c5b105c4960619feb32641ef051fa39ecb913cc0feb6bacebdfa71f8d3cae277 diff --git a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 deleted file mode 100644 index 5ea09845f..000000000 --- a/clang_archive_hashes/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -9e61c6669991e2f0d065348c95917b2c6b697d75098b60ec1c2e9f17093ce012 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 new file mode 100644 index 000000000..18b5a60ea --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 @@ -0,0 +1 @@ +cc99fda45b4c740f35d0a367985a2bf55491065a501e2dd5d1ad3f97dcac89da diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake index ee5feaa71..5c4e3d976 100644 --- a/cmake/DownloadAndExtractClang.cmake +++ b/cmake/DownloadAndExtractClang.cmake @@ -11,7 +11,7 @@ set(CLANG_ARCHIVE_EXT .tar.xz) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04) + clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-16.04) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) From d3a36a4ae6a14d61f39dc604ff7cd0fa5b484af8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 13 May 2018 09:52:19 -0700 Subject: [PATCH 097/378] Use llvm::cl and simplify main.cc import_pipeline.cc --- CMakeLists.txt | 5 +- src/command_line.cc | 396 ------------------------------------- src/file_consumer.h | 28 +++ src/import_pipeline.cc | 178 +++++++++++++++-- src/import_pipeline.h | 20 +- src/indexer.h | 1 - src/main.cc | 135 +++++++++++++ src/message_handler.h | 2 - src/messages/initialize.cc | 3 +- src/performance.h | 30 --- src/platform.h | 3 - src/platform_posix.cc | 69 +------ src/platform_win.cc | 18 -- src/queue_manager.h | 1 - src/utils.cc | 36 +--- 15 files changed, 346 insertions(+), 579 deletions(-) delete mode 100644 src/command_line.cc create mode 100644 src/main.cc delete mode 100644 src/performance.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e62c8f0d..1e71d938d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,9 @@ if(NOT CYGWIN) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) endif() +# To link against LLVM libraries (usually compiled with -fno-rtti) +target_compile_options(ccls PRIVATE -fno-rtti) + # CMake sets MSVC for both MSVC and Clang(Windows) if(MSVC) # Common MSVC/Clang(Windows) options @@ -205,12 +208,12 @@ target_sources(ccls PRIVATE src/clang_indexer.cc src/clang_translation_unit.cc src/clang_utils.cc - src/command_line.cc src/config.cc src/diagnostics_engine.cc src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc + src/main.cc src/import_pipeline.cc src/include_complete.cc src/method.cc diff --git a/src/command_line.cc b/src/command_line.cc deleted file mode 100644 index 70599b012..000000000 --- a/src/command_line.cc +++ /dev/null @@ -1,396 +0,0 @@ -// TODO: cleanup includes -#include "cache_manager.h" -#include "clang_complete.h" -#include "diagnostics_engine.h" -#include "file_consumer.h" -#include "import_pipeline.h" -#include "include_complete.h" -#include "indexer.h" -#include "lex_utils.h" -#include "lru_cache.h" -#include "lsp_diagnostic.h" -#include "match.h" -#include "message_handler.h" -#include "platform.h" -#include "project.h" -#include "query.h" -#include "query_utils.h" -#include "queue_manager.h" -#include "serializer.h" -#include "serializers/json.h" -#include "test.h" -#include "timer.h" -#include "working_files.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -std::string g_init_options; - -namespace { - -std::unordered_map ParseOptions(int argc, - char** argv) { - std::unordered_map output; - - for (int i = 1; i < argc; ++i) { - std::string arg = argv[i]; - if (arg[0] == '-') { - auto equal = arg.find('='); - if (equal != std::string::npos) { - output[arg.substr(0, equal)] = arg.substr(equal + 1); - } else if (i + 1 < argc && argv[i + 1][0] != '-') - output[arg] = argv[++i]; - else - output[arg] = ""; - } - } - - return output; -} - -bool HasOption(const std::unordered_map& options, - const std::string& option) { - return options.find(option) != options.end(); -} - -// This function returns true if e2e timing should be displayed for the given -// MethodId. -bool ShouldDisplayMethodTiming(MethodType type) { - return - type != kMethodType_TextDocumentPublishDiagnostics && - type != kMethodType_CclsPublishInactiveRegions && - type != kMethodType_Unknown; -} - -void PrintHelp() { - printf("%s", R"help(ccls is a C/C++/Objective-C language server. - -Mode: - --test-unit Run unit tests. - --test-index - Run index tests. opt_filter_path can be used to specify which - test to run (ie, "foo" will run all tests which contain "foo" - in the path). If not provided all tests are run. - (default if no other mode is specified) - Run as a language server over stdin and stdout - -Other command line options: - --init - Override client provided initialization options - https://github.com/MaskRay/ccls/wiki/Initialization-options - --log-file Logging file for diagnostics - --log-file-append Like --log-file, but appending - --log-all-to-stderr Write all log messages to STDERR. - --help Print this help information. - --ci Prevents tests from prompting the user for input. Used for - continuous integration so it can fail faster instead of timing - out. - -See more on https://github.com/MaskRay/ccls/wiki -)help"); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// QUERYDB MAIN //////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -bool QueryDbMainLoop(QueryDatabase* db, - MultiQueueWaiter* waiter, - Project* project, - VFS* vfs, - ImportPipelineStatus* status, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files, - ClangCompleteManager* clang_complete, - IncludeComplete* include_complete, - CodeCompleteCache* global_code_complete_cache, - CodeCompleteCache* non_global_code_complete_cache, - CodeCompleteCache* signature_cache) { - auto* queue = QueueManager::instance(); - std::vector> messages = - queue->for_querydb.DequeueAll(); - bool did_work = messages.size(); - for (auto& message : messages) { - // TODO: Consider using std::unordered_map to lookup the handler - for (MessageHandler* handler : *MessageHandler::message_handlers) { - if (handler->GetMethodType() == message->GetMethodType()) { - handler->Run(std::move(message)); - break; - } - } - - if (message) { - LOG_S(ERROR) << "No handler for " << message->GetMethodType(); - } - } - - // TODO: consider rate-limiting and checking for IPC messages so we don't - // block requests / we can serve partial requests. - - if (QueryDb_ImportMain(db, status, semantic_cache, working_files)) { - did_work = true; - } - - return did_work; -} - -void RunQueryDbThread(const std::string& bin_name, - MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter) { - Project project; - SemanticHighlightSymbolCache semantic_cache; - WorkingFiles working_files; - VFS vfs; - DiagnosticsEngine diag_engine; - - ClangCompleteManager clang_complete( - &project, &working_files, - [&](std::string path, std::vector diagnostics) { - diag_engine.Publish(&working_files, path, diagnostics); - }, - [](lsRequestId id) { - if (id.Valid()) { - Out_Error out; - out.id = id; - out.error.code = lsErrorCodes::InternalError; - out.error.message = - "Dropping completion request; a newer request " - "has come in that will be serviced instead."; - QueueManager::WriteStdout(kMethodType_Unknown, out); - } - }); - - IncludeComplete include_complete(&project); - auto global_code_complete_cache = std::make_unique(); - auto non_global_code_complete_cache = std::make_unique(); - auto signature_cache = std::make_unique(); - ImportPipelineStatus import_pipeline_status; - QueryDatabase db; - - // Setup shared references. - for (MessageHandler* handler : *MessageHandler::message_handlers) { - handler->db = &db; - handler->waiter = indexer_waiter; - handler->project = &project; - handler->diag_engine = &diag_engine; - handler->vfs = &vfs; - handler->import_pipeline_status = &import_pipeline_status; - handler->semantic_cache = &semantic_cache; - handler->working_files = &working_files; - handler->clang_complete = &clang_complete; - handler->include_complete = &include_complete; - handler->global_code_complete_cache = global_code_complete_cache.get(); - handler->non_global_code_complete_cache = - non_global_code_complete_cache.get(); - handler->signature_cache = signature_cache.get(); - } - - // Run query db main loop. - SetThreadName("querydb"); - while (true) { - bool did_work = QueryDbMainLoop( - &db, querydb_waiter, &project, &vfs, - &import_pipeline_status, - &semantic_cache, &working_files, &clang_complete, &include_complete, - global_code_complete_cache.get(), non_global_code_complete_cache.get(), - signature_cache.get()); - - // Cleanup and free any unused memory. - FreeUnusedMemory(); - - if (!did_work) { - auto* queue = QueueManager::instance(); - querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// STDIN MAIN ////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -// Separate thread whose only job is to read from stdin and -// dispatch read commands to the actual indexer program. This -// cannot be done on the main thread because reading from std::cin -// blocks. -// -// |ipc| is connected to a server. -void LaunchStdinLoop(std::unordered_map* request_times) { - std::thread([request_times]() { - SetThreadName("stdin"); - auto* queue = QueueManager::instance(); - while (true) { - std::unique_ptr message; - std::optional err = - MessageRegistry::instance()->ReadMessageFromStdin(&message); - - // Message parsing can fail if we don't recognize the method. - if (err) { - // The message may be partially deserialized. - // Emit an error ResponseMessage if |id| is available. - if (message) { - lsRequestId id = message->GetRequestId(); - if (id.Valid()) { - Out_Error out; - out.id = id; - out.error.code = lsErrorCodes::InvalidParams; - out.error.message = std::move(*err); - queue->WriteStdout(kMethodType_Unknown, out); - } - } - continue; - } - - // Cache |method_id| so we can access it after moving |message|. - MethodType method_type = message->GetMethodType(); - (*request_times)[method_type] = Timer(); - - queue->for_querydb.PushBack(std::move(message)); - - // If the message was to exit then querydb will take care of the actual - // exit. Stop reading from stdin since it might be detached. - if (method_type == kMethodType_Exit) - break; - } - }).detach(); -} - -void LaunchStdoutThread(std::unordered_map* request_times, - MultiQueueWaiter* waiter) { - std::thread([=]() { - SetThreadName("stdout"); - auto* queue = QueueManager::instance(); - - while (true) { - std::vector messages = queue->for_stdout.DequeueAll(); - if (messages.empty()) { - waiter->Wait(&queue->for_stdout); - continue; - } - - for (auto& message : messages) { - if (ShouldDisplayMethodTiming(message.method)) { - Timer time = (*request_times)[message.method]; - time.ResetAndPrint("[e2e] Running " + std::string(message.method)); - } - - fwrite(message.content.c_str(), message.content.size(), 1, stdout); - fflush(stdout); - } - } - }).detach(); -} - -void LanguageServerMain(const std::string& bin_name, - MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter) { - std::unordered_map request_times; - - LaunchStdinLoop(&request_times); - - // We run a dedicated thread for writing to stdout because there can be an - // unknown number of delays when output information. - LaunchStdoutThread(&request_times, stdout_waiter); - - // Start querydb which takes over this thread. The querydb will launch - // indexer threads as needed. - RunQueryDbThread(bin_name, querydb_waiter, indexer_waiter); -} - -int main(int argc, char** argv) { - TraceMe(); - - std::unordered_map options = - ParseOptions(argc, argv); - - if (HasOption(options, "-h") || HasOption(options, "--help")) { - PrintHelp(); - // Also emit doctest help if --test-unit is passed. - if (!HasOption(options, "--test-unit")) - return 0; - } - - if (!HasOption(options, "--log-all-to-stderr")) - loguru::g_stderr_verbosity = loguru::Verbosity_WARNING; - - loguru::g_preamble_date = false; - loguru::g_preamble_time = false; - loguru::g_preamble_verbose = false; - loguru::g_flush_interval_ms = 0; - loguru::init(argc, argv); - - MultiQueueWaiter querydb_waiter, indexer_waiter, stdout_waiter; - QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); - - PlatformInit(); - IndexInit(); - - bool language_server = true; - - if (HasOption(options, "--log-file")) { - loguru::add_file(options["--log-file"].c_str(), loguru::Truncate, - loguru::Verbosity_MAX); - } - if (HasOption(options, "--log-file-append")) { - loguru::add_file(options["--log-file-append"].c_str(), loguru::Append, - loguru::Verbosity_MAX); - } - - if (HasOption(options, "--test-unit")) { - language_server = false; - doctest::Context context; - context.applyCommandLine(argc, argv); - int res = context.run(); - if (res != 0 || context.shouldExit()) - return res; - } - - if (HasOption(options, "--test-index")) { - language_server = false; - if (!RunIndexTests(options["--test-index"], !HasOption(options, "--ci"))) - return 1; - } - - if (language_server) { - if (HasOption(options, "--init")) { - // We check syntax error here but override client-side - // initializationOptions in messages/initialize.cc - g_init_options = options["--init"]; - rapidjson::Document reader; - rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); - if (!ok) { - fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", - rapidjson::GetParseError_En(ok.Code()), ok.Offset()); - return 1; - } - JsonReader json_reader{&reader}; - try { - Config config; - Reflect(json_reader, config); - } catch (std::invalid_argument& e) { - fprintf(stderr, "Failed to parse --init %s, expected %s\n", - static_cast(json_reader).GetPath().c_str(), - e.what()); - return 1; - } - } - - LanguageServerMain(argv[0], &querydb_waiter, &indexer_waiter, - &stdout_waiter); - } - - return 0; -} diff --git a/src/file_consumer.h b/src/file_consumer.h index eb006a32a..a7f7b2716 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -1,6 +1,7 @@ #pragma once #include "position.h" +#include "serializer.h" #include "utils.h" #include @@ -77,3 +78,30 @@ struct FileConsumer { std::string parse_file_; int thread_id_; }; + +// Contains timing information for the entire pipeline for importing a file +// into the querydb. +struct PerformanceImportFile { + // All units are in microseconds. + + // [indexer] clang parsing the file + uint64_t index_parse = 0; + // [indexer] build the IndexFile object from clang parse + uint64_t index_build = 0; + // [indexer] save the IndexFile to disk + uint64_t index_save_to_disk = 0; + // [indexer] loading previously cached index + uint64_t index_load_cached = 0; + // [indexer] create delta IndexUpdate object + uint64_t index_make_delta = 0; + // [querydb] update WorkingFile indexed file state + // uint64_t querydb_update_working_file = 0; + // [querydb] apply IndexUpdate + // uint64_t querydb_apply_index_update = 0; +}; +MAKE_REFLECT_STRUCT(PerformanceImportFile, + index_parse, + index_build, + index_save_to_disk, + index_load_cached, + index_make_delta); diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index a2aef1c17..625ba878a 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -1,8 +1,10 @@ #include "import_pipeline.h" #include "cache_manager.h" +#include "clang_complete.h" #include "config.h" #include "diagnostics_engine.h" +#include "include_complete.h" #include "lsp.h" #include "message_handler.h" #include "platform.h" @@ -15,6 +17,7 @@ #include #include +#include namespace { @@ -201,11 +204,19 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, return true; } +// This function returns true if e2e timing should be displayed for the given +// MethodId. +bool ShouldDisplayMethodTiming(MethodType type) { + return + type != kMethodType_TextDocumentPublishDiagnostics && + type != kMethodType_CclsPublishInactiveRegions && + type != kMethodType_Unknown; +} + } // namespace void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, - ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, MultiQueueWaiter* waiter) { @@ -218,10 +229,8 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, waiter->Wait(&queue->index_request); } -namespace { void QueryDb_OnIndexed(QueueManager* queue, QueryDatabase* db, - ImportPipelineStatus* status, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, Index_OnIndexed* response) { @@ -264,23 +273,154 @@ void QueryDb_OnIndexed(QueueManager* queue, } } -} // namespace +void LaunchStdinLoop(std::unordered_map* request_times) { + std::thread([request_times]() { + SetThreadName("stdin"); + auto* queue = QueueManager::instance(); + while (true) { + std::unique_ptr message; + std::optional err = + MessageRegistry::instance()->ReadMessageFromStdin(&message); + + // Message parsing can fail if we don't recognize the method. + if (err) { + // The message may be partially deserialized. + // Emit an error ResponseMessage if |id| is available. + if (message) { + lsRequestId id = message->GetRequestId(); + if (id.Valid()) { + Out_Error out; + out.id = id; + out.error.code = lsErrorCodes::InvalidParams; + out.error.message = std::move(*err); + queue->WriteStdout(kMethodType_Unknown, out); + } + } + continue; + } -bool QueryDb_ImportMain(QueryDatabase* db, - ImportPipelineStatus* status, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files) { - auto* queue = QueueManager::instance(); - bool did_work = false; - - for (int i = 80; i--; ) { - std::optional response = queue->on_indexed.TryPopFront(); - if (!response) - break; - did_work = true; - QueryDb_OnIndexed(queue, db, status, semantic_cache, working_files, - &*response); + // Cache |method_id| so we can access it after moving |message|. + MethodType method_type = message->GetMethodType(); + (*request_times)[method_type] = Timer(); + + queue->for_querydb.PushBack(std::move(message)); + + // If the message was to exit then querydb will take care of the actual + // exit. Stop reading from stdin since it might be detached. + if (method_type == kMethodType_Exit) + break; + } + }).detach(); +} + +void LaunchStdoutThread(std::unordered_map* request_times, + MultiQueueWaiter* waiter) { + std::thread([=]() { + SetThreadName("stdout"); + auto* queue = QueueManager::instance(); + + while (true) { + std::vector messages = queue->for_stdout.DequeueAll(); + if (messages.empty()) { + waiter->Wait(&queue->for_stdout); + continue; + } + + for (auto& message : messages) { + if (ShouldDisplayMethodTiming(message.method)) { + Timer time = (*request_times)[message.method]; + time.ResetAndPrint("[e2e] Running " + std::string(message.method)); + } + + fwrite(message.content.c_str(), message.content.size(), 1, stdout); + fflush(stdout); + } + } + }).detach(); +} + +void MainLoop(MultiQueueWaiter* querydb_waiter, + MultiQueueWaiter* indexer_waiter) { + Project project; + SemanticHighlightSymbolCache semantic_cache; + WorkingFiles working_files; + VFS vfs; + DiagnosticsEngine diag_engine; + + ClangCompleteManager clang_complete( + &project, &working_files, + [&](std::string path, std::vector diagnostics) { + diag_engine.Publish(&working_files, path, diagnostics); + }, + [](lsRequestId id) { + if (id.Valid()) { + Out_Error out; + out.id = id; + out.error.code = lsErrorCodes::InternalError; + out.error.message = + "Dropping completion request; a newer request " + "has come in that will be serviced instead."; + QueueManager::WriteStdout(kMethodType_Unknown, out); + } + }); + + IncludeComplete include_complete(&project); + auto global_code_complete_cache = std::make_unique(); + auto non_global_code_complete_cache = std::make_unique(); + auto signature_cache = std::make_unique(); + QueryDatabase db; + + // Setup shared references. + for (MessageHandler* handler : *MessageHandler::message_handlers) { + handler->db = &db; + handler->waiter = indexer_waiter; + handler->project = &project; + handler->diag_engine = &diag_engine; + handler->vfs = &vfs; + handler->semantic_cache = &semantic_cache; + handler->working_files = &working_files; + handler->clang_complete = &clang_complete; + handler->include_complete = &include_complete; + handler->global_code_complete_cache = global_code_complete_cache.get(); + handler->non_global_code_complete_cache = + non_global_code_complete_cache.get(); + handler->signature_cache = signature_cache.get(); } - return did_work; + // Run query db main loop. + SetThreadName("querydb"); + auto* queue = QueueManager::instance(); + while (true) { + std::vector> messages = + queue->for_querydb.DequeueAll(); + bool did_work = messages.size(); + for (auto& message : messages) { + // TODO: Consider using std::unordered_map to lookup the handler + for (MessageHandler* handler : *MessageHandler::message_handlers) { + if (handler->GetMethodType() == message->GetMethodType()) { + handler->Run(std::move(message)); + break; + } + } + + if (message) + LOG_S(ERROR) << "No handler for " << message->GetMethodType(); + } + + for (int i = 80; i--;) { + std::optional response = queue->on_indexed.TryPopFront(); + if (!response) + break; + did_work = true; + QueryDb_OnIndexed(queue, &db, &semantic_cache, &working_files, &*response); + } + + // Cleanup and free any unused memory. + FreeUnusedMemory(); + + if (!did_work) { + auto* queue = QueueManager::instance(); + querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb); + } + } } diff --git a/src/import_pipeline.h b/src/import_pipeline.h index 0ba25eea7..87076be90 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -1,30 +1,28 @@ #pragma once +#include "queue_manager.h" +#include "timer.h" + #include +#include struct ClangTranslationUnit; class DiagnosticsEngine; struct VFS; struct ICacheManager; -struct MultiQueueWaiter; struct Project; struct QueryDatabase; struct SemanticHighlightSymbolCache; struct WorkingFiles; -struct ImportPipelineStatus { - std::atomic num_active_threads = {0}; - std::atomic next_progress_output = {0}; -}; - void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, - ImportPipelineStatus* status, Project* project, WorkingFiles* working_files, MultiQueueWaiter* waiter); -bool QueryDb_ImportMain(QueryDatabase* db, - ImportPipelineStatus* status, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files); +void LaunchStdinLoop(std::unordered_map* request_times); +void LaunchStdoutThread(std::unordered_map* request_times, + MultiQueueWaiter* waiter); +void MainLoop(MultiQueueWaiter* querydb_waiter, + MultiQueueWaiter* indexer_waiter); diff --git a/src/indexer.h b/src/indexer.h index e27c78e71..12bed98cb 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -8,7 +8,6 @@ #include "lsp.h" #include "maybe.h" #include "nt_string.h" -#include "performance.h" #include "position.h" #include "serializer.h" #include "symbol.h" diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 000000000..503b1e12a --- /dev/null +++ b/src/main.cc @@ -0,0 +1,135 @@ +#include "import_pipeline.h" +#include "platform.h" +#include "serializer.h" +#include "serializers/json.h" +#include "test.h" +#include "working_files.h" + +#include +#include +using namespace llvm; +using namespace llvm::cl; + +#include +#include +#include + +#include +#include +#include +#include +#include + +std::string g_init_options; + +namespace { +opt opt_help("h", desc("Alias for -help")); +opt opt_verbose("v", desc("verbosity"), init(0)); +opt opt_test_index("test-index", desc("run index tests")); +opt opt_test_unit("test-unit", desc("run unit tests")); + +opt opt_init("init", desc("extra initialization options")); +opt opt_log_file("log-file", desc("log"), value_desc("filename")); +opt opt_log_file_append("log-file-append", desc("log"), value_desc("filename")); + +list opt_extra(Positional, ZeroOrMore, desc("extra")); + +} // namespace + +int main(int argc, char** argv) { + TraceMe(); + + ParseCommandLineOptions(argc, argv, + "C/C++/Objective-C language server\n\n" + "See more on https://github.com/MaskRay/ccls/wiki"); + + if (opt_help) { + PrintHelpMessage(); + // Also emit doctest help if --test-unit is passed. + if (!opt_test_unit) + return 0; + } + + loguru::g_stderr_verbosity = opt_verbose - 1; + loguru::g_preamble_date = false; + loguru::g_preamble_time = false; + loguru::g_preamble_verbose = false; + loguru::g_flush_interval_ms = 0; + loguru::init(argc, argv); + + MultiQueueWaiter querydb_waiter, indexer_waiter, stdout_waiter; + QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); + +#ifdef _WIN32 + // We need to write to stdout in binary mode because in Windows, writing + // \n will implicitly write \r\n. Language server API will ignore a + // \r\r\n split request. + _setmode(_fileno(stdout), O_BINARY); + _setmode(_fileno(stdin), O_BINARY); +#endif + + IndexInit(); + + bool language_server = true; + + if (opt_log_file.size()) + loguru::add_file(opt_log_file.c_str(), loguru::Truncate, opt_verbose); + if (opt_log_file_append.size()) + loguru::add_file(opt_log_file_append.c_str(), loguru::Append, opt_verbose); + + if (opt_test_unit) { + language_server = false; + doctest::Context context; + std::vector args{argv[0]}; + if (opt_help) + args.push_back("-h"); + for (auto& arg : opt_extra) + args.push_back(arg.c_str()); + context.applyCommandLine(args.size(), args.data()); + int res = context.run(); + if (res != 0 || context.shouldExit()) + return res; + } + + if (opt_test_index) { + language_server = false; + if (!RunIndexTests("", sys::Process::StandardInIsUserInput())) + return 1; + } + + if (language_server) { + if (!opt_init.empty()) { + // We check syntax error here but override client-side + // initializationOptions in messages/initialize.cc + g_init_options = opt_init; + rapidjson::Document reader; + rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); + if (!ok) { + fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", + rapidjson::GetParseError_En(ok.Code()), ok.Offset()); + return 1; + } + JsonReader json_reader{&reader}; + try { + Config config; + Reflect(json_reader, config); + } catch (std::invalid_argument& e) { + fprintf(stderr, "Failed to parse --init %s, expected %s\n", + static_cast(json_reader).GetPath().c_str(), + e.what()); + return 1; + } + } + + std::unordered_map request_times; + + // The thread that reads from stdin and dispatchs commands to the main thread. + LaunchStdinLoop(&request_times); + // The thread that writes responses from the main thread to stdout. + LaunchStdoutThread(&request_times, &stdout_waiter); + // Main thread which also spawns indexer threads upon the "initialize" request. + MainLoop(&querydb_waiter, &indexer_waiter); + } + + return 0; +} diff --git a/src/message_handler.h b/src/message_handler.h index 2afcbc43e..d836c8737 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -17,7 +17,6 @@ struct Config; class DiagnosticsEngine; struct VFS; struct ImportManager; -struct ImportPipelineStatus; struct IncludeComplete; struct MultiQueueWaiter; struct Project; @@ -108,7 +107,6 @@ struct MessageHandler { DiagnosticsEngine* diag_engine = nullptr; VFS* vfs = nullptr; ImportManager* import_manager = nullptr; - ImportPipelineStatus* import_pipeline_status = nullptr; SemanticHighlightSymbolCache* semantic_cache = nullptr; WorkingFiles* working_files = nullptr; ClangCompleteManager* clang_complete = nullptr; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 6a91b2020..6dfb3d3ea 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -519,8 +519,7 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); SetThreadName(name.c_str()); - Indexer_Main(diag_engine, vfs, import_pipeline_status, project, - working_files, waiter); + Indexer_Main(diag_engine, vfs, project, working_files, waiter); }).detach(); } diff --git a/src/performance.h b/src/performance.h deleted file mode 100644 index 28579f9c0..000000000 --- a/src/performance.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "serializer.h" - -// Contains timing information for the entire pipeline for importing a file -// into the querydb. -struct PerformanceImportFile { - // All units are in microseconds. - - // [indexer] clang parsing the file - uint64_t index_parse = 0; - // [indexer] build the IndexFile object from clang parse - uint64_t index_build = 0; - // [indexer] save the IndexFile to disk - uint64_t index_save_to_disk = 0; - // [indexer] loading previously cached index - uint64_t index_load_cached = 0; - // [indexer] create delta IndexUpdate object - uint64_t index_make_delta = 0; - // [querydb] update WorkingFile indexed file state - // uint64_t querydb_update_working_file = 0; - // [querydb] apply IndexUpdate - // uint64_t querydb_apply_index_update = 0; -}; -MAKE_REFLECT_STRUCT(PerformanceImportFile, - index_parse, - index_build, - index_save_to_disk, - index_load_cached, - index_make_delta); diff --git a/src/platform.h b/src/platform.h index adf49d120..775486a04 100644 --- a/src/platform.h +++ b/src/platform.h @@ -6,9 +6,6 @@ #include #include -void PlatformInit(); - -std::string GetExecutablePath(); std::string NormalizePath(const std::string& path); void SetThreadName(const char* name); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ac058fe5c..d1d6c9e01 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -8,40 +8,22 @@ #include -#include -#if defined(__FreeBSD__) -#include -#include -#elif defined(__OpenBSD__) -#include -#endif - #include -#include #include -#include -#include #include #include #include #include -#include #include +#include +#include +#include +#include #include #include // required for stat.h #include - -#include -#include - -#include -#include - -#if defined(__FreeBSD__) -#include // MAXPATHLEN -#include // sysctl -#elif defined(__linux__) +#ifdef __GLIBC__ #include #endif @@ -114,52 +96,13 @@ std::optional RealPathNotExpandSymlink(std::string path) { } // namespace -void PlatformInit() {} - -#ifdef __APPLE__ -extern "C" int _NSGetExecutablePath(char* buf, uint32_t* bufsize); -#endif - -// See -// https://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from -std::string GetExecutablePath() { -#ifdef __APPLE__ - uint32_t size = 0; - _NSGetExecutablePath(nullptr, &size); - char* buffer = new char[size]; - _NSGetExecutablePath(buffer, &size); - char* resolved = realpath(buffer, nullptr); - std::string result(resolved); - delete[] buffer; - free(resolved); - return result; -#elif defined(__FreeBSD__) - static const int name[] = { - CTL_KERN, - KERN_PROC, - KERN_PROC_PATHNAME, - -1, - }; - char path[MAXPATHLEN]; - size_t len = sizeof(path); - path[0] = '\0'; - (void)sysctl(name, 4, path, &len, NULL, 0); - return std::string(path); -#else - char buffer[PATH_MAX] = {0}; - if (-1 == readlink("/proc/self/exe", buffer, PATH_MAX)) - return ""; - return buffer; -#endif -} - std::string NormalizePath(const std::string& path) { std::optional resolved = RealPathNotExpandSymlink(path); return resolved ? *resolved : path; } void FreeUnusedMemory() { -#if defined(__GLIBC__) +#ifdef __GLIBC__ malloc_trim(0); #endif } diff --git a/src/platform_win.cc b/src/platform_win.cc index fdd56aa49..6c02c0ee2 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -3,8 +3,6 @@ #include "utils.h" -#include - #include #include #include @@ -17,22 +15,6 @@ #include #include -void PlatformInit() { - // We need to write to stdout in binary mode because in Windows, writing - // \n will implicitly write \r\n. Language server API will ignore a - // \r\r\n split request. - _setmode(_fileno(stdout), O_BINARY); - _setmode(_fileno(stdin), O_BINARY); -} - -// See -// https://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from -std::string GetExecutablePath() { - char result[MAX_PATH] = {0}; - GetModuleFileName(NULL, result, MAX_PATH); - return NormalizePath(result); -} - std::string NormalizePath(const std::string& path) { DWORD retval = 0; TCHAR buffer[MAX_PATH] = TEXT(""); diff --git a/src/queue_manager.h b/src/queue_manager.h index 63657fea8..03f3909c7 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -1,7 +1,6 @@ #pragma once #include "method.h" -#include "performance.h" #include "query.h" #include "threaded_queue.h" diff --git a/src/utils.cc b/src/utils.cc index cf63245fb..f9632f3aa 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -16,15 +16,6 @@ #include using namespace std::placeholders; -// DEFAULT_RESOURCE_DIRECTORY is passed with quotes for non-MSVC compilers, ie, -// foo vs "foo". -#if defined(_MSC_VER) -#define _STRINGIFY(x) #x -#define ENSURE_STRING_MACRO_ARGUMENT(x) _STRINGIFY(x) -#else -#define ENSURE_STRING_MACRO_ARGUMENT(x) x -#endif - void TrimInPlace(std::string& s) { auto f = [](char c) { return !isspace(c); }; s.erase(s.begin(), std::find_if(s.begin(), s.end(), f)); @@ -137,8 +128,9 @@ std::optional ReadContent(const std::string& filename) { void WriteToFile(const std::string& filename, const std::string& content) { FILE* f = fopen(filename.c_str(), "wb"); - if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) { - LOG_S(ERROR) << "Failed to write to " << filename << ' ' << strerror(errno); + if (!f || + (content.size() && fwrite(content.c_str(), content.size(), 1, f) != 1)) { + LOG_S(ERROR) << "failed to write to " << filename << ' ' << strerror(errno); return; } fclose(f); @@ -154,25 +146,5 @@ std::optional LastWriteTime(const std::string& filename) { } std::string GetDefaultResourceDirectory() { - std::string result; - - std::string resource_directory = - std::string(ENSURE_STRING_MACRO_ARGUMENT(DEFAULT_RESOURCE_DIRECTORY)); - // Remove double quoted resource dir if it was passed with quotes - // by the build system. - if (resource_directory.size() >= 2 && resource_directory[0] == '"' && - resource_directory[resource_directory.size() - 1] == '"') { - resource_directory = - resource_directory.substr(1, resource_directory.size() - 2); - } - if (resource_directory.compare(0, 2, "..") == 0) { - std::string executable_path = GetExecutablePath(); - size_t pos = executable_path.find_last_of('/'); - result = executable_path.substr(0, pos + 1); - result += resource_directory; - } else { - result = resource_directory; - } - - return NormalizePath(result); + return DEFAULT_RESOURCE_DIRECTORY; } From f145c4422ffb7901edc3ccc3ec475cac7c428859 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 13 May 2018 13:30:24 -0700 Subject: [PATCH 098/378] experimental/filesystem -> LLVM/Support/FileSystem.h; sparsepp -> DenseMap --- .gitmodules | 3 -- CMakeLists.txt | 18 +++-------- cmake/FindClang.cmake | 1 + src/clang_complete.cc | 9 ++++-- src/clang_utils.cc | 11 +++++-- src/filesystem.cc | 50 +++++++++++++++-------------- src/filesystem.hh | 6 ++-- src/messages/initialize.cc | 12 ++++--- src/project.cc | 65 ++++++++++++++++++++------------------ src/query.cc | 16 ++++++---- src/query.h | 17 +++++----- src/query_utils.h | 4 +-- src/serializer.cc | 2 +- src/utils.cc | 11 +++---- third_party/sparsepp | 1 - 15 files changed, 116 insertions(+), 110 deletions(-) delete mode 160000 third_party/sparsepp diff --git a/.gitmodules b/.gitmodules index 27ff39f04..f0c273413 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "third_party/doctest"] path = third_party/doctest url = https://github.com/onqtam/doctest -[submodule "third_party/sparsepp"] - path = third_party/sparsepp - url = https://github.com/greg7mdp/sparsepp [submodule "third_party/loguru"] path = third_party/loguru url = https://github.com/emilk/loguru diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e71d938d..010258ad0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,10 +91,9 @@ if(NOT SYSTEM_CLANG) target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) # Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++ - target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++experimental c++abi) - else() - # FreeBSD uses system libcxxrt.a and does not need libc++abi. - target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib c++experimental) + target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++abi) + + # FreeBSD defaults to -stdlib=libc++ and uses system libcxxrt.a endif() endif() @@ -121,25 +120,17 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) target_link_libraries(ccls PRIVATE -lc++experimental) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - if(NOT CLANG_USE_BUNDLED_LIBC++) - target_link_libraries(ccls PRIVATE -lstdc++fs) - endif() # loguru calls dladdr target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) # loguru::stacktrace_as_stdstring calls backtrace_symbols - # sparsepp/spp_memory.h uses libkvm # src/platform_posix.cc uses libthr find_package(Backtrace REQUIRED) - target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} kvm thr) + target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} thr) if(SYSTEM_CLANG) target_link_libraries(ccls PRIVATE c++experimental) endif() - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) - # sparsepp/spp_memory.h uses LibPsapi - target_link_libraries(ccls PRIVATE Psapi) endif() ### Definitions @@ -156,7 +147,6 @@ target_include_directories(ccls PRIVATE src third_party third_party/rapidjson/include - third_party/sparsepp third_party/loguru third_party/doctest) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index ab81ad615..9524ca234 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -70,6 +70,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE _Clang_find_library(Clang_LIBRARY clang) _Clang_find_add_library(clangDriver) +_Clang_find_add_library(clangBasic) _Clang_find_add_library(LLVMOption) _Clang_find_add_library(LLVMSupport) _Clang_find_add_library(LLVMDemangle) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 8ea334a8c..6d23be43d 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -1,10 +1,12 @@ #include "clang_complete.h" #include "clang_utils.h" -#include "filesystem.hh" #include "platform.h" #include "timer.h" +#include "filesystem.hh" +using namespace llvm; + #include #include @@ -29,8 +31,9 @@ unsigned Flags() { } std::string StripFileType(const std::string& path) { - fs::path p(path); - return p.parent_path() / p.stem(); + SmallString<128> Ret; + sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path)); + return Ret.str(); } unsigned GetCompletionPriority(const CXCompletionString& str, diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 5a25106a6..6a56d2195 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -1,8 +1,10 @@ #include "clang_utils.h" -#include "filesystem.hh" #include "platform.h" +#include "filesystem.hh" +using namespace llvm; + namespace { lsRange GetLsRangeForFixIt(const CXSourceRange& range) { @@ -115,8 +117,11 @@ std::string FileName(CXFile file) { // clang_getFileName return values may contain .. ret = NormalizePath(ToString(clang_getFileName(file))); // Resolve /usr/include/c++/7.3.0 symlink. - if (!StartsWith(ret, g_config->projectRoot)) - ret = fs::canonical(ret); + if (!StartsWith(ret, g_config->projectRoot)) { + SmallString<256> dest; + sys::fs::real_path(ret, dest); + ret = dest.str(); + } return ret; } diff --git a/src/filesystem.cc b/src/filesystem.cc index 541bdfcbb..f9d310047 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -1,8 +1,8 @@ #include "filesystem.hh" +using namespace llvm; #include "utils.h" -#include #include static void GetFilesInFolderHelper( @@ -10,31 +10,33 @@ static void GetFilesInFolderHelper( bool recursive, std::string output_prefix, const std::function& handler) { - std::queue> q; - q.emplace(fs::path(folder), fs::path(output_prefix)); - while (!q.empty()) { - try { - for (auto it = fs::directory_iterator(q.front().first); - it != fs::directory_iterator(); ++it) { - auto path = it->path(); - std::string filename = path.filename(); - if (filename[0] != '.' || filename == ".ccls") { - fs::file_status status = it->symlink_status(); - if (fs::is_regular_file(status)) - handler(q.front().second / filename); - else if (fs::is_directory(status) || fs::is_symlink(status)) { - if (recursive) { - std::string child_dir = q.front().second / filename; - if (fs::is_directory(status)) - q.push(make_pair(path, child_dir)); - } - } - } + std::error_code ec; + if (recursive) + for (sys::fs::recursive_directory_iterator I(folder, ec), E; I != E && !ec; + I.increment(ec)) { + std::string path = I->path(), filename = sys::path::filename(path); + if (filename[0] != '.' || filename == ".ccls") { + SmallString<256> Path; + if (output_prefix.size()) { + sys::path::append(Path, output_prefix, path); + handler(Path.str()); + } else + handler(path); + } + } + else + for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec; + I.increment(ec)) { + std::string path = I->path(), filename = sys::path::filename(path); + if (filename[0] != '.' || filename == ".ccls") { + SmallString<256> Path; + if (output_prefix.size()) { + sys::path::append(Path, output_prefix, path); + handler(Path.str()); + } else + handler(path); } - } catch (fs::filesystem_error&) { } - q.pop(); - } } void GetFilesInFolder(std::string folder, diff --git a/src/filesystem.hh b/src/filesystem.hh index dedce15e5..334810fc6 100644 --- a/src/filesystem.hh +++ b/src/filesystem.hh @@ -1,11 +1,11 @@ #pragma once -#include +#include +#include + #include #include -namespace fs = std::experimental::filesystem; - void GetFilesInFolder(std::string folder, bool recursive, bool add_folder_to_path, diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 6dfb3d3ea..a2d21e416 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,6 +1,5 @@ #include "cache_manager.h" #include "diagnostics_engine.h" -#include "filesystem.hh" #include "import_pipeline.h" #include "include_complete.h" #include "message_handler.h" @@ -11,6 +10,9 @@ #include "timer.h" #include "working_files.h" +#include "filesystem.hh" +using namespace llvm; + #include #include @@ -492,10 +494,10 @@ struct Handler_Initialize : BaseMessageHandler { config->projectRoot = project_path; // Create two cache directories for files inside and outside of the // project. - fs::create_directories(config->cacheDirectory + - EscapeFileName(config->projectRoot)); - fs::create_directories(config->cacheDirectory + '@' + - EscapeFileName(config->projectRoot)); + sys::fs::create_directories(config->cacheDirectory + + EscapeFileName(config->projectRoot)); + sys::fs::create_directories(config->cacheDirectory + '@' + + EscapeFileName(config->projectRoot)); g_config = std::move(config); Timer time; diff --git a/src/project.cc b/src/project.cc index 67c7f0a01..63ed720ef 100644 --- a/src/project.cc +++ b/src/project.cc @@ -35,15 +35,17 @@ using namespace llvm::opt; #include struct CompileCommandsEntry { - fs::path directory; + std::string directory; std::string file; std::string command; std::vector args; - fs::path ResolveIfRelative(fs::path path) const { - if (path.is_absolute()) + std::string ResolveIfRelative(std::string path) const { + if (sys::path::is_absolute(path)) return path; - return directory / path; + SmallString<256> Ret; + sys::path::append(Ret, directory, path); + return Ret.str(); } }; MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); @@ -56,7 +58,7 @@ struct ProjectConfig { std::unordered_set quote_dirs; std::unordered_set angle_dirs; std::vector extra_flags; - fs::path project_dir; + std::string project_dir; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -72,7 +74,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( const CompileCommandsEntry& entry) { Project::Entry result; result.filename = entry.file; - const std::string base_name = fs::path(entry.file).filename(); + const std::string base_name = sys::path::filename(entry.file); // Expand %c %cpp %clang std::vector args; @@ -145,7 +147,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (!Args.hasArg(OPT_resource_dir)) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (!Args.hasArg(OPT_working_directory)) - args.push_back("-working-directory=" + entry.directory.string()); + args.push_back("-working-directory=" + entry.directory); // There could be a clang version mismatch between what the project uses and // what ccls uses. Make sure we do not emit warnings for mismatched options. @@ -176,10 +178,11 @@ std::vector ReadCompilerArgumentsFromFile( std::vector LoadFromDirectoryListing(ProjectConfig* config) { std::vector result; config->mode = ProjectMode::DotCcls; - LOG_IF_S(WARNING, !fs::exists(config->project_dir / ".ccls") && - config->extra_flags.empty()) - << "ccls has no clang arguments. Considering adding either a " - "compile_commands.json or .ccls file. See the ccls README for " + SmallString<256> Path; + sys::path::append(Path, config->project_dir, ".ccls"); + LOG_IF_S(WARNING, !sys::fs::exists(Path) && config->extra_flags.empty()) + << "ccls has no clang arguments. Use either " + "compile_commands.json or .ccls, See ccls README for " "more information."; std::unordered_map> folder_args; @@ -190,21 +193,20 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { [&folder_args, &files](const std::string& path) { if (SourceFileLanguage(path) != LanguageId::Unknown) { files.push_back(path); - } else if (fs::path(path).filename() == ".ccls") { + } else if (sys::path::filename(path) == ".ccls") { LOG_S(INFO) << "Using .ccls arguments from " << path; - folder_args.emplace( - fs::path(path).parent_path().string(), - ReadCompilerArgumentsFromFile(path)); + folder_args.emplace(sys::path::parent_path(path), + ReadCompilerArgumentsFromFile(path)); } }); - const std::string project_dir = config->project_dir.string(); + const std::string& project_dir = config->project_dir; const auto& project_dir_args = folder_args[project_dir]; LOG_IF_S(INFO, !project_dir_args.empty()) << "Using .ccls arguments " << StringJoin(project_dir_args); - auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) { - while (!(cur = cur.parent_path()).empty()) { + auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) { + while (!(cur = sys::path::parent_path(cur)).empty()) { auto it = folder_args.find(cur); if (it != folder_args.end()) return it->second; @@ -235,16 +237,20 @@ std::vector LoadCompilationEntriesFromDirectory( ProjectConfig* project, const std::string& opt_compilation_db_dir) { // If there is a .ccls file always load using directory listing. - if (fs::exists(project->project_dir / ".ccls")) + SmallString<256> Path; + sys::path::append(Path, project->project_dir, ".ccls"); + if (sys::fs::exists(Path)) return LoadFromDirectoryListing(project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. - fs::path comp_db_dir; + std::string comp_db_dir; + Path.clear(); if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir.string() + comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir : opt_compilation_db_dir; + sys::path::append(Path, comp_db_dir, "compile_commands.json"); } else { project->mode = ProjectMode::ExternalCommand; #ifdef _WIN32 @@ -254,6 +260,7 @@ std::vector LoadCompilationEntriesFromDirectory( if (!mkdtemp(tmpdir)) return {}; comp_db_dir = tmpdir; + sys::path::append(Path, comp_db_dir, "compile_commands.json"); rapidjson::StringBuffer input; rapidjson::Writer writer(input); JsonWriter json_writer(&writer); @@ -262,14 +269,12 @@ std::vector LoadCompilationEntriesFromDirectory( std::vector{g_config->compilationDatabaseCommand, project->project_dir}, input.GetString()); - FILE* fout = fopen((comp_db_dir / "compile_commands.json").c_str(), "wb"); + FILE* fout = fopen(Path.c_str(), "wb"); fwrite(contents.c_str(), contents.size(), 1, fout); fclose(fout); #endif } - fs::path comp_db_path = comp_db_dir / "compile_commands.json"; - LOG_S(INFO) << "Trying to load " << comp_db_path.string(); CXCompilationDatabase_Error cx_db_load_error; CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( comp_db_dir.c_str(), &cx_db_load_error); @@ -277,17 +282,18 @@ std::vector LoadCompilationEntriesFromDirectory( #ifdef _WIN32 // TODO #else - unlink(comp_db_path.c_str()); + unlink(Path.c_str()); rmdir(comp_db_dir.c_str()); #endif } - if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { - LOG_S(INFO) << "Unable to load " << comp_db_path.string() + LOG_S(INFO) << "unable to load " << Path.c_str() << "; using directory listing instead."; return LoadFromDirectoryListing(project); } + LOG_S(INFO) << "loaded " << Path.c_str(); + Timer clang_time; Timer our_time; clang_time.Pause(); @@ -437,13 +443,12 @@ Project::Entry Project::FindCompilationEntryForFile( // |best_entry| probably has its own path in the arguments. We need to remap // that path to the new filename. - fs::path best_entry_base_name = fs::path(best_entry->filename).filename(); + std::string best_entry_base_name = sys::path::filename(best_entry->filename); for (std::string& arg : result.args) { try { if (arg == best_entry->filename || - fs::path(arg).filename() == best_entry_base_name) { + sys::path::filename(arg) == best_entry_base_name) arg = filename; - } } catch (...) { } } diff --git a/src/query.cc b/src/query.cc index 036f85e25..5ed2d77e2 100644 --- a/src/query.cc +++ b/src/query.cc @@ -154,7 +154,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { // Returns true if an element with the same file is found. template -bool TryReplaceDef(std::forward_list& def_list, Q&& def) { +bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { for (auto& def1 : def_list) if (def1.spell->file_id == def.spell->file_id) { def1 = std::move(def); @@ -262,18 +262,22 @@ void QueryDatabase::RemoveUsrs( case SymbolKind::Func: { for (auto usr : to_remove) { QueryFunc& func = Func(usr); - func.def.remove_if([=](const QueryFunc::Def& def) { + auto it = llvm::find_if(func.def, [=](const QueryFunc::Def& def) { return def.spell->file_id == file_id; }); + if (it != func.def.end()) + func.def.erase(it); } break; } case SymbolKind::Var: { for (auto usr : to_remove) { QueryVar& var = Var(usr); - var.def.remove_if([=](const QueryVar::Def& def) { + auto it = llvm::find_if(var.def, [=](const QueryVar::Def& def) { return def.spell->file_id == file_id; }); + if (it != var.def.end()) + var.def.erase(it); } break; } @@ -348,7 +352,7 @@ void QueryDatabase::Update(int file_id, QueryFunc& existing = Func(u.first); existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { - existing.def.push_front(std::move(def)); + existing.def.push_back(std::move(def)); UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, u.first); } } @@ -364,7 +368,7 @@ void QueryDatabase::Update(int file_id, QueryType& existing = Type(u.first); existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { - existing.def.push_front(std::move(def)); + existing.def.push_back(std::move(def)); UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, u.first); } } @@ -380,7 +384,7 @@ void QueryDatabase::Update(int file_id, QueryVar& existing = Var(u.first); existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) { - existing.def.push_front(std::move(def)); + existing.def.push_back(std::move(def)); if (!existing.def.front().is_local()) UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first); } diff --git a/src/query.h b/src/query.h index 571f1a4e6..f85d986b0 100644 --- a/src/query.h +++ b/src/query.h @@ -3,9 +3,8 @@ #include "indexer.h" #include "serializer.h" -#include - -#include +#include +#include struct QueryFile; struct QueryType; @@ -69,7 +68,7 @@ using UsrUpdate = struct QueryFunc : QueryEntity { Usr usr; int symbol_idx = -1; - std::forward_list def; + llvm::SmallVector def; std::vector declarations; std::vector uses; std::vector derived; @@ -78,7 +77,7 @@ struct QueryFunc : QueryEntity { struct QueryType : QueryEntity { Usr usr; int symbol_idx = -1; - std::forward_list def; + llvm::SmallVector def; std::vector declarations; std::vector uses; std::vector derived; @@ -88,7 +87,7 @@ struct QueryType : QueryEntity { struct QueryVar : QueryEntity { Usr usr; int symbol_idx = -1; - std::forward_list def; + llvm::SmallVector def; std::vector declarations; std::vector uses; }; @@ -138,9 +137,9 @@ struct QueryDatabase { std::vector files; std::unordered_map name2file_id; - spp::sparse_hash_map usr2func; - spp::sparse_hash_map usr2type; - spp::sparse_hash_map usr2var; + llvm::DenseMap usr2func; + llvm::DenseMap usr2type; + llvm::DenseMap usr2var; // Marks the given Usrs as invalid. void RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove); diff --git a/src/query_utils.h b/src/query_utils.h index 59bbc4270..3b57ae9d8 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -11,7 +11,7 @@ Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. template -std::vector GetDeclarations(spp::sparse_hash_map& usr2entity, +std::vector GetDeclarations(llvm::DenseMap& usr2entity, const std::vector& usrs) { std::vector ret; ret.reserve(usrs.size()); @@ -135,7 +135,7 @@ void EachOccurrenceWithParent(QueryDatabase* db, } template -void EachDefinedEntity(spp::sparse_hash_map& collection, +void EachDefinedEntity(llvm::DenseMap& collection, const std::vector& usrs, Fn&& fn) { for (Usr usr : usrs) { diff --git a/src/serializer.cc b/src/serializer.cc index fd07a045f..b98abbde2 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -160,7 +160,7 @@ void Reflect(Writer& visitor, IndexInclude& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); if (gTestOutputMode) { - std::string basename = fs::path(value.resolved_path).filename(); + std::string basename = llvm::sys::path::filename(value.resolved_path); if (!StartsWith(value.resolved_path, "&")) basename = "&" + basename; REFLECT_MEMBER2("resolved_path", basename); diff --git a/src/utils.cc b/src/utils.cc index f9632f3aa..57a5319f3 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,6 +1,7 @@ #include "utils.h" #include "filesystem.hh" +using namespace llvm; #include "platform.h" #include @@ -137,12 +138,10 @@ void WriteToFile(const std::string& filename, const std::string& content) { } std::optional LastWriteTime(const std::string& filename) { - std::error_code ec; - auto ftime = fs::last_write_time(filename, ec); - if (ec) return std::nullopt; - return std::chrono::time_point_cast(ftime) - .time_since_epoch() - .count(); + sys::fs::file_status Status; + if (sys::fs::status(filename, Status)) + return {}; + return Status.getLastModificationTime().time_since_epoch().count(); } std::string GetDefaultResourceDirectory() { diff --git a/third_party/sparsepp b/third_party/sparsepp deleted file mode 160000 index 1ca7189fe..000000000 --- a/third_party/sparsepp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1ca7189fe81ee8c59bf08196852f70843a68a63a From 576959e460156f498f2236087ef3648bf983df15 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 13 May 2018 19:09:26 -0700 Subject: [PATCH 099/378] Congratulations to Tea Deliverers --- CMakeLists.txt | 5 +---- cmake/FindClang.cmake | 13 +++++++++---- src/filesystem.cc | 37 +++++++++++-------------------------- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 010258ad0..05aa3e0b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ option(SYSTEM_CLANG "Use system installation of Clang instead of \ downloading Clang" OFF) option(ASAN "Compile with address sanitizers" OFF) option(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" OFF) +option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") @@ -105,11 +106,7 @@ endif() # See cmake/FindClang.cmake find_package(Clang ${CLANG_VERSION} REQUIRED) -find_package(Curses REQUIRED) target_link_libraries(ccls PRIVATE Clang::Clang) -if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) - target_link_libraries(ccls PRIVATE Clang::Clang ${CURSES_LIBRARIES}) -endif() # Enable threading support set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 9524ca234..cc808ccc7 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -71,9 +71,13 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE _Clang_find_library(Clang_LIBRARY clang) _Clang_find_add_library(clangDriver) _Clang_find_add_library(clangBasic) -_Clang_find_add_library(LLVMOption) -_Clang_find_add_library(LLVMSupport) -_Clang_find_add_library(LLVMDemangle) +if(USE_SHARED_LLVM) + _Clang_find_add_library(LLVM) +else() + _Clang_find_add_library(LLVMOption) + _Clang_find_add_library(LLVMSupport) + _Clang_find_add_library(LLVMDemangle) +endif() _Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) _Clang_find_path(Clang_BUILD_INCLUDE_DIR clang/Driver/Options.inc) _Clang_find_path(LLVM_INCLUDE_DIR llvm/PassInfo.h) @@ -113,5 +117,6 @@ if(Clang_FOUND AND NOT TARGET Clang::Clang) IMPORTED_LOCATION ${Clang_LIBRARY} INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") - set_property(TARGET Clang::Clang PROPERTY INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES}) + find_package(Curses REQUIRED) + set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES}") endif() diff --git a/src/filesystem.cc b/src/filesystem.cc index f9d310047..1b343b144 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -5,23 +5,20 @@ using namespace llvm; #include -static void GetFilesInFolderHelper( - std::string folder, - bool recursive, - std::string output_prefix, - const std::function& handler) { +void GetFilesInFolder(std::string folder, + bool recursive, + bool dir_prefix, + const std::function& handler) { + EnsureEndsInSlash(folder); std::error_code ec; if (recursive) for (sys::fs::recursive_directory_iterator I(folder, ec), E; I != E && !ec; I.increment(ec)) { std::string path = I->path(), filename = sys::path::filename(path); if (filename[0] != '.' || filename == ".ccls") { - SmallString<256> Path; - if (output_prefix.size()) { - sys::path::append(Path, output_prefix, path); - handler(Path.str()); - } else - handler(path); + if (!dir_prefix) + path = path.substr(folder.size()); + handler(path); } } else @@ -29,21 +26,9 @@ static void GetFilesInFolderHelper( I.increment(ec)) { std::string path = I->path(), filename = sys::path::filename(path); if (filename[0] != '.' || filename == ".ccls") { - SmallString<256> Path; - if (output_prefix.size()) { - sys::path::append(Path, output_prefix, path); - handler(Path.str()); - } else - handler(path); + if (!dir_prefix) + path = path.substr(folder.size()); + handler(path); } } } - -void GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path, - const std::function& handler) { - EnsureEndsInSlash(folder); - GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "", - handler); -} From 19d0aad2ca9663b5633b575efe41803005b21d38 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 14 May 2018 09:52:28 -0700 Subject: [PATCH 100/378] clean up clang_complete found by scturtle; clean up project --- src/clang_complete.cc | 1 - src/clang_complete.h | 4 ---- src/project.cc | 19 ------------------- 3 files changed, 24 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 6d23be43d..6d344da0f 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -776,7 +776,6 @@ std::shared_ptr ClangCompleteManager::TryGetSession( // If this request is for a completion, we should move it to // |completion_sessions|. if (mark_as_completion) { - assert(!completion_sessions_.TryGet(filename)); preloaded_sessions_.TryTake(filename); completion_sessions_.Insert(filename, preloaded_session); } diff --git a/src/clang_complete.h b/src/clang_complete.h index ee0cd6a7b..aa471c8ec 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -44,10 +44,6 @@ struct ClangCompleteManager { using OnDiagnostic = std::function diagnostics)>; - using OnIndex = std::function& unsaved, - const std::string& path, - const std::vector& args)>; using OnComplete = std::function& results, bool is_cached_result)>; diff --git a/src/project.cc b/src/project.cc index 63ed720ef..7f8dfbff1 100644 --- a/src/project.cc +++ b/src/project.cc @@ -95,25 +95,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( if (args.empty()) return result; - std::string first_arg = args[0]; - // Windows' filesystem is not case sensitive, so we compare only - // the lower case variant. - std::transform(first_arg.begin(), first_arg.end(), first_arg.begin(), - tolower); - bool clang_cl = strstr(first_arg.c_str(), "clang-cl") || - strstr(first_arg.c_str(), "cl.exe"); - // Clang only cares about the last --driver-mode flag, so the loop - // iterates in reverse to find the last one as soon as possible - // in case of multiple --driver-mode flags. - for (int i = args.size() - 1; i >= 0; --i) { - if (strstr(args[i].c_str(), "--dirver-mode=")) { - clang_cl = clang_cl || strstr(args[i].c_str(), "--driver-mode=cl"); - break; - } - } - // Compiler driver. - result.args.push_back(args[0]); - std::unique_ptr Opts = driver::createDriverOptTable(); unsigned MissingArgIndex, MissingArgCount; std::vector cargs; From ba45e7ca6375f8dbcbedca5e939dc6e1bc101cda Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 14 May 2018 22:13:18 -0700 Subject: [PATCH 101/378] cmake: link against zlib; use StringMap --- cmake/FindClang.cmake | 3 +- src/import_pipeline.cc | 11 ++-- src/indexer.h | 4 +- src/message_handler.cc | 17 +++--- src/messages/text_document_definition.cc | 2 +- src/method.cc | 2 +- src/project.cc | 14 +++-- src/query.cc | 2 +- src/query.h | 9 ++-- src/query_utils.h | 4 +- src/serializer.cc | 66 ++++++++++++++++-------- src/serializer.h | 26 ---------- 12 files changed, 78 insertions(+), 82 deletions(-) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index cc808ccc7..ad085d483 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -118,5 +118,6 @@ if(Clang_FOUND AND NOT TARGET Clang::Clang) INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") find_package(Curses REQUIRED) - set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES}") + find_package(ZLIB REQUIRED) + set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES};${ZLIB_LIBRARIES}") endif() diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index 625ba878a..5ed8ebd86 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -115,11 +115,11 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, path_to_index, entry.args, std::nullopt)) reparse = 2; for (const auto& dep : prev->dependencies) - if (auto write_time1 = LastWriteTime(dep.first)) { + if (auto write_time1 = LastWriteTime(dep.first().str())) { if (dep.second < *write_time1) { reparse = 2; std::lock_guard lock(vfs->mutex); - vfs->state[dep.first].stage = 0; + vfs->state[dep.first().str()].stage = 0; } } else reparse = 2; @@ -134,8 +134,8 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, request.is_interactive); } for (const auto& dep : dependencies) - if (vfs->Mark(dep.first, 0, 2)) { - prev = cache.RawCacheLoad(dep.first); + if (vfs->Mark(dep.first().str(), 0, 2)) { + prev = cache.RawCacheLoad(dep.first().str()); IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), request.is_interactive); @@ -189,7 +189,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (entry.id >= 0) { std::lock_guard lock(project->mutex_); for (auto& dep : curr->dependencies) - project->absolute_path_to_entry_index_[dep.first] = entry.id; + project->absolute_path_to_entry_index_[dep.first()] = entry.id; } // Build delta update. @@ -388,7 +388,6 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, } // Run query db main loop. - SetThreadName("querydb"); auto* queue = QueueManager::instance(); while (true) { std::vector> messages = diff --git a/src/indexer.h b/src/indexer.h index 12bed98cb..55dc00e8d 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -13,6 +13,8 @@ #include "symbol.h" #include "utils.h" +#include + #include #include #include @@ -297,7 +299,7 @@ struct IndexFile { std::vector skipped_by_preprocessor; std::vector includes; - std::unordered_map dependencies; + llvm::StringMap dependencies; std::unordered_map usr2func; std::unordered_map usr2type; std::unordered_map usr2var; diff --git a/src/message_handler.cc b/src/message_handler.cc index a16f59bb9..cf17c0139 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -245,15 +245,14 @@ void EmitSemanticHighlighting(QueryDatabase* db, detailed_name.substr(0, detailed_name.find('<')); int16_t start_line = sym.range.start.line; int16_t start_col = sym.range.start.column; - if (start_line >= 0 && start_line < working_file->index_lines.size()) { - std::string_view line = working_file->index_lines[start_line]; - sym.range.end.line = start_line; - if (start_col + concise_name.size() <= line.size() && - line.compare(start_col, concise_name.size(), concise_name) == 0) - sym.range.end.column = start_col + concise_name.size(); - else - continue; // applies to for loop - } + if (start_line < 0 || start_line >= working_file->index_lines.size()) + continue; + std::string_view line = working_file->index_lines[start_line]; + sym.range.end.line = start_line; + if (!(start_col + concise_name.size() <= line.size() && + line.compare(start_col, concise_name.size(), concise_name) == 0)) + continue; + sym.range.end.column = start_col + concise_name.size(); break; } case SymbolKind::Type: diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 103436d19..1d7e545a4 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -155,7 +155,7 @@ struct Handler_TextDocumentDefinition auto pos = name.rfind(query); if (pos != std::string::npos) { std::get<0>(score) = int(name.size() - query.size()); - std::get<1>(score) = -pos; + std::get<1>(score) = -int(pos); } if (score < best_score) { best_score = score; diff --git a/src/method.cc b/src/method.cc index f0ba5ce18..38da766aa 100644 --- a/src/method.cc +++ b/src/method.cc @@ -12,7 +12,7 @@ MethodType kMethodType_CclsPublishSemanticHighlighting = void Reflect(Reader& visitor, lsRequestId& value) { if (visitor.IsInt64()) { value.type = lsRequestId::kInt; - value.value = visitor.GetInt64(); + value.value = int(visitor.GetInt64()); } else if (visitor.IsInt()) { value.type = lsRequestId::kInt; value.value = visitor.GetInt(); diff --git a/src/project.cc b/src/project.cc index 7f8dfbff1..063c9e5ab 100644 --- a/src/project.cc +++ b/src/project.cc @@ -16,6 +16,8 @@ #include #include #include +#include +#include using namespace clang; using namespace llvm; using namespace llvm::opt; @@ -29,7 +31,6 @@ using namespace llvm::opt; #include #endif -#include #include #include #include @@ -145,14 +146,11 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( std::vector ReadCompilerArgumentsFromFile( const std::string& path) { + auto MBOrErr = MemoryBuffer::getFile(path); + if (!MBOrErr) return {}; std::vector args; - std::ifstream fin(path); - for (std::string line; std::getline(fin, line);) { - TrimInPlace(line); - if (line.empty() || StartsWith(line, "#")) - continue; - args.push_back(line); - } + for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) + args.push_back(*I); return args; } diff --git a/src/query.cc b/src/query.cc index 5ed2d77e2..59edfe03a 100644 --- a/src/query.cc +++ b/src/query.cc @@ -77,7 +77,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { def.inactive_regions = std::move(indexed.skipped_by_preprocessor); def.dependencies.reserve(indexed.dependencies.size()); for (auto& dep : indexed.dependencies) - def.dependencies.push_back(dep.first); + def.dependencies.push_back(dep.first()); def.language = indexed.language; auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { diff --git a/src/query.h b/src/query.h index f85d986b0..0186e0704 100644 --- a/src/query.h +++ b/src/query.h @@ -3,7 +3,6 @@ #include "indexer.h" #include "serializer.h" -#include #include struct QueryFile; @@ -136,10 +135,10 @@ struct QueryDatabase { std::vector symbols; std::vector files; - std::unordered_map name2file_id; - llvm::DenseMap usr2func; - llvm::DenseMap usr2type; - llvm::DenseMap usr2var; + llvm::StringMap name2file_id; + std::unordered_map usr2func; + std::unordered_map usr2type; + std::unordered_map usr2var; // Marks the given Usrs as invalid. void RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove); diff --git a/src/query_utils.h b/src/query_utils.h index 3b57ae9d8..e76d32128 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -11,7 +11,7 @@ Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. template -std::vector GetDeclarations(llvm::DenseMap& usr2entity, +std::vector GetDeclarations(std::unordered_map& usr2entity, const std::vector& usrs) { std::vector ret; ret.reserve(usrs.size()); @@ -135,7 +135,7 @@ void EachOccurrenceWithParent(QueryDatabase* db, } template -void EachDefinedEntity(llvm::DenseMap& collection, +void EachDefinedEntity(std::unordered_map& collection, const std::vector& usrs, Fn&& fn) { for (Usr usr : usrs) { diff --git a/src/serializer.cc b/src/serializer.cc index b98abbde2..734c147ac 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -10,6 +10,8 @@ #include +using namespace llvm; + bool gTestOutputMode = false; //// Elementary types @@ -149,6 +151,49 @@ void Reflect(Writer& visitor, JsonNull& value) { visitor.Null(); } +// std::unordered_map +template +void Reflect(Reader& visitor, std::unordered_map& map) { + visitor.IterArray([&](Reader& entry) { + V val; + Reflect(entry, val); + auto usr = val.usr; + map[usr] = std::move(val); + }); +} +template +void Reflect(Writer& visitor, std::unordered_map& map) { + std::vector> xs(map.begin(), map.end()); + std::sort(xs.begin(), xs.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); + visitor.StartArray(xs.size()); + for (auto& it : xs) + Reflect(visitor, it.second); + visitor.EndArray(); +} + +// Used by IndexFile::dependencies. Timestamps are emitted for Binary. +void Reflect(Reader& visitor, StringMap& map) { + visitor.IterArray([&](Reader& entry) { + std::string name; + Reflect(entry, name); + if (visitor.Format() == SerializeFormat::Binary) + Reflect(entry, map[name]); + else + map[name] = 0; + }); +} +void Reflect(Writer& visitor, StringMap& map) { + visitor.StartArray(map.size()); + for (auto& it : map) { + std::string key = it.first(); + Reflect(visitor, key); + if (visitor.Format() == SerializeFormat::Binary) + Reflect(visitor, it.second); + } + visitor.EndArray(); +} + // TODO: Move this to indexer.cc void Reflect(Reader& visitor, IndexInclude& value) { REFLECT_MEMBER_START(); @@ -313,27 +358,6 @@ void Reflect(Writer& visitor, SerializeFormat& value) { } } -void Reflect(Reader& visitor, std::unordered_map& map) { - visitor.IterArray([&](Reader& entry) { - std::string name; - Reflect(entry, name); - if (visitor.Format() == SerializeFormat::Binary) - Reflect(entry, map[name]); - else - map[name] = 0; - }); -} -void Reflect(Writer& visitor, std::unordered_map& map) { - visitor.StartArray(map.size()); - for (auto& it : map) { - std::string key = it.first; - Reflect(visitor, key); - if (visitor.Format() == SerializeFormat::Binary) - Reflect(visitor, it.second); - } - visitor.EndArray(); -} - std::string Serialize(SerializeFormat format, IndexFile& file) { switch (format) { case SerializeFormat::Binary: { diff --git a/src/serializer.h b/src/serializer.h index 3e1bfe87a..cc296c796 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -13,7 +13,6 @@ #include #include #include -#include #include enum class SerializeFormat { Binary, Json }; @@ -282,31 +281,6 @@ void Reflect(Writer& visitor, std::vector& values) { visitor.EndArray(); } -// std::unordered_map -template -void Reflect(Reader& visitor, std::unordered_map& map) { - visitor.IterArray([&](Reader& entry) { - V val; - Reflect(entry, val); - auto usr = val.usr; - map[usr] = std::move(val); - }); -} -template -void Reflect(Writer& visitor, std::unordered_map& map) { - std::vector> xs(map.begin(), map.end()); - std::sort(xs.begin(), xs.end(), - [](const auto& a, const auto& b) { return a.first < b.first; }); - visitor.StartArray(xs.size()); - for (auto& it : xs) - Reflect(visitor, it.second); - visitor.EndArray(); -} - -// Used by IndexFile::dependencies. Timestamps are emitted for Binary. -void Reflect(Reader& visitor, std::unordered_map& map); -void Reflect(Writer& visitor, std::unordered_map& map); - // ReflectMember template From 4e2f64893cb95eaa48a128a0e1dec20c31d3c261 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 16 May 2018 23:49:21 -0700 Subject: [PATCH 102/378] textDocument/references: include base references by default --- README.md | 15 +++++- src/filesystem.cc | 31 ++++++------- src/indexer.h | 3 ++ src/messages/text_document_references.cc | 58 ++++++++++++++++++------ src/project.cc | 11 +++-- src/query_utils.h | 24 ---------- src/threaded_queue.h | 38 ++-------------- 7 files changed, 89 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 35553bfcf..0da7b661c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,20 @@ a C/C++/Objective-C language server. * preprocessor skipped regions * semantic highlighting, including support for [rainbow semantic highlighting](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e) -It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ]). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. +It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ](../../wiki/FAQ). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. + +The comparison with cquery as noted on 2018-05-17: + +| | cquery | ccls | +|------------ |--------------------------------|---------------------------| +| third_party | more | fewer | +| C++ | C++14 | C++17 | +| clang API | libclang (C) | libclang + clang/llvm C++ | +| Filesystem | AbsolutePath + custom routines | llvm/Support | +| index | | slight enhancement | +| pipeline | index merge+id remapping | simpler and more robust | + +cquery has system include path detection (through running the compiler driver) while ccls does not. # >>> [Getting started](../../wiki/Getting-started) (CLICK HERE) <<< diff --git a/src/filesystem.cc b/src/filesystem.cc index 1b343b144..b3c31fe61 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -3,32 +3,31 @@ using namespace llvm; #include "utils.h" -#include +#include void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix, const std::function& handler) { EnsureEndsInSlash(folder); - std::error_code ec; - if (recursive) - for (sys::fs::recursive_directory_iterator I(folder, ec), E; I != E && !ec; - I.increment(ec)) { - std::string path = I->path(), filename = sys::path::filename(path); - if (filename[0] != '.' || filename == ".ccls") { - if (!dir_prefix) - path = path.substr(folder.size()); - handler(path); - } - } - else + std::vector st{folder}; + while (st.size()) { + std::error_code ec; + folder = st.back(); + st.pop_back(); for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec; I.increment(ec)) { + auto Status = I->status(); + if (!Status) continue; std::string path = I->path(), filename = sys::path::filename(path); if (filename[0] != '.' || filename == ".ccls") { - if (!dir_prefix) - path = path.substr(folder.size()); - handler(path); + if (sys::fs::is_regular_file(*Status)) { + if (!dir_prefix) + path = path.substr(folder.size()); + handler(path); + } else if (recursive && sys::fs::is_directory(*Status)) + st.push_back(path); } } + } } diff --git a/src/indexer.h b/src/indexer.h index 55dc00e8d..2c35784eb 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -114,6 +114,7 @@ struct FuncDef : NameMixin { lsSymbolKind kind = lsSymbolKind::Unknown; StorageClass storage = StorageClass::Invalid; + std::vector GetBases() const { return bases; } bool operator==(const FuncDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && extent == o.extent && declaring_type == o.declaring_type && @@ -182,6 +183,7 @@ struct TypeDef : NameMixin { int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; + std::vector GetBases() const { return bases; } bool operator==(const TypeDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && extent == o.extent && alias_of == o.alias_of && bases == o.bases && @@ -240,6 +242,7 @@ struct VarDef : NameMixin { bool is_local() const { return kind == lsSymbolKind::Variable; } + std::vector GetBases() const { return {}; } bool operator==(const VarDef& o) const { return detailed_name == o.detailed_name && spell == o.spell && extent == o.extent && type == o.type && kind == o.kind && diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index 53232609f..dce6e5b74 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -2,7 +2,7 @@ #include "query_utils.h" #include "queue_manager.h" -#include +#include namespace { MethodType kMethodType = "textDocument/references"; @@ -10,8 +10,9 @@ MethodType kMethodType = "textDocument/references"; struct In_TextDocumentReferences : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct lsReferenceContext { + bool base = true; // Include the declaration of the current symbol. - bool includeDeclaration; + bool includeDeclaration = false; // Include references with these |Role| bits set. Role role = Role::All; }; @@ -24,6 +25,7 @@ struct In_TextDocumentReferences : public RequestInMessage { Params params; }; MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, + base, includeDeclaration, role); MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, @@ -60,17 +62,47 @@ struct Handler_TextDocumentReferences for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { // Found symbol. Return references. - EachOccurrenceWithParent( - db, sym, params.context.includeDeclaration, - [&](Use use, lsSymbolKind parent_kind) { - if (use.role & params.context.role) - if (std::optional ls_loc = - GetLsLocationEx(db, working_files, use, container)) { - if (container) - ls_loc->parentKind = parent_kind; - out.result.push_back(*ls_loc); - } - }); + std::unordered_set seen; + seen.insert(sym.usr); + std::vector stack{sym.usr}; + if (sym.kind != SymbolKind::Func) + params.context.base = false; + while (stack.size()) { + sym.usr = stack.back(); + stack.pop_back(); + auto fn = [&](Use use, lsSymbolKind parent_kind) { + if (use.role & params.context.role) + if (std::optional ls_loc = + GetLsLocationEx(db, working_files, use, container)) { + if (container) + ls_loc->parentKind = parent_kind; + out.result.push_back(*ls_loc); + } + }; + WithEntity(db, sym, [&](const auto& entity) { + lsSymbolKind parent_kind = lsSymbolKind::Unknown; + for (auto& def : entity.def) + if (def.spell) { + parent_kind = GetSymbolKind(db, sym); + if (params.context.base) + for (Usr usr : def.GetBases()) + if (!seen.count(usr)) { + seen.insert(usr); + stack.push_back(usr); + } + break; + } + for (Use use : entity.uses) + fn(use, parent_kind); + if (params.context.includeDeclaration) { + for (auto& def : entity.def) + if (def.spell) + fn(*def.spell, parent_kind); + for (Use use : entity.declarations) + fn(use, parent_kind); + } + }); + } break; } diff --git a/src/project.cc b/src/project.cc index 063c9e5ab..4800033b0 100644 --- a/src/project.cc +++ b/src/project.cc @@ -95,6 +95,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( } if (args.empty()) return result; + args.insert(args.end(), config->extra_flags.begin(), + config->extra_flags.end()); std::unique_ptr Opts = driver::createDriverOptTable(); unsigned MissingArgIndex, MissingArgCount; @@ -111,6 +113,11 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( config->angle_dirs.insert(entry.ResolveIfRelative(A->getValue())); for (const auto* A : Args.filtered(OPT_I, OPT_iquote)) config->quote_dirs.insert(entry.ResolveIfRelative(A->getValue())); + for (const auto* A : Args.filtered(OPT_idirafter)) { + std::string dir = entry.ResolveIfRelative(A->getValue()); + config->angle_dirs.insert(dir); + config->quote_dirs.insert(dir); + } for (size_t i = 1; i < args.size(); i++) // This is most likely the file path we will be passing to clang. The @@ -122,10 +129,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - // We don't do any special processing on user-given extra flags. - for (const auto& flag : config->extra_flags) - args.push_back(flag); - if (!Args.hasArg(OPT_resource_dir)) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (!Args.hasArg(OPT_working_directory)) diff --git a/src/query_utils.h b/src/query_utils.h index e76d32128..1e65b2a3c 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -110,30 +110,6 @@ void EachOccurrence(QueryDatabase* db, lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym); -template -void EachOccurrenceWithParent(QueryDatabase* db, - SymbolIdx sym, - bool include_decl, - Fn&& fn) { - WithEntity(db, sym, [&](const auto& entity) { - lsSymbolKind parent_kind = lsSymbolKind::Unknown; - for (auto& def : entity.def) - if (def.spell) { - parent_kind = GetSymbolKind(db, sym); - break; - } - for (Use use : entity.uses) - fn(use, parent_kind); - if (include_decl) { - for (auto& def : entity.def) - if (def.spell) - fn(*def.spell, parent_kind); - for (Use use : entity.declarations) - fn(use, parent_kind); - } - }); -} - template void EachDefinedEntity(std::unordered_map& collection, const std::vector& usrs, diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 70e502521..93f1ccf1f 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -69,13 +69,11 @@ struct MultiQueueWaiter { template struct ThreadedQueue : public BaseThreadQueue { public: - ThreadedQueue() : total_count_(0) { + ThreadedQueue() { owned_waiter_ = std::make_unique(); waiter_ = owned_waiter_.get(); } - - explicit ThreadedQueue(MultiQueueWaiter* waiter) - : total_count_(0), waiter_(waiter) {} + explicit ThreadedQueue(MultiQueueWaiter* waiter) : waiter_(waiter) {} // Returns the number of elements in the queue. This is lock-free. size_t Size() const { return total_count_; } @@ -92,10 +90,6 @@ struct ThreadedQueue : public BaseThreadQueue { waiter_->cv.notify_one(); } - void PushFront(T&& t, bool priority = false) { - Push<&std::deque::push_front>(std::move(t), priority); - } - void PushBack(T&& t, bool priority = false) { Push<&std::deque::push_back>(std::move(t), priority); } @@ -162,7 +156,7 @@ struct ThreadedQueue : public BaseThreadQueue { // Get the first element from the queue without blocking. Returns a null // value if the queue is empty. - std::optional TryPopFrontHelper(int which) { + std::optional TryPopFront() { std::lock_guard lock(mutex_); auto execute = [&](std::deque* q) { auto val = std::move(q->front()); @@ -170,35 +164,13 @@ struct ThreadedQueue : public BaseThreadQueue { --total_count_; return std::move(val); }; - if (which & 2 && priority_.size()) + if (priority_.size()) return execute(&priority_); - if (which & 1 && queue_.size()) - return execute(&queue_); - return std::nullopt; - } - - std::optional TryPopFront() { return TryPopFrontHelper(3); } - - std::optional TryPopBack() { - std::lock_guard lock(mutex_); - auto execute = [&](std::deque* q) { - auto val = std::move(q->back()); - q->pop_back(); - --total_count_; - return std::move(val); - }; - // Reversed if (queue_.size()) return execute(&queue_); - if (priority_.size()) - return execute(&priority_); return std::nullopt; } - std::optional TryPopFrontLow() { return TryPopFrontHelper(1); } - - std::optional TryPopFrontHigh() { return TryPopFrontHelper(2); } - template void Iterate(Fn fn) { std::lock_guard lock(mutex_); @@ -211,7 +183,7 @@ struct ThreadedQueue : public BaseThreadQueue { mutable std::mutex mutex_; private: - std::atomic total_count_; + std::atomic total_count_{0}; std::deque priority_; std::deque queue_; MultiQueueWaiter* waiter_; From 32bde07df64cd6958e19c100c25bab1c1a36f6b7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 19 May 2018 23:40:07 -0700 Subject: [PATCH 103/378] filesystem.cc: deduplicate with UniqueID --- src/filesystem.cc | 53 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/filesystem.cc b/src/filesystem.cc index b3c31fe61..7ff90c851 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -3,6 +3,7 @@ using namespace llvm; #include "utils.h" +#include #include void GetFilesInFolder(std::string folder, @@ -10,23 +11,47 @@ void GetFilesInFolder(std::string folder, bool dir_prefix, const std::function& handler) { EnsureEndsInSlash(folder); - std::vector st{folder}; - while (st.size()) { - std::error_code ec; - folder = st.back(); - st.pop_back(); - for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec; - I.increment(ec)) { - auto Status = I->status(); - if (!Status) continue; - std::string path = I->path(), filename = sys::path::filename(path); - if (filename[0] != '.' || filename == ".ccls") { - if (sys::fs::is_regular_file(*Status)) { + sys::fs::file_status Status; + if (sys::fs::status(folder, Status, true)) + return; + sys::fs::UniqueID ID; + std::vector curr{folder}; + std::vector> succ; + std::set seen{Status.getUniqueID()}; + while (curr.size() || succ.size()) { + if (curr.empty()) { + for (auto& it : succ) + if (!seen.count(it.second.getUniqueID())) + curr.push_back(std::move(it.first)); + succ.clear(); + } else { + std::error_code ec; + std::string folder1 = curr.back(); + curr.pop_back(); + for (sys::fs::directory_iterator I(folder1, ec, false), E; I != E && !ec; + I.increment(ec)) { + std::string path = I->path(), filename = sys::path::filename(path); + if ((filename[0] == '.' && filename != ".ccls") || + sys::fs::status(path, Status, false)) + continue; + if (sys::fs::is_symlink_file(Status)) { + if (sys::fs::status(path, Status, true)) + continue; + if (sys::fs::is_directory(Status)) { + if (recursive) + succ.emplace_back(path, Status); + continue; + } + } + if (sys::fs::is_regular_file(Status)) { if (!dir_prefix) path = path.substr(folder.size()); handler(path); - } else if (recursive && sys::fs::is_directory(*Status)) - st.push_back(path); + } else if (recursive && sys::fs::is_directory(Status) && + !seen.count(ID = Status.getUniqueID())) { + curr.push_back(path); + seen.insert(ID); + } } } } From 07f0cdbf382aa955126ff3e90e74816186390b52 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 25 May 2018 22:48:58 -0700 Subject: [PATCH 104/378] Simplify; improve $ccls/inheritanceHierarchy --- src/messages/ccls_inheritance_hierarchy.cc | 21 +- src/messages/initialize.cc | 204 +++++++++--------- src/messages/text_document_did_change.cc | 14 +- src/messages/text_document_did_open.cc | 2 +- src/messages/text_document_did_save.cc | 14 +- .../workspace_did_change_watched_files.cc | 15 +- src/project.cc | 12 +- src/queue_manager.cc | 16 +- src/queue_manager.h | 2 - 9 files changed, 134 insertions(+), 166 deletions(-) diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 3f9605444..bbf255a13 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -2,6 +2,8 @@ #include "query_utils.h" #include "queue_manager.h" +#include + namespace { MethodType kMethodType = "$ccls/inheritanceHierarchy"; @@ -79,19 +81,22 @@ bool ExpandHelper(MessageHandler* m, int levels, Q& entity) { const auto* def = entity.AnyDef(); - if (!def) { + if (def) { + entry->name = def->Name(qualified); + if (def->spell) { + if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + entry->location = *loc; + } + } else if (!derived) { entry->numChildren = 0; return false; } - entry->name = def->Name(qualified); - if (def->spell) { - if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def->spell)) - entry->location = *loc; - } + std::unordered_set seen; if (derived) { if (levels > 0) { for (auto usr : entity.derived) { + if (seen.insert(usr).second) + continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); entry1.usr = usr; @@ -105,6 +110,8 @@ bool ExpandHelper(MessageHandler* m, } else { if (levels > 0) { for (auto usr : def->bases) { + if (seen.insert(usr).second) + continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); entry1.usr = usr; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index a2d21e416..fc4bc4d92 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -267,12 +267,8 @@ struct lsTextDocumentClientCapabilities { // and `${3:foo}`. `$0` defines the final tab stop, it defaults to // the end of the snippet. Placeholders with equal identifiers are linked, // that is typing in one will update others too. - std::optional snippetSupport; - }; - - // The client supports the following `CompletionItem` specific - // capabilities. - std::optional completionItem; + bool snippetSupport = false; + } completionItem; } completion; struct lsGenericDynamicReg { @@ -426,114 +422,110 @@ struct Handler_Initialize : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_InitializeRequest* request) override { - // Log initialization parameters. - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer(&writer); - Reflect(json_writer, request->params.initializationOptions); - LOG_S(INFO) << "Init parameters: " << output.GetString(); - std::unique_ptr config; - - if (request->params.rootUri) { - std::string project_path = - NormalizePath(request->params.rootUri->GetPath()); - LOG_S(INFO) << "[querydb] Initialize in directory " << project_path - << " with uri " << request->params.rootUri->raw_uri; - - { - if (request->params.initializationOptions) - config = std::make_unique(*request->params.initializationOptions); - else - config = std::make_unique(); - rapidjson::Document reader; - reader.Parse(g_init_options.c_str()); - if (!reader.HasParseError()) { - JsonReader json_reader{&reader}; - try { - Reflect(json_reader, *config); - } catch (std::invalid_argument&) { - // This will not trigger because parse error is handled in - // MessageRegistry::Parse in lsp.cc - } - } + auto& params = request->params; + if (!params.rootUri) + return; + { + rapidjson::StringBuffer output; + rapidjson::Writer writer(output); + JsonWriter json_writer(&writer); + Reflect(json_writer, params.initializationOptions); + LOG_S(INFO) << "initializationOptions: " << output.GetString(); + } - if (config->cacheDirectory.empty()) { - LOG_S(ERROR) << "cacheDirectory cannot be empty."; - exit(1); - } else { - config->cacheDirectory = NormalizePath(config->cacheDirectory); - EnsureEndsInSlash(config->cacheDirectory); + std::string project_path = NormalizePath(params.rootUri->GetPath()); + LOG_S(INFO) << "initialize in directory " << project_path << " with uri " + << params.rootUri->raw_uri; + + { + if (params.initializationOptions) + g_config = std::make_unique(*params.initializationOptions); + else + g_config = std::make_unique(); + rapidjson::Document reader; + reader.Parse(g_init_options.c_str()); + if (!reader.HasParseError()) { + JsonReader json_reader{&reader}; + try { + Reflect(json_reader, *g_config); + } catch (std::invalid_argument&) { + // This will not trigger because parse error is handled in + // MessageRegistry::Parse in lsp.cc } } - // Client capabilities - { - const auto& cap = request->params.capabilities.textDocument; - if (cap.completion.completionItem) - config->client.snippetSupport = - cap.completion.completionItem->snippetSupport.value_or(false); + if (g_config->cacheDirectory.empty()) { + LOG_S(ERROR) << "cacheDirectory cannot be empty."; + exit(1); + } else { + g_config->cacheDirectory = NormalizePath(g_config->cacheDirectory); + EnsureEndsInSlash(g_config->cacheDirectory); } + } - // Ensure there is a resource directory. - if (config->clang.resourceDir.empty()) - config->clang.resourceDir = GetDefaultResourceDirectory(); - LOG_S(INFO) << "Using -resource-dir=" << config->clang.resourceDir; - - // Send initialization before starting indexers, so we don't send a - // status update too early. - // TODO: query request->params.capabilities.textDocument and support - // only things the client supports. - - Out_InitializeResponse out; - out.id = request->id; - - QueueManager::WriteStdout(kMethodType, out); - - // Set project root. - EnsureEndsInSlash(project_path); - config->projectRoot = project_path; - // Create two cache directories for files inside and outside of the - // project. - sys::fs::create_directories(config->cacheDirectory + - EscapeFileName(config->projectRoot)); - sys::fs::create_directories(config->cacheDirectory + '@' + - EscapeFileName(config->projectRoot)); - - g_config = std::move(config); - Timer time; - diag_engine->Init(); - semantic_cache->Init(); - - // Open up / load the project. - project->Load(project_path); - time.ResetAndPrint("[perf] Loaded compilation entries (" + - std::to_string(project->entries.size()) + " files)"); - - // Start indexer threads. Start this after loading the project, as that - // may take a long time. Indexer threads will emit status/progress - // reports. - if (g_config->index.threads == 0) - g_config->index.threads = std::thread::hardware_concurrency(); - - LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; - for (int i = 0; i < g_config->index.threads; i++) { - std::thread([=]() { - g_thread_id = i + 1; - std::string name = "indexer" + std::to_string(i); - SetThreadName(name.c_str()); - Indexer_Main(diag_engine, vfs, project, working_files, waiter); - }).detach(); - } + // Client capabilities + const auto& capabilities = params.capabilities; + g_config->client.snippetSupport = + capabilities.textDocument.completion.completionItem.snippetSupport; + + // Ensure there is a resource directory. + if (g_config->clang.resourceDir.empty()) + g_config->clang.resourceDir = GetDefaultResourceDirectory(); + LOG_S(INFO) << "Using -resource-dir=" << g_config->clang.resourceDir; + + // Send initialization before starting indexers, so we don't send a + // status update too early. + // TODO: query request->params.capabilities.textDocument and support + // only things the client supports. + + Out_InitializeResponse out; + out.id = request->id; + + QueueManager::WriteStdout(kMethodType, out); + + // Set project root. + EnsureEndsInSlash(project_path); + g_config->projectRoot = project_path; + // Create two cache directories for files inside and outside of the + // project. + sys::fs::create_directories(g_config->cacheDirectory + + EscapeFileName(g_config->projectRoot)); + sys::fs::create_directories(g_config->cacheDirectory + '@' + + EscapeFileName(g_config->projectRoot)); + + Timer time; + diag_engine->Init(); + semantic_cache->Init(); + + // Open up / load the project. + project->Load(project_path); + time.ResetAndPrint("[perf] Loaded compilation entries (" + + std::to_string(project->entries.size()) + " files)"); + + // Start indexer threads. Start this after loading the project, as that + // may take a long time. Indexer threads will emit status/progress + // reports. + if (g_config->index.threads == 0) + g_config->index.threads = std::thread::hardware_concurrency(); + + LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; + for (int i = 0; i < g_config->index.threads; i++) { + std::thread([=]() { + g_thread_id = i + 1; + std::string name = "indexer" + std::to_string(i); + SetThreadName(name.c_str()); + Indexer_Main(diag_engine, vfs, project, working_files, waiter); + }).detach(); + } - // Start scanning include directories before dispatching project - // files, because that takes a long time. - include_complete->Rescan(); + // Start scanning include directories before dispatching project + // files, because that takes a long time. + include_complete->Rescan(); - time.Reset(); - project->Index(QueueManager::instance(), working_files, request->id); - // We need to support multiple concurrent index processes. - time.ResetAndPrint("[perf] Dispatched initial index requests"); - } + time.Reset(); + project->Index(QueueManager::instance(), working_files, request->id); + // We need to support multiple concurrent index processes. + time.ResetAndPrint("[perf] Dispatched initial index requests"); } }; REGISTER_MESSAGE_HANDLER(Handler_Initialize); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 10a646ca3..b09b18296 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -26,16 +26,10 @@ struct Handler_TextDocumentDidChange std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); if (g_config->index.onDidChange) { - std::optional content = ReadContent(path); - if (!content) { - LOG_S(ERROR) << "Unable to read file content after saving " << path; - } else { - Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content), - true); - } + Project::Entry entry = project->FindCompilationEntryForFile(path); + QueueManager::instance()->index_request.PushBack( + Index_Request(entry.filename, entry.args, true /*is_interactive*/), + true); } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index c3ae0b07d..a91afb1cb 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -65,7 +65,7 @@ struct Handler_TextDocumentDidOpen QueueManager::instance()->index_request.PushBack( Index_Request(entry.filename, params.args.size() ? params.args : entry.args, - true /*is_interactive*/, params.textDocument.text), + true /*is_interactive*/), true /* priority */); clang_complete->FlushSession(entry.filename); diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index c6891c2c7..3e5a90116 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -48,16 +48,10 @@ struct Handler_TextDocumentDidSave // if so, ignore that index response. // TODO: send as priority request if (!g_config->index.onDidChange) { - std::optional content = ReadContent(path); - if (!content) { - LOG_S(ERROR) << "Unable to read file content after saving " << path; - } else { - Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/, - *content), - true); - } + Project::Entry entry = project->FindCompilationEntryForFile(path); + QueueManager::instance()->index_request.PushBack( + Index_Request(entry.filename, entry.args, true /*is_interactive*/), + true); } clang_complete->NotifySave(path); diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 6dbac73c9..e15e9e21b 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -54,20 +54,15 @@ struct Handler_WorkspaceDidChangeWatchedFiles switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - std::optional content = ReadContent(path); - if (!content) - 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)); - if (is_interactive) - clang_complete->NotifySave(path); - } + QueueManager::instance()->index_request.PushBack( + Index_Request(path, entry.args, is_interactive)); + if (is_interactive) + clang_complete->NotifySave(path); break; } case lsFileChangeType::Deleted: QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive, std::string())); + Index_Request(path, entry.args, is_interactive)); break; } } diff --git a/src/project.cc b/src/project.cc index 4800033b0..3ca211d45 100644 --- a/src/project.cc +++ b/src/project.cc @@ -458,19 +458,13 @@ void Project::Index(QueueManager* queue, WorkingFiles* wfiles, lsRequestId id) { ForAllFilteredFiles([&](int i, const Project::Entry& entry) { - std::optional content = ReadContent(entry.filename); - if (!content) { - LOG_S(ERROR) << "When loading project, canont read file " - << entry.filename; - return; - } bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - queue->index_request.PushBack(Index_Request(entry.filename, entry.args, - is_interactive, *content, id)); + queue->index_request.PushBack( + Index_Request(entry.filename, entry.args, is_interactive, id)); }); // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - queue->index_request.PushBack(Index_Request("", {}, false, "")); + queue->index_request.PushBack(Index_Request("", {}, false)); } TEST_SUITE("Project") { diff --git a/src/queue_manager.cc b/src/queue_manager.cc index 87cb794a0..623c72dfb 100644 --- a/src/queue_manager.cc +++ b/src/queue_manager.cc @@ -6,17 +6,11 @@ #include -Index_Request::Index_Request( - const std::string& path, - const std::vector& args, - bool is_interactive, - const std::string& contents, - lsRequestId id) - : path(path), - args(args), - is_interactive(is_interactive), - contents(contents), - id(id) {} +Index_Request::Index_Request(const std::string& path, + const std::vector& args, + bool is_interactive, + lsRequestId id) + : path(path), args(args), is_interactive(is_interactive), id(id) {} Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update, PerformanceImportFile perf) diff --git a/src/queue_manager.h b/src/queue_manager.h index 03f3909c7..13ee57b47 100644 --- a/src/queue_manager.h +++ b/src/queue_manager.h @@ -19,13 +19,11 @@ struct Index_Request { // TODO: make |args| a string that is parsed lazily. std::vector args; bool is_interactive; - std::string contents; // Preloaded contents. lsRequestId id; Index_Request(const std::string& path, const std::vector& args, bool is_interactive, - const std::string& contents, lsRequestId id = {}); }; From 8fabe3d1aecce10b8872a8f038d29a0679b7afcd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 27 May 2018 12:24:56 -0700 Subject: [PATCH 105/378] Replace loguru with a custom logger --- .gitmodules | 3 - CMakeLists.txt | 3 +- src/cache_manager.cc | 2 - src/clang_complete.cc | 20 +++--- src/clang_indexer.cc | 3 +- src/clang_translation_unit.cc | 3 +- src/file_consumer.cc | 7 +-- src/include_complete.cc | 6 +- src/log.cc | 62 +++++++++++++++++++ src/log.hh | 40 ++++++++++++ src/lsp.cc | 42 +------------ src/lsp.h | 8 --- src/main.cc | 34 ++++++---- src/message_handler.cc | 12 +--- src/messages/ccls_call_hierarchy.cc | 2 - src/messages/ccls_freshen_index.cc | 3 +- src/messages/exit.cc | 3 - src/messages/initialize.cc | 13 ++-- src/messages/text_document_completion.cc | 2 - src/messages/text_document_did_change.cc | 2 - src/messages/text_document_did_open.cc | 3 - src/messages/text_document_did_save.cc | 2 - .../workspace_did_change_configuration.cc | 3 - .../workspace_did_change_watched_files.cc | 2 - src/messages/workspace_symbol.cc | 7 --- src/{import_pipeline.cc => pipeline.cc} | 12 ++-- src/{import_pipeline.h => pipeline.hh} | 0 src/platform.h | 2 - src/platform_posix.cc | 10 --- src/project.cc | 2 +- src/query.cc | 1 - src/query_utils.cc | 4 +- src/serializer.cc | 5 +- src/test.cc | 1 - src/third_party_impl.cc | 3 - src/timer.cc | 2 +- src/type_printer.cc | 8 +-- src/utils.cc | 3 +- src/working_files.cc | 20 +----- third_party/loguru | 1 - 40 files changed, 174 insertions(+), 187 deletions(-) create mode 100644 src/log.cc create mode 100644 src/log.hh rename src/{import_pipeline.cc => pipeline.cc} (98%) rename src/{import_pipeline.h => pipeline.hh} (100%) delete mode 160000 third_party/loguru diff --git a/.gitmodules b/.gitmodules index f0c273413..fbe945c5f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "third_party/doctest"] path = third_party/doctest url = https://github.com/onqtam/doctest -[submodule "third_party/loguru"] - path = third_party/loguru - url = https://github.com/emilk/loguru diff --git a/CMakeLists.txt b/CMakeLists.txt index 05aa3e0b1..f3bdd59f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,14 +201,15 @@ target_sources(ccls PRIVATE src/filesystem.cc src/fuzzy_match.cc src/main.cc - src/import_pipeline.cc src/include_complete.cc src/method.cc src/language.cc src/lex_utils.cc + src/log.cc src/lsp.cc src/match.cc src/message_handler.cc + src/pipeline.cc src/platform_posix.cc src/platform_win.cc src/port.cc diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 79a159a43..c3e64788e 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -5,8 +5,6 @@ #include "lsp.h" #include "platform.h" -#include - #include #include diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 6d344da0f..e06c76475 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -1,14 +1,15 @@ #include "clang_complete.h" #include "clang_utils.h" +#include "filesystem.hh" +#include "log.hh" #include "platform.h" #include "timer.h" -#include "filesystem.hh" +#include +#include using namespace llvm; -#include - #include #include @@ -660,15 +661,15 @@ ClangCompleteManager::ClangCompleteManager(Project* project, preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { std::thread([&]() { - SetThreadName("comp-query"); + set_thread_name("comp-query"); CompletionQueryMain(this); }).detach(); std::thread([&]() { - SetThreadName("comp-preload"); + set_thread_name("comp-preload"); CompletionPreloadMain(this); }).detach(); std::thread([&]() { - SetThreadName("diag-query"); + set_thread_name("diag-query"); DiagnosticQueryMain(this); }).detach(); } @@ -803,10 +804,11 @@ void ClangCompleteManager::FlushSession(const std::string& filename) { } void ClangCompleteManager::FlushAllSessions() { - std::lock_guard lock(sessions_lock_); + LOG_S(INFO) << "flush all clang complete sessions"; + std::lock_guard lock(sessions_lock_); - preloaded_sessions_.Clear(); - completion_sessions_.Clear(); + preloaded_sessions_.Clear(); + completion_sessions_.Clear(); } void CodeCompleteCache::WithLock(std::function action) { diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 405d91b4b..a9d669864 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -2,13 +2,12 @@ #include "clang_cursor.h" #include "clang_utils.h" +#include "log.hh" #include "platform.h" #include "serializer.h" #include "timer.h" #include "type_printer.h" -#include - #include #include #include diff --git a/src/clang_translation_unit.cc b/src/clang_translation_unit.cc index ffca1b0be..f9f9aaf4f 100644 --- a/src/clang_translation_unit.cc +++ b/src/clang_translation_unit.cc @@ -1,11 +1,10 @@ #include "clang_translation_unit.h" #include "clang_utils.h" +#include "log.hh" #include "platform.h" #include "utils.h" -#include - namespace { void EmitDiagnostics(std::string path, diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 5db6afca3..218ec3bfb 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -2,11 +2,10 @@ #include "clang_utils.h" #include "indexer.h" +#include "log.hh" #include "platform.h" #include "utils.h" -#include - namespace { std::optional GetFileContents( @@ -108,8 +107,8 @@ IndexFile* FileConsumer::TryConsumeFile( if (clang_getFileUniqueID(file, &file_id) != 0) { std::string file_name = FileName(file); if (!file_name.empty()) { - // LOG_S(ERROR) << "Could not get unique file id for " << file_name - // << " when parsing " << parse_file_; + LOG_S(ERROR) << "Could not get unique file id for " << file_name + << " when parsing " << parse_file_; } return nullptr; } diff --git a/src/include_complete.cc b/src/include_complete.cc index ea33fa33d..1d1b74a16 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -6,6 +6,10 @@ #include "project.h" #include "timer.h" +#include +#include +using namespace llvm; + #include namespace { @@ -103,7 +107,7 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { - SetThreadName("scan_includes"); + set_thread_name("scan_includes"); Timer timer; for (const std::string& dir : project_->quote_include_directories) diff --git a/src/log.cc b/src/log.cc new file mode 100644 index 000000000..573f9184e --- /dev/null +++ b/src/log.cc @@ -0,0 +1,62 @@ +#include "log.hh" + +#include +#include + +#include +#include +#include +#include +#include + +namespace ccls::log { +static std::mutex mtx; +FILE* file; +Verbosity verbosity; + +Message::Message(Verbosity verbosity, const char* file, int line) + : verbosity_(verbosity) { + using namespace llvm; + time_t tim = time(NULL); + struct tm t; + { + std::lock_guard lock(mtx); + t = *localtime(&tim); + } + char buf[16]; + snprintf(buf, sizeof buf, "%02d:%02d:%02d ", t.tm_hour, t.tm_min, t.tm_sec); + stream_ << buf; + { + SmallString<32> Name; + get_thread_name(Name); + stream_ << std::left << std::setw(13) << Name.c_str(); + } + { + const char* p = strrchr(file, '/'); + if (p) + file = p + 1; + stream_ << std::right << std::setw(15) << file << ':' << std::left + << std::setw(3) << line; + } + stream_ << ' '; + // clang-format off + switch (verbosity_) { + case Verbosity_FATAL: stream_ << 'F'; break; + case Verbosity_ERROR: stream_ << 'E'; break; + case Verbosity_WARNING: stream_ << 'W'; break; + case Verbosity_INFO: stream_ << 'I'; break; + default: stream_ << "V(" << int(verbosity_) << ')'; + } + // clang-format on + stream_ << ' '; +} + +Message::~Message() { + if (!file) return; + std::lock_guard lock(mtx); + stream_ << '\n'; + fputs(stream_.str().c_str(), file); + if (verbosity_ == Verbosity_FATAL) + abort(); +} +} diff --git a/src/log.hh b/src/log.hh new file mode 100644 index 000000000..caab81511 --- /dev/null +++ b/src/log.hh @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +namespace ccls::log { +extern FILE* file; + +struct Voidify { + void operator&(const std::ostream&) {} +}; + +enum Verbosity { + Verbosity_FATAL = -3, + Verbosity_ERROR = -2, + Verbosity_WARNING = -1, + Verbosity_INFO = 0, +}; +extern Verbosity verbosity; + +struct Message { + std::stringstream stream_; + int verbosity_; + + Message(Verbosity verbosity, const char* file, int line); + ~Message(); +}; +} + +#define LOG_IF(v, cond) \ + !(cond) ? void(0) \ + : ccls::log::Voidify() & \ + ccls::log::Message(v, __FILE__, __LINE__).stream_ +#define LOG_S(v) \ + LOG_IF(ccls::log::Verbosity_##v, \ + ccls::log::Verbosity_##v <= ccls::log::verbosity) +#define LOG_IF_S(v, cond) \ + LOG_IF(ccls::log::Verbosity_##v, \ + (cond) && ccls::log::Verbosity_##v <= ccls::log::verbosity) +#define CHECK_S(cond) LOG_IF(FATAL, !(cond)) << "check failed: " #cond " " diff --git a/src/lsp.cc b/src/lsp.cc index 9b11ac76b..2968c399b 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -1,10 +1,9 @@ #include "lsp.h" +#include "log.hh" #include "serializers/json.h" -#include #include -#include #include @@ -68,45 +67,6 @@ std::optional ReadJsonRpcContentFrom( return content; } -std::function()> MakeContentReader(std::string* content, - bool can_be_empty) { - return [content, can_be_empty]() -> std::optional { - if (!can_be_empty) - REQUIRE(!content->empty()); - if (content->empty()) - return std::nullopt; - char c = (*content)[0]; - content->erase(content->begin()); - return c; - }; -} - -TEST_SUITE("FindIncludeLine") { - TEST_CASE("ReadContentFromSource") { - auto parse_correct = [](std::string content) -> std::string { - auto reader = MakeContentReader(&content, false /*can_be_empty*/); - auto got = ReadJsonRpcContentFrom(reader); - REQUIRE(got); - return got.value(); - }; - - auto parse_incorrect = [](std::string content) -> std::optional { - auto reader = MakeContentReader(&content, true /*can_be_empty*/); - return ReadJsonRpcContentFrom(reader); - }; - - REQUIRE(parse_correct("Content-Length: 0\r\n\r\n") == ""); - REQUIRE(parse_correct("Content-Length: 1\r\n\r\na") == "a"); - REQUIRE(parse_correct("Content-Length: 4\r\n\r\nabcd") == "abcd"); - - REQUIRE(parse_incorrect("ggg") == std::optional()); - REQUIRE(parse_incorrect("Content-Length: 0\r\n") == - std::optional()); - REQUIRE(parse_incorrect("Content-Length: 5\r\n\r\nab") == - std::optional()); - } -} - std::optional ReadCharFromStdinBlocking() { // We do not use std::cin because it does not read bytes once stuck in // cin.bad(). We can call cin.clear() but C++ iostream has other annoyance diff --git a/src/lsp.h b/src/lsp.h index a72410b68..84fbf2e1d 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -304,14 +304,6 @@ struct lsWorkspaceEdit { }; MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges); -struct lsFormattingOptions { - // Size of a tab in spaces. - int tabSize; - // Prefer spaces over tabs. - bool insertSpaces; -}; -MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); - // MarkedString can be used to render human readable text. It is either a // markdown string or a code-block that provides a language and a code snippet. // The language identifier is sematically equal to the std::optional language diff --git a/src/main.cc b/src/main.cc index 503b1e12a..fcfc66e92 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,5 @@ -#include "import_pipeline.h" +#include "log.hh" +#include "pipeline.hh" #include "platform.h" #include "serializer.h" #include "serializers/json.h" @@ -7,12 +8,12 @@ #include #include +#include using namespace llvm; using namespace llvm::cl; #include #include -#include #include #include @@ -34,10 +35,15 @@ opt opt_log_file_append("log-file-append", desc("log"), value_desc( list opt_extra(Positional, ZeroOrMore, desc("extra")); +void CloseLog() { + fclose(ccls::log::file); +} + } // namespace int main(int argc, char** argv) { TraceMe(); + sys::PrintStackTraceOnErrorSignal(argv[0]); ParseCommandLineOptions(argc, argv, "C/C++/Objective-C language server\n\n" @@ -50,13 +56,6 @@ int main(int argc, char** argv) { return 0; } - loguru::g_stderr_verbosity = opt_verbose - 1; - loguru::g_preamble_date = false; - loguru::g_preamble_time = false; - loguru::g_preamble_verbose = false; - loguru::g_flush_interval_ms = 0; - loguru::init(argc, argv); - MultiQueueWaiter querydb_waiter, indexer_waiter, stdout_waiter; QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); @@ -72,10 +71,19 @@ int main(int argc, char** argv) { bool language_server = true; - if (opt_log_file.size()) - loguru::add_file(opt_log_file.c_str(), loguru::Truncate, opt_verbose); - if (opt_log_file_append.size()) - loguru::add_file(opt_log_file_append.c_str(), loguru::Append, opt_verbose); + if (opt_log_file.size() || opt_log_file_append.size()) { + ccls::log::file = opt_log_file.size() + ? fopen(opt_log_file.c_str(), "wb") + : fopen(opt_log_file_append.c_str(), "ab"); + if (!ccls::log::file) { + fprintf( + stderr, "failed to open %s\n", + (opt_log_file.size() ? opt_log_file : opt_log_file_append).c_str()); + return 2; + } + setbuf(ccls::log::file, NULL); + atexit(CloseLog); + } if (opt_test_unit) { language_server = false; diff --git a/src/message_handler.cc b/src/message_handler.cc index cf17c0139..a0014c216 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -1,12 +1,11 @@ #include "message_handler.h" #include "lex_utils.h" +#include "log.hh" #include "project.h" #include "query_utils.h" #include "queue_manager.h" -#include - #include MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); @@ -156,14 +155,7 @@ bool FindFileOrFail(QueryDatabase* db, if (indexing) LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; else - LOG_S(INFO) << "Unable to find file \"" << absolute_path << "\""; - /* - LOG_S(INFO) << "Files (size=" << db->usr_to_file.size() << "): " - << StringJoinMap(db->usr_to_file, - [](const std::pair& entry) { - return entry.first.path; - }); - */ + LOG_S(INFO) << "unable to find file \"" << absolute_path << "\""; if (id) { Out_Error out; diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index c15e11226..08c94515e 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -2,8 +2,6 @@ #include "query_utils.h" #include "queue_manager.h" -#include - #include namespace { diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index f9e047fa9..bf36450f7 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -1,14 +1,13 @@ #include "cache_manager.h" -#include "import_pipeline.h" #include "match.h" #include "message_handler.h" +#include "pipeline.hh" #include "platform.h" #include "project.h" #include "queue_manager.h" #include "timer.h" #include "working_files.h" -#include #include #include diff --git a/src/messages/exit.cc b/src/messages/exit.cc index 2722dca51..edf0c4ffc 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -1,7 +1,5 @@ #include "message_handler.h" -#include - namespace { struct In_Exit : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType_Exit; } @@ -13,7 +11,6 @@ struct Handler_Exit : MessageHandler { MethodType GetMethodType() const override { return kMethodType_Exit; } void Run(std::unique_ptr request) override { - LOG_S(INFO) << "Exiting; got exit message"; exit(0); } }; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index fc4bc4d92..d15ba2e2a 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,8 +1,10 @@ #include "cache_manager.h" #include "diagnostics_engine.h" -#include "import_pipeline.h" +#include "filesystem.hh" #include "include_complete.h" +#include "log.hh" #include "message_handler.h" +#include "pipeline.hh" #include "platform.h" #include "project.h" #include "queue_manager.h" @@ -10,11 +12,10 @@ #include "timer.h" #include "working_files.h" -#include "filesystem.hh" +#include +#include using namespace llvm; -#include - #include #include #include @@ -508,12 +509,12 @@ struct Handler_Initialize : BaseMessageHandler { if (g_config->index.threads == 0) g_config->index.threads = std::thread::hardware_concurrency(); - LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; + LOG_S(INFO) << "start " << g_config->index.threads << " indexers"; for (int i = 0; i < g_config->index.threads; i++) { std::thread([=]() { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); - SetThreadName(name.c_str()); + set_thread_name(name.c_str()); Indexer_Main(diag_engine, vfs, project, working_files, waiter); }).detach(); } diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index a08205499..1f536a40b 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -8,8 +8,6 @@ #include "lex_utils.h" -#include - #include namespace { diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index b09b18296..8072cb952 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -5,8 +5,6 @@ #include "working_files.h" #include "queue_manager.h" -#include - namespace { MethodType kMethodType = "textDocument/didChange"; diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index a91afb1cb..12c79bdb4 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -7,8 +7,6 @@ #include "timer.h" #include "working_files.h" -#include - namespace { MethodType kMethodType = "textDocument/didOpen"; @@ -69,7 +67,6 @@ struct Handler_TextDocumentDidOpen true /* priority */); clang_complete->FlushSession(entry.filename); - LOG_S(INFO) << "Flushed clang complete sessions for " << entry.filename; } } }; diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 3e5a90116..50835f013 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -4,8 +4,6 @@ #include "project.h" #include "queue_manager.h" -#include - namespace { MethodType kMethodType = "textDocument/didSave"; diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index afe578ca1..ab33009b2 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -6,8 +6,6 @@ #include "timer.h" #include "working_files.h" -#include - namespace { MethodType kMethodType = "workspace/didChangeConfiguration"; @@ -38,7 +36,6 @@ struct Handler_WorkspaceDidChangeConfiguration "[perf] Dispatched workspace/didChangeConfiguration index requests"); clang_complete->FlushAllSessions(); - LOG_S(INFO) << "Flushed all clang complete sessions"; } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeConfiguration); diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index e15e9e21b..3140a9293 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -5,8 +5,6 @@ #include "queue_manager.h" #include "working_files.h" -#include - namespace { MethodType kMethodType = "workspace/didChangeWatchedFiles"; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 910cfdabc..77df7fea6 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -4,8 +4,6 @@ #include "query_utils.h" #include "queue_manager.h" -#include - #include #include #include @@ -70,9 +68,6 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { Out_WorkspaceSymbol out; out.id = request->id; - LOG_S(INFO) << "[querydb] Considering " << db->symbols.size() - << " candidates for query " << request->params.query; - std::string query = request->params.query; // {symbol info, matching detailed_name or short_name, index} @@ -129,8 +124,6 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { out.result.push_back(std::get<0>(entry)); } - LOG_S(INFO) << "[querydb] Found " << out.result.size() - << " results for query " << query; QueueManager::WriteStdout(kMethodType, out); } }; diff --git a/src/import_pipeline.cc b/src/pipeline.cc similarity index 98% rename from src/import_pipeline.cc rename to src/pipeline.cc index 5ed8ebd86..b552448f9 100644 --- a/src/import_pipeline.cc +++ b/src/pipeline.cc @@ -1,10 +1,11 @@ -#include "import_pipeline.h" +#include "pipeline.hh" #include "cache_manager.h" #include "clang_complete.h" #include "config.h" #include "diagnostics_engine.h" #include "include_complete.h" +#include "log.hh" #include "lsp.h" #include "message_handler.h" #include "platform.h" @@ -13,8 +14,9 @@ #include "queue_manager.h" #include "timer.h" -#include -#include +#include +#include +using namespace llvm; #include #include @@ -275,7 +277,7 @@ void QueryDb_OnIndexed(QueueManager* queue, void LaunchStdinLoop(std::unordered_map* request_times) { std::thread([request_times]() { - SetThreadName("stdin"); + set_thread_name("stdin"); auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; @@ -316,7 +318,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { std::thread([=]() { - SetThreadName("stdout"); + set_thread_name("stdout"); auto* queue = QueueManager::instance(); while (true) { diff --git a/src/import_pipeline.h b/src/pipeline.hh similarity index 100% rename from src/import_pipeline.h rename to src/pipeline.hh diff --git a/src/platform.h b/src/platform.h index 775486a04..7d73549ad 100644 --- a/src/platform.h +++ b/src/platform.h @@ -8,8 +8,6 @@ std::string NormalizePath(const std::string& path); -void SetThreadName(const char* name); - // Free any unused memory and return it to the system. void FreeUnusedMemory(); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index d1d6c9e01..10bad8d4e 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -1,13 +1,8 @@ -#include -#include - #if defined(__unix__) || defined(__APPLE__) #include "platform.h" #include "utils.h" -#include - #include #include #include @@ -160,8 +155,3 @@ std::string GetExternalCommandOutput(const std::vector& command, } #endif - -void SetThreadName(const char* name) { - loguru::set_thread_name(name); - llvm::set_thread_name(name); -} diff --git a/src/project.cc b/src/project.cc index 3ca211d45..44682d98c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -4,6 +4,7 @@ #include "clang_utils.h" #include "filesystem.hh" #include "language.h" +#include "log.hh" #include "match.h" #include "platform.h" #include "queue_manager.h" @@ -25,7 +26,6 @@ using namespace llvm::opt; #include #include #include -#include #if defined(__unix__) || defined(__APPLE__) #include diff --git a/src/query.cc b/src/query.cc index 59edfe03a..256d5fa3c 100644 --- a/src/query.cc +++ b/src/query.cc @@ -5,7 +5,6 @@ #include "serializers/json.h" #include -#include #include #include diff --git a/src/query_utils.cc b/src/query_utils.cc index c0bdac2ef..9f801ced8 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -2,9 +2,7 @@ #include "queue_manager.h" -#include - -#include +#include #include namespace { diff --git a/src/serializer.cc b/src/serializer.cc index 734c147ac..72090c6ec 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,13 +1,12 @@ #include "serializer.h" #include "filesystem.hh" +#include "log.hh" #include "serializers/binary.h" #include "serializers/json.h" #include "indexer.h" -#include - #include using namespace llvm; @@ -414,7 +413,7 @@ std::unique_ptr Deserialize( file = std::make_unique(path, file_content); Reflect(reader, *file); } catch (std::invalid_argument& e) { - LOG_S(INFO) << "Failed to deserialize '" << path + LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what(); return nullptr; } diff --git a/src/test.cc b/src/test.cc index 6cd4b2f76..00dec8261 100644 --- a/src/test.cc +++ b/src/test.cc @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/src/third_party_impl.cc b/src/third_party_impl.cc index 231ab76c9..572a07d31 100644 --- a/src/third_party_impl.cc +++ b/src/third_party_impl.cc @@ -1,5 +1,2 @@ #define DOCTEST_CONFIG_IMPLEMENT #include - -#define LOGURU_IMPLEMENTATION 1 -#include diff --git a/src/timer.cc b/src/timer.cc index 96ec658cd..022ca22e3 100644 --- a/src/timer.cc +++ b/src/timer.cc @@ -1,6 +1,6 @@ #include "timer.h" -#include +#include "log.hh" Timer::Timer() { Reset(); diff --git a/src/type_printer.cc b/src/type_printer.cc index 06346d470..eac5ad41b 100644 --- a/src/type_printer.cc +++ b/src/type_printer.cc @@ -1,7 +1,5 @@ #include "type_printer.h" -#include - namespace { int GetNameInsertingPosition(const std::string& type_desc, @@ -82,12 +80,8 @@ std::tuple GetFunctionSignature( std::string type_desc_with_names(type_desc.begin(), type_desc.begin() + i); type_desc_with_names.append(func_name); for (auto& arg : args) { - if (arg.first < 0) { - LOG_S(ERROR) - << "When adding argument names to '" << type_desc - << "', failed to detect positions to insert argument names"; + if (arg.first < 0) break; - } if (arg.second.empty()) continue; // TODO Use inside-out syntax. Note, clang/lib/AST/TypePrinter.cpp does diff --git a/src/utils.cc b/src/utils.cc index 57a5319f3..cc4484765 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -2,11 +2,10 @@ #include "filesystem.hh" using namespace llvm; +#include "log.hh" #include "platform.h" -#include #include -#include #include #include diff --git a/src/working_files.cc b/src/working_files.cc index 5e2934641..cfefda8a8 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -1,10 +1,10 @@ #include "working_files.h" #include "lex_utils.h" +#include "log.hh" #include "position.h" #include -#include #include #include @@ -320,23 +320,9 @@ void WorkingFile::ComputeLineMapping() { std::optional WorkingFile::GetBufferPosFromIndexPos(int line, int* column, bool is_end) { - // The implementation is simple but works pretty well for most cases. We - // lookup the line contents in the indexed file contents, and try to find the - // most similar line in the current buffer file. - // - // Previously, this was implemented by tracking edits and by running myers - // diff algorithm. They were complex implementations that did not work as - // well. - - // Note: |index_line| and |buffer_line| are 1-based. - - // TODO: reenable this assert once we are using the real indexed file. - // assert(index_line >= 1 && index_line <= index_lines.size()); if (line < 0 || line >= (int)index_lines.size()) { - loguru::Text stack = loguru::stacktrace(); - LOG_S(WARNING) << "Bad index_line (got " << line << ", expected [0, " - << index_lines.size() << ")) in " << filename - << stack.c_str(); + LOG_S(WARNING) << "bad index_line (got " << line << ", expected [0, " + << index_lines.size() << ")) in " << filename; return std::nullopt; } diff --git a/third_party/loguru b/third_party/loguru deleted file mode 160000 index 6bf94c5f2..000000000 --- a/third_party/loguru +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6bf94c5f2bec437e871402d0a27e8a3094b261d5 From c9f0b65062746b41daa24bcaecfaed78e72bab03 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 27 May 2018 17:50:02 -0700 Subject: [PATCH 106/378] Simplify pipeline --- CMakeLists.txt | 8 +- src/cache_manager.cc | 62 ------ src/cache_manager.h | 26 --- src/clang_complete.cc | 31 +-- src/clang_complete.h | 3 +- src/clang_translation_unit.cc | 155 -------------- src/clang_translation_unit.h | 30 --- src/{clang_cursor.cc => clang_tu.cc} | 154 +++++++++++++- src/{clang_cursor.h => clang_tu.h} | 25 ++- src/diagnostics_engine.cc | 5 +- src/include_complete.cc | 2 +- src/{clang_indexer.cc => indexer.cc} | 2 - src/indexer.h | 3 +- src/main.cc | 10 +- src/match.cc | 5 +- src/message_handler.cc | 9 +- src/messages/ccls_base.cc | 5 +- src/messages/ccls_call_hierarchy.cc | 6 +- src/messages/ccls_callers.cc | 5 +- src/messages/ccls_file_info.cc | 5 +- src/messages/ccls_freshen_index.cc | 7 +- src/messages/ccls_inheritance_hierarchy.cc | 13 +- src/messages/ccls_member_hierarchy.cc | 5 +- src/messages/ccls_random.cc | 5 +- src/messages/ccls_vars.cc | 5 +- src/messages/initialize.cc | 9 +- src/messages/shutdown.cc | 5 +- src/messages/text_document_code_lens.cc | 5 +- src/messages/text_document_completion.cc | 9 +- src/messages/text_document_definition.cc | 5 +- src/messages/text_document_did_change.cc | 8 +- src/messages/text_document_did_close.cc | 5 +- src/messages/text_document_did_open.cc | 17 +- src/messages/text_document_did_save.cc | 11 +- .../text_document_document_highlight.cc | 5 +- src/messages/text_document_document_symbol.cc | 5 +- src/messages/text_document_hover.cc | 5 +- src/messages/text_document_implementation.cc | 5 +- .../text_document_range_formatting.cc | 5 +- src/messages/text_document_references.cc | 5 +- src/messages/text_document_rename.cc | 5 +- src/messages/text_document_signature_help.cc | 5 +- src/messages/text_document_type_definition.cc | 5 +- .../workspace_did_change_configuration.cc | 6 +- .../workspace_did_change_watched_files.cc | 10 +- src/messages/workspace_execute_command.cc | 5 +- src/messages/workspace_symbol.cc | 5 +- src/pipeline.cc | 189 +++++++++++++----- src/pipeline.hh | 33 +-- src/port.cc | 10 - src/port.h | 34 ---- src/project.cc | 12 +- src/project.h | 6 +- src/query_utils.cc | 2 +- src/queue_manager.cc | 46 ----- src/queue_manager.h | 84 -------- src/serializer.h | 21 +- src/test.cc | 2 - src/threaded_queue.h | 20 -- src/utils.cc | 9 - src/utils.h | 2 - 61 files changed, 479 insertions(+), 722 deletions(-) delete mode 100644 src/cache_manager.cc delete mode 100644 src/cache_manager.h delete mode 100644 src/clang_translation_unit.cc delete mode 100644 src/clang_translation_unit.h rename src/{clang_cursor.cc => clang_tu.cc} (64%) rename src/{clang_cursor.h => clang_tu.h} (82%) rename src/{clang_indexer.cc => indexer.cc} (99%) delete mode 100644 src/port.cc delete mode 100644 src/port.h delete mode 100644 src/queue_manager.cc delete mode 100644 src/queue_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f3bdd59f1..52f0f269a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,11 +189,8 @@ file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h target_sources(ccls PRIVATE third_party/siphash.cc) target_sources(ccls PRIVATE - src/cache_manager.cc src/clang_complete.cc - src/clang_cursor.cc - src/clang_indexer.cc - src/clang_translation_unit.cc + src/clang_tu.cc src/clang_utils.cc src/config.cc src/diagnostics_engine.cc @@ -202,6 +199,7 @@ target_sources(ccls PRIVATE src/fuzzy_match.cc src/main.cc src/include_complete.cc + src/indexer.cc src/method.cc src/language.cc src/lex_utils.cc @@ -212,12 +210,10 @@ target_sources(ccls PRIVATE src/pipeline.cc src/platform_posix.cc src/platform_win.cc - src/port.cc src/position.cc src/project.cc src/query_utils.cc src/query.cc - src/queue_manager.cc src/serializer.cc src/test.cc src/third_party_impl.cc diff --git a/src/cache_manager.cc b/src/cache_manager.cc deleted file mode 100644 index c3e64788e..000000000 --- a/src/cache_manager.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "cache_manager.h" - -#include "config.h" -#include "indexer.h" -#include "lsp.h" -#include "platform.h" - -#include -#include - -namespace { -std::string GetCachePath(const std::string& source_file) { - assert(!g_config->cacheDirectory.empty()); - std::string cache_file; - size_t len = g_config->projectRoot.size(); - if (StartsWith(source_file, g_config->projectRoot)) { - cache_file = EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file.substr(len)); - } else { - cache_file = '@' + EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file); - } - - return g_config->cacheDirectory + cache_file; -} - -std::string AppendSerializationFormat(const std::string& base) { - switch (g_config->cacheFormat) { - case SerializeFormat::Binary: - return base + ".blob"; - case SerializeFormat::Json: - return base + ".json"; - } -} -} - -// Manages loading caches from file paths for the indexer process. -void ICacheManager::WriteToCache(IndexFile& file) { - std::string cache_path = GetCachePath(file.path); - WriteToFile(cache_path, file.file_contents); - - std::string indexed_content = Serialize(g_config->cacheFormat, file); - WriteToFile(AppendSerializationFormat(cache_path), indexed_content); -} - -std::optional ICacheManager::LoadCachedFileContents( - const std::string& path) { - return ReadContent(GetCachePath(path)); -} - -std::unique_ptr ICacheManager::RawCacheLoad( - const std::string& path) { - std::string cache_path = GetCachePath(path); - std::optional file_content = ReadContent(cache_path); - std::optional serialized_indexed_content = - ReadContent(AppendSerializationFormat(cache_path)); - if (!file_content || !serialized_indexed_content) - return nullptr; - - return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, - *file_content, IndexFile::kMajorVersion); -} diff --git a/src/cache_manager.h b/src/cache_manager.h deleted file mode 100644 index daffdd48c..000000000 --- a/src/cache_manager.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -struct IndexFile; - -struct ICacheManager { - void WriteToCache(IndexFile& file); - - std::optional LoadCachedFileContents(const std::string& path); - - template - void IterateLoadedCaches(Fn fn) { - for (const auto& cache : caches_) - fn(cache.second.get()); - } - - std::unique_ptr RawCacheLoad(const std::string& path); - - std::unordered_map> caches_; -}; diff --git a/src/clang_complete.cc b/src/clang_complete.cc index e06c76475..f35c9429d 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -21,14 +21,8 @@ unsigned Flags() { CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion | - CXTranslationUnit_DetailedPreprocessingRecord -#if !defined(_WIN32) - // For whatever reason, CreatePreambleOnFirstParse causes clang to - // become very crashy on windows. - // TODO: do more investigation, submit fixes to clang. - | CXTranslationUnit_CreatePreambleOnFirstParse -#endif - ; + CXTranslationUnit_DetailedPreprocessingRecord | + CXTranslationUnit_CreatePreambleOnFirstParse; } std::string StripFileType(const std::string& path) { @@ -57,23 +51,6 @@ unsigned GetCompletionPriority(const CXCompletionString& str, return priority; } -/* -bool IsCallKind(CXCursorKind kind) { - switch (kind) { - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_CXXMethod: - case CXCursor_FunctionTemplate: - case CXCursor_FunctionDecl: - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - return true; - default: - return false; - } -} -*/ - lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { case CXCursor_UnexposedDecl: @@ -383,8 +360,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, std::vector args = session->file.args; // -fspell-checking enables FixIts for, ie, misspelled types. - if (!AnyStartsWith(args, "-fno-spell-checking") && - !AnyStartsWith(args, "-fspell-checking")) { + if (!std::count(args.begin(), args.end(), "-fno-spell-checking") && + !std::count(args.begin(), args.end(), "-fspell-checking")) { args.push_back("-fspell-checking"); } diff --git a/src/clang_complete.h b/src/clang_complete.h index aa471c8ec..af824df18 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -1,7 +1,6 @@ #pragma once -#include "clang_cursor.h" -#include "clang_translation_unit.h" +#include "clang_tu.h" #include "lru_cache.h" #include "lsp_completion.h" #include "lsp_diagnostic.h" diff --git a/src/clang_translation_unit.cc b/src/clang_translation_unit.cc deleted file mode 100644 index f9f9aaf4f..000000000 --- a/src/clang_translation_unit.cc +++ /dev/null @@ -1,155 +0,0 @@ -#include "clang_translation_unit.h" - -#include "clang_utils.h" -#include "log.hh" -#include "platform.h" -#include "utils.h" - -namespace { - -void EmitDiagnostics(std::string path, - std::vector args, - CXTranslationUnit tu) { - std::string output = "Fatal errors while trying to parse " + path + "\n"; - output += - "Args: " + - StringJoinMap(args, [](const char* arg) { return std::string(arg); }) + - "\n"; - - size_t num_diagnostics = clang_getNumDiagnostics(tu); - for (unsigned i = 0; i < num_diagnostics; ++i) { - output += " - "; - - CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); - - // Location. - CXFile file; - unsigned int line, column; - clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, - &line, &column, nullptr); - std::string path = FileName(file); - output += path + ":" + std::to_string(line - 1) + ":" + - std::to_string(column) + " "; - - // Severity - switch (clang_getDiagnosticSeverity(diagnostic)) { - case CXDiagnostic_Ignored: - case CXDiagnostic_Note: - output += "[info]"; - break; - case CXDiagnostic_Warning: - output += "[warning]"; - break; - case CXDiagnostic_Error: - output += "[error]"; - break; - case CXDiagnostic_Fatal: - output += "[fatal]"; - break; - } - - // Content. - output += " " + ToString(clang_getDiagnosticSpelling(diagnostic)); - - clang_disposeDiagnostic(diagnostic); - - output += "\n"; - } - - LOG_S(WARNING) << output; -} -} // namespace - -// static -std::unique_ptr ClangTranslationUnit::Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags) { - std::vector args; - for (auto& arg : arguments) - args.push_back(arg.c_str()); - - CXTranslationUnit cx_tu; - CXErrorCode error_code; - { - error_code = clang_parseTranslationUnit2FullArgv( - index->cx_index, nullptr, args.data(), (int)args.size(), - unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); - } - - if (error_code != CXError_Success && cx_tu) - EmitDiagnostics(filepath, args, cx_tu); - - // We sometimes dump the command to logs and ask the user to run it. Include - // -fsyntax-only so they don't do a full compile. - auto make_msg = [&]() { - return "Please try running the following, identify which flag causes the " - "issue, and report a bug. ccls will then filter the flag for you " - " automatically:\n " + - StringJoin(args, " ") + " -fsyntax-only"; - }; - - switch (error_code) { - case CXError_Success: - return std::make_unique(cx_tu); - case CXError_Failure: - 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(); - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " - << make_msg(); - return nullptr; - } - - return nullptr; -} - -// static -std::unique_ptr ClangTranslationUnit::Reparse( - std::unique_ptr tu, - std::vector& unsaved) { - int error_code; - { - error_code = clang_reparseTranslationUnit( - tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), - clang_defaultReparseOptions(tu->cx_tu)); - } - - if (error_code != CXError_Success && tu->cx_tu) - EmitDiagnostics("", {}, tu->cx_tu); - - switch (error_code) { - case CXError_Success: - return tu; - case CXError_Failure: - LOG_S(ERROR) << "libclang reparse generic failure"; - return nullptr; - case CXError_Crashed: - LOG_S(ERROR) << "libclang reparse crashed"; - return nullptr; - case CXError_InvalidArguments: - LOG_S(ERROR) << "libclang reparse had invalid arguments"; - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang reparse had ast read error"; - return nullptr; - } - - return nullptr; -} - -ClangTranslationUnit::ClangTranslationUnit(CXTranslationUnit tu) : cx_tu(tu) {} - -ClangTranslationUnit::~ClangTranslationUnit() { - clang_disposeTranslationUnit(cx_tu); -} diff --git a/src/clang_translation_unit.h b/src/clang_translation_unit.h deleted file mode 100644 index 59e2f17fa..000000000 --- a/src/clang_translation_unit.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "clang_cursor.h" - -#include - -#include -#include -#include - -// RAII wrapper around CXTranslationUnit which also makes it much more -// challenging to use a CXTranslationUnit instance that is not correctly -// initialized. -struct ClangTranslationUnit { - static std::unique_ptr Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags); - - static std::unique_ptr Reparse( - std::unique_ptr tu, - std::vector& unsaved); - - explicit ClangTranslationUnit(CXTranslationUnit tu); - ~ClangTranslationUnit(); - - CXTranslationUnit cx_tu; -}; diff --git a/src/clang_cursor.cc b/src/clang_tu.cc similarity index 64% rename from src/clang_cursor.cc rename to src/clang_tu.cc index ab880b3d9..dbb1d89db 100644 --- a/src/clang_cursor.cc +++ b/src/clang_tu.cc @@ -1,12 +1,70 @@ -#include "clang_cursor.h" +#include "clang_tu.h" #include "clang_utils.h" +#include "log.hh" +#include "platform.h" +#include "utils.h" #include #include #include #include +namespace { + +void EmitDiagnostics(std::string path, + std::vector args, + CXTranslationUnit tu) { + std::string output = "Fatal errors while trying to parse " + path + "\n"; + output += + "Args: " + + StringJoinMap(args, [](const char* arg) { return std::string(arg); }) + + "\n"; + + size_t num_diagnostics = clang_getNumDiagnostics(tu); + for (unsigned i = 0; i < num_diagnostics; ++i) { + output += " - "; + + CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); + + // Location. + CXFile file; + unsigned int line, column; + clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, + &line, &column, nullptr); + std::string path = FileName(file); + output += path + ":" + std::to_string(line - 1) + ":" + + std::to_string(column) + " "; + + // Severity + switch (clang_getDiagnosticSeverity(diagnostic)) { + case CXDiagnostic_Ignored: + case CXDiagnostic_Note: + output += "[info]"; + break; + case CXDiagnostic_Warning: + output += "[warning]"; + break; + case CXDiagnostic_Error: + output += "[error]"; + break; + case CXDiagnostic_Fatal: + output += "[fatal]"; + break; + } + + // Content. + output += " " + ToString(clang_getDiagnosticSpelling(diagnostic)); + + clang_disposeDiagnostic(diagnostic); + + output += "\n"; + } + + LOG_S(WARNING) << output; +} +} // namespace + Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { CXSourceLocation start = clang_getRangeStart(range); CXSourceLocation end = clang_getRangeEnd(range); @@ -284,3 +342,97 @@ ClangIndex::ClangIndex(int exclude_declarations_from_pch, ClangIndex::~ClangIndex() { clang_disposeIndex(cx_index); } + +// static +std::unique_ptr ClangTranslationUnit::Create( + ClangIndex* index, + const std::string& filepath, + const std::vector& arguments, + std::vector& unsaved_files, + unsigned flags) { + std::vector args; + for (auto& arg : arguments) + args.push_back(arg.c_str()); + + CXTranslationUnit cx_tu; + CXErrorCode error_code; + { + error_code = clang_parseTranslationUnit2FullArgv( + index->cx_index, nullptr, args.data(), (int)args.size(), + unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); + } + + if (error_code != CXError_Success && cx_tu) + EmitDiagnostics(filepath, args, cx_tu); + + // We sometimes dump the command to logs and ask the user to run it. Include + // -fsyntax-only so they don't do a full compile. + auto make_msg = [&]() { + return "Please try running the following, identify which flag causes the " + "issue, and report a bug. ccls will then filter the flag for you " + " automatically:\n " + + StringJoin(args, " ") + " -fsyntax-only"; + }; + + switch (error_code) { + case CXError_Success: + return std::make_unique(cx_tu); + case CXError_Failure: + 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(); + return nullptr; + case CXError_ASTReadError: + LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " + << make_msg(); + return nullptr; + } + + return nullptr; +} + +// static +std::unique_ptr ClangTranslationUnit::Reparse( + std::unique_ptr tu, + std::vector& unsaved) { + int error_code; + { + error_code = clang_reparseTranslationUnit( + tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), + clang_defaultReparseOptions(tu->cx_tu)); + } + + if (error_code != CXError_Success && tu->cx_tu) + EmitDiagnostics("", {}, tu->cx_tu); + + switch (error_code) { + case CXError_Success: + return tu; + case CXError_Failure: + LOG_S(ERROR) << "libclang reparse generic failure"; + return nullptr; + case CXError_Crashed: + LOG_S(ERROR) << "libclang reparse crashed"; + return nullptr; + case CXError_InvalidArguments: + LOG_S(ERROR) << "libclang reparse had invalid arguments"; + return nullptr; + case CXError_ASTReadError: + LOG_S(ERROR) << "libclang reparse had ast read error"; + return nullptr; + } + + return nullptr; +} + +ClangTranslationUnit::ClangTranslationUnit(CXTranslationUnit tu) : cx_tu(tu) {} + +ClangTranslationUnit::~ClangTranslationUnit() { + clang_disposeTranslationUnit(cx_tu); +} diff --git a/src/clang_cursor.h b/src/clang_tu.h similarity index 82% rename from src/clang_cursor.h rename to src/clang_tu.h index 67acd08bd..2530b2de0 100644 --- a/src/clang_cursor.h +++ b/src/clang_tu.h @@ -1,12 +1,10 @@ #pragma once - #include "nt_string.h" #include "position.h" #include -#include -#include +#include #include #include @@ -119,3 +117,24 @@ class ClangIndex { ~ClangIndex(); CXIndex cx_index; }; + +// RAII wrapper around CXTranslationUnit which also makes it much more +// challenging to use a CXTranslationUnit instance that is not correctly +// initialized. +struct ClangTranslationUnit { + static std::unique_ptr Create( + ClangIndex* index, + const std::string& filepath, + const std::vector& arguments, + std::vector& unsaved_files, + unsigned flags); + + static std::unique_ptr Reparse( + std::unique_ptr tu, + std::vector& unsaved); + + explicit ClangTranslationUnit(CXTranslationUnit tu); + ~ClangTranslationUnit(); + + CXTranslationUnit cx_tu; +}; diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 3e7ce0f7f..c714ec9b9 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -1,6 +1,7 @@ #include "diagnostics_engine.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -30,6 +31,6 @@ void DiagnosticsEngine::Publish(WorkingFiles* working_files, Out_TextDocumentPublishDiagnostics out; out.params.uri = lsDocumentUri::FromPath(path); out.params.diagnostics = diagnostics; - QueueManager::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); + pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); } } diff --git a/src/include_complete.cc b/src/include_complete.cc index 1d1b74a16..5fb6c9b1d 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -107,7 +107,7 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { - set_thread_name("scan_includes"); + set_thread_name("include"); Timer timer; for (const std::string& dir : project_->quote_include_directories) diff --git a/src/clang_indexer.cc b/src/indexer.cc similarity index 99% rename from src/clang_indexer.cc rename to src/indexer.cc index a9d669864..0794a5f31 100644 --- a/src/clang_indexer.cc +++ b/src/indexer.cc @@ -1,7 +1,5 @@ #include "indexer.h" -#include "clang_cursor.h" -#include "clang_utils.h" #include "log.hh" #include "platform.h" #include "serializer.h" diff --git a/src/indexer.h b/src/indexer.h index 2c35784eb..ae29f918b 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -1,7 +1,6 @@ #pragma once -#include "clang_cursor.h" -#include "clang_translation_unit.h" +#include "clang_tu.h" #include "clang_utils.h" #include "file_consumer.h" #include "language.h" diff --git a/src/main.cc b/src/main.cc index fcfc66e92..03936f5c7 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,6 +5,7 @@ #include "serializers/json.h" #include "test.h" #include "working_files.h" +using namespace ccls; #include #include @@ -56,8 +57,7 @@ int main(int argc, char** argv) { return 0; } - MultiQueueWaiter querydb_waiter, indexer_waiter, stdout_waiter; - QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); + pipeline::Init(); #ifdef _WIN32 // We need to write to stdout in binary mode because in Windows, writing @@ -132,11 +132,11 @@ int main(int argc, char** argv) { std::unordered_map request_times; // The thread that reads from stdin and dispatchs commands to the main thread. - LaunchStdinLoop(&request_times); + pipeline::LaunchStdin(&request_times); // The thread that writes responses from the main thread to stdout. - LaunchStdoutThread(&request_times, &stdout_waiter); + pipeline::LaunchStdout(&request_times); // Main thread which also spawns indexer threads upon the "initialize" request. - MainLoop(&querydb_waiter, &indexer_waiter); + pipeline::MainLoop(); } return 0; diff --git a/src/match.cc b/src/match.cc index 6f6bda56f..178095d61 100644 --- a/src/match.cc +++ b/src/match.cc @@ -1,7 +1,8 @@ #include "match.h" #include "lsp.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -32,7 +33,7 @@ std::optional Matcher::Create(const std::string& search) { out.params.type = lsMessageType::Error; out.params.message = "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); return std::nullopt; } } diff --git a/src/message_handler.cc b/src/message_handler.cc index a0014c216..cd7915e5b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -4,7 +4,8 @@ #include "log.hh" #include "project.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -167,7 +168,7 @@ bool FindFileOrFail(QueryDatabase* db, out.error.code = lsErrorCodes::InternalError; out.error.message = "Unable to find file " + absolute_path; } - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } return false; @@ -182,7 +183,7 @@ void EmitInactiveLines(WorkingFile* working_file, if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); } - QueueManager::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); + pipeline::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); } void EmitSemanticHighlighting(QueryDatabase* db, @@ -343,5 +344,5 @@ void EmitSemanticHighlighting(QueryDatabase* db, for (auto& entry : grouped_symbols) if (entry.second.ranges.size()) out.params.symbols.push_back(entry.second); - QueueManager::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); + pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index 804137623..fa04a498e 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { @@ -43,7 +44,7 @@ struct Handler_CclsBase : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsBase); diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 08c94515e..2911d75da 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -1,6 +1,8 @@ #include "message_handler.h" +#include "pipeline.hh" +using namespace ccls; #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -225,7 +227,7 @@ struct Handler_CclsCallHierarchy } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc index db781be98..4325d3b7c 100644 --- a/src/messages/ccls_callers.cc +++ b/src/messages/ccls_callers.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "$ccls/callers"; @@ -39,7 +40,7 @@ struct Handler_CclsCallers : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallers); diff --git a/src/messages/ccls_file_info.cc b/src/messages/ccls_file_info.cc index cbd6ed78d..689ef1f94 100644 --- a/src/messages/ccls_file_info.cc +++ b/src/messages/ccls_file_info.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; MAKE_REFLECT_STRUCT(QueryFile::Def, path, @@ -49,7 +50,7 @@ struct Handler_CclsFileInfo : BaseMessageHandler { out.result.language = file->def->language; out.result.includes = file->def->includes; out.result.inactive_regions = file->def->inactive_regions; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFileInfo); diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index bf36450f7..6584b373a 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -1,12 +1,11 @@ -#include "cache_manager.h" #include "match.h" #include "message_handler.h" -#include "pipeline.hh" #include "platform.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include "working_files.h" +using namespace ccls; #include #include @@ -79,7 +78,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { } // Send index requests for every file. - project->Index(QueueManager::instance(), working_files, lsRequestId()); + project->Index(working_files, lsRequestId()); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index bbf255a13..c6fccaff9 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -95,7 +96,7 @@ bool ExpandHelper(MessageHandler* m, if (derived) { if (levels > 0) { for (auto usr : entity.derived) { - if (seen.insert(usr).second) + if (!seen.insert(usr).second) continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); @@ -110,7 +111,7 @@ bool ExpandHelper(MessageHandler* m, } else { if (levels > 0) { for (auto usr : def->bases) { - if (seen.insert(usr).second) + if (!seen.insert(usr).second) continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); @@ -180,17 +181,15 @@ struct Handler_CclsInheritanceHierarchy WorkingFile* wfile = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(wfile, file, params.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { out.result = BuildInitial(sym, params.derived, params.qualified, params.levels); break; } - } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index dd075c399..2ac6045da 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -264,7 +265,7 @@ struct Handler_CclsMemberHierarchy } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index 3a32f6efb..382bba348 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include #include @@ -126,7 +127,7 @@ struct Handler_CclsRandom : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsRandom); diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 90575b905..31e0c7790 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "$ccls/vars"; @@ -48,7 +49,7 @@ struct Handler_CclsVars : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsVars); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index d15ba2e2a..7a00ca81d 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,4 +1,3 @@ -#include "cache_manager.h" #include "diagnostics_engine.h" #include "filesystem.hh" #include "include_complete.h" @@ -7,10 +6,10 @@ #include "pipeline.hh" #include "platform.h" #include "project.h" -#include "queue_manager.h" #include "serializers/json.h" #include "timer.h" #include "working_files.h" +using namespace ccls; #include #include @@ -482,7 +481,7 @@ struct Handler_Initialize : BaseMessageHandler { Out_InitializeResponse out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Set project root. EnsureEndsInSlash(project_path); @@ -515,7 +514,7 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); - Indexer_Main(diag_engine, vfs, project, working_files, waiter); + pipeline::Indexer_Main(diag_engine, vfs, project, working_files); }).detach(); } @@ -524,7 +523,7 @@ struct Handler_Initialize : BaseMessageHandler { include_complete->Rescan(); time.Reset(); - project->Index(QueueManager::instance(), working_files, request->id); + project->Index(working_files, request->id); // We need to support multiple concurrent index processes. time.ResetAndPrint("[perf] Dispatched initial index requests"); } diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index e16721d47..e06c72811 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -1,5 +1,6 @@ #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "shutdown"; @@ -21,7 +22,7 @@ struct Handler_Shutdown : BaseMessageHandler { void Run(In_Shutdown* request) override { Out_Shutdown out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_Shutdown); diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 2ac395c9e..a5b32fb65 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -2,7 +2,8 @@ #include "lsp_code_action.h" #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/codeLens"; @@ -225,7 +226,7 @@ struct Handler_TextDocumentCodeLens }; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 1f536a40b..399986557 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -2,9 +2,10 @@ #include "fuzzy_match.h" #include "include_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include "working_files.h" +using namespace ccls; #include "lex_utils.h" @@ -270,7 +271,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { auto write_empty_result = [request]() { Out_TextDocumentComplete out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); }; std::string path = request->params.textDocument.uri.GetPath(); @@ -377,7 +378,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { item.textEdit->range.end.character = (int)buffer_line.size(); } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } else { ClangCompleteManager::OnComplete callback = std::bind( [this, request, is_global_completion, existing_completion, @@ -389,7 +390,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { // Emit completion results. FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren); - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Cache completion results. if (!is_cached_result) { diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 1d7e545a4..80aaf9a15 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -1,7 +1,8 @@ #include "lex_utils.h" #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include #include @@ -173,7 +174,7 @@ struct Handler_TextDocumentDefinition } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 8072cb952..54ce8b702 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" #include "working_files.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didChange"; @@ -25,9 +25,7 @@ struct Handler_TextDocumentDidChange working_files->OnChange(request->params); if (g_config->index.onDidChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/), - true); + pipeline::Index(entry.filename, entry.args, true); } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( diff --git a/src/messages/text_document_did_close.cc b/src/messages/text_document_did_close.cc index 6cf1d3fb0..e13382d74 100644 --- a/src/messages/text_document_did_close.cc +++ b/src/messages/text_document_did_close.cc @@ -1,7 +1,8 @@ #include "clang_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didClose"; @@ -27,7 +28,7 @@ struct Handler_TextDocumentDidClose // Clear any diagnostics for the file. Out_TextDocumentPublishDiagnostics out; out.params.uri = request->params.textDocument.uri; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Remove internal state. working_files->OnClose(request->params.textDocument); diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 12c79bdb4..0f45b5060 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "include_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include "working_files.h" @@ -38,11 +38,9 @@ struct Handler_TextDocumentDidOpen const auto& params = request->params; std::string path = params.textDocument.uri.GetPath(); - ICacheManager cache; WorkingFile* working_file = working_files->OnOpen(params.textDocument); - std::optional cached_file_contents = - cache.LoadCachedFileContents(path); - if (cached_file_contents) + if (std::optional cached_file_contents = + pipeline::LoadCachedFileContents(path)) working_file->SetIndexContent(*cached_file_contents); QueryFile* file = nullptr; @@ -60,11 +58,8 @@ struct Handler_TextDocumentDidOpen // Submit new index request if it is not a header file. if (SourceFileLanguage(path) != LanguageId::Unknown) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, - params.args.size() ? params.args : entry.args, - true /*is_interactive*/), - true /* priority */); + pipeline::Index(entry.filename, + params.args.size() ? params.args : entry.args, true); clang_complete->FlushSession(entry.filename); } diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 50835f013..d3c77f065 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -1,8 +1,8 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didSave"; @@ -29,7 +29,8 @@ struct Handler_TextDocumentDidSave MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDidSave* request) override { - std::string path = request->params.textDocument.uri.GetPath(); + const auto& params = request->params; + std::string path = params.textDocument.uri.GetPath(); // Send out an index request, and copy the current buffer state so we // can update the cached index contents when the index is done. @@ -47,9 +48,7 @@ struct Handler_TextDocumentDidSave // TODO: send as priority request if (!g_config->index.onDidChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/), - true); + pipeline::Index(entry.filename, entry.args, true); } clang_complete->NotifySave(path); diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index 643ef8599..f7cfc0f15 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -1,7 +1,8 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" #include "symbol.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/documentHighlight"; @@ -61,7 +62,7 @@ struct Handler_TextDocumentDocumentHighlight break; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 29071eb7c..959328e38 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/documentSymbol"; @@ -64,7 +65,7 @@ struct Handler_TextDocumentDocumentSymbol } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index eacd662bb..f3f282186 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/hover"; @@ -99,7 +100,7 @@ struct Handler_TextDocumentHover : BaseMessageHandler { } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); diff --git a/src/messages/text_document_implementation.cc b/src/messages/text_document_implementation.cc index 6bb5148f2..8c10fbacf 100644 --- a/src/messages/text_document_implementation.cc +++ b/src/messages/text_document_implementation.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/implementation"; @@ -41,7 +42,7 @@ struct Handler_TextDocumentImplementation break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc index bc860f67b..8ffe41f8e 100644 --- a/src/messages/text_document_range_formatting.cc +++ b/src/messages/text_document_range_formatting.cc @@ -1,7 +1,8 @@ #include "clang_format.h" #include "lex_utils.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "working_files.h" #include @@ -64,7 +65,7 @@ struct Handler_TextDocumentRangeFormatting response.result = {}; #endif - QueueManager::WriteStdout(kMethodType, response); + pipeline::WriteStdout(kMethodType, response); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index dce6e5b74..d8d60f11a 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -135,7 +136,7 @@ struct Handler_TextDocumentReferences if ((int)out.result.size() >= g_config->xref.maxNum) out.result.resize(g_config->xref.maxNum); - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index a3301998f..6e2844bbc 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/rename"; @@ -102,7 +103,7 @@ struct Handler_TextDocumentRename : BaseMessageHandler { break; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index c06050eae..608c4037a 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -1,6 +1,7 @@ #include "clang_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include @@ -142,7 +143,7 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { out.result.activeParameter = active_param; Timer timer; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); if (!is_cached_result) { signature_cache->WithLock([&]() { diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 4a31cde21..98a54312f 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/typeDefinition"; @@ -60,7 +61,7 @@ struct Handler_TextDocumentTypeDefinition } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index ab33009b2..73775d426 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -1,8 +1,8 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include "working_files.h" @@ -31,7 +31,7 @@ struct Handler_WorkspaceDidChangeConfiguration std::to_string(project->entries.size()) + " files)"); time.Reset(); - project->Index(QueueManager::instance(), working_files, lsRequestId()); + project->Index(working_files, lsRequestId()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 3140a9293..f5e813633 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "workspace/didChangeWatchedFiles"; @@ -52,15 +52,13 @@ struct Handler_WorkspaceDidChangeWatchedFiles switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive)); + pipeline::Index(path, entry.args, is_interactive); if (is_interactive) clang_complete->NotifySave(path); break; } case lsFileChangeType::Deleted: - QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive)); + pipeline::Index(path, entry.args, is_interactive); break; } } diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index 8c1327c1a..c2d71c751 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -1,7 +1,8 @@ #include "lsp_code_action.h" #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "workspace/executeCommand"; @@ -34,7 +35,7 @@ struct Handler_WorkspaceExecuteCommand out.result = params.arguments.locations; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 77df7fea6..d9e88dca8 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -1,8 +1,9 @@ #include "fuzzy_match.h" #include "lex_utils.h" #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include #include @@ -124,7 +125,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { out.result.push_back(std::get<0>(entry)); } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); diff --git a/src/pipeline.cc b/src/pipeline.cc index b552448f9..1b06cca79 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -1,6 +1,5 @@ #include "pipeline.hh" -#include "cache_manager.h" #include "clang_complete.h" #include "config.h" #include "diagnostics_engine.h" @@ -11,18 +10,43 @@ #include "platform.h" #include "project.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include #include using namespace llvm; -#include #include +struct Index_Request { + std::string path; + std::vector args; + bool is_interactive; + lsRequestId id; +}; + +struct Index_OnIndexed { + IndexUpdate update; + PerformanceImportFile perf; +}; + +struct Stdout_Request { + MethodType method; + std::string content; +}; + +namespace ccls::pipeline { namespace { +MultiQueueWaiter* main_waiter; +MultiQueueWaiter* indexer_waiter; +MultiQueueWaiter* stdout_waiter; +ThreadedQueue>* on_request; +ThreadedQueue* index_request; +ThreadedQueue* on_indexed; +ThreadedQueue* for_stdout; + // Checks if |path| needs to be reparsed. This will modify cached state // such that calling this function twice with the same path may return true // the first time but will return false the second. @@ -64,24 +88,57 @@ bool FileNeedsParse(int64_t write_time, return false; }; +std::string AppendSerializationFormat(const std::string& base) { + switch (g_config->cacheFormat) { + case SerializeFormat::Binary: + return base + ".blob"; + case SerializeFormat::Json: + return base + ".json"; + } +} + +std::string GetCachePath(const std::string& source_file) { + std::string cache_file; + size_t len = g_config->projectRoot.size(); + if (StartsWith(source_file, g_config->projectRoot)) { + cache_file = EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file.substr(len)); + } else { + cache_file = '@' + EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file); + } + + return g_config->cacheDirectory + cache_file; +} + +std::unique_ptr RawCacheLoad( + const std::string& path) { + std::string cache_path = GetCachePath(path); + std::optional file_content = ReadContent(cache_path); + std::optional serialized_indexed_content = + ReadContent(AppendSerializationFormat(cache_path)); + if (!file_content || !serialized_indexed_content) + return nullptr; + + return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, + *file_content, IndexFile::kMajorVersion); +} + bool Indexer_Parse(DiagnosticsEngine* diag_engine, WorkingFiles* working_files, Project* project, VFS* vfs, ClangIndexer* indexer) { - auto* queue = QueueManager::instance(); - std::optional opt_request = queue->index_request.TryPopFront(); + std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; auto& request = *opt_request; - ICacheManager cache; // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { IndexUpdate dummy; dummy.refresh = true; - queue->on_indexed.PushBack( - Index_OnIndexed(std::move(dummy), PerformanceImportFile()), false); + on_indexed->PushBack({std::move(dummy), PerformanceImportFile()}, false); return false; } @@ -108,7 +165,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, return true; int reparse; // request.is_interactive; - prev = cache.RawCacheLoad(path_to_index); + prev = RawCacheLoad(path_to_index); if (!prev) reparse = 2; else { @@ -132,15 +189,13 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), - request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } for (const auto& dep : dependencies) if (vfs->Mark(dep.first().str(), 0, 2)) { - prev = cache.RawCacheLoad(dep.first().str()); + prev = RawCacheLoad(dep.first().str()); IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), - request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } std::lock_guard lock(vfs->mutex); @@ -152,7 +207,6 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, LOG_S(INFO) << "parse " << path_to_index; - std::vector result; PerformanceImportFile perf; auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}, &perf); @@ -162,7 +216,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, out.id = request.id; out.error.code = lsErrorCodes::InternalError; out.error.message = "Failed to index " + path_to_index; - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } vfs->Reset(path_to_index); return true; @@ -179,12 +233,17 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; LOG_S(INFO) << "emit index for " << path; - prev = cache.RawCacheLoad(path); + prev = RawCacheLoad(path); // Write current index to disk if requested. LOG_S(INFO) << "store index for " << path; Timer time; - cache.WriteToCache(*curr); + { + std::string cache_path = GetCachePath(path); + WriteToFile(cache_path, curr->file_contents); + WriteToFile(AppendSerializationFormat(cache_path), + Serialize(g_config->cacheFormat, *curr)); + } perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); vfs->Reset(path_to_index); @@ -199,8 +258,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; - Index_OnIndexed reply(std::move(update), perf); - queue->on_indexed.PushBack(std::move(reply), request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } return true; @@ -217,26 +275,34 @@ bool ShouldDisplayMethodTiming(MethodType type) { } // namespace +void Init() { + main_waiter = new MultiQueueWaiter; + on_request = new ThreadedQueue>(main_waiter); + on_indexed = new ThreadedQueue(main_waiter); + + indexer_waiter = new MultiQueueWaiter; + index_request = new ThreadedQueue(indexer_waiter); + + stdout_waiter = new MultiQueueWaiter; + for_stdout = new ThreadedQueue(stdout_waiter); +} + void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, Project* project, - WorkingFiles* working_files, - MultiQueueWaiter* waiter) { - auto* queue = QueueManager::instance(); + WorkingFiles* working_files) { // Build one index per-indexer, as building the index acquires a global lock. ClangIndexer indexer; while (true) if (!Indexer_Parse(diag_engine, working_files, project, vfs, &indexer)) - waiter->Wait(&queue->index_request); + indexer_waiter->Wait(index_request); } -void QueryDb_OnIndexed(QueueManager* queue, - QueryDatabase* db, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files, - Index_OnIndexed* response) { - +void Main_OnIndexed(QueryDatabase* db, + SemanticHighlightSymbolCache* semantic_cache, + WorkingFiles* working_files, + Index_OnIndexed* response) { if (response->update.refresh) { LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); @@ -257,9 +323,8 @@ void QueryDb_OnIndexed(QueueManager* queue, if (response->update.files_def_update) { auto& update = *response->update.files_def_update; time.ResetAndPrint("apply index for " + update.value.path); - WorkingFile* working_file = - working_files->GetFileByFilename(update.value.path); - if (working_file) { + if (WorkingFile* working_file = + working_files->GetFileByFilename(update.value.path)) { // Update indexed content. working_file->SetIndexContent(update.file_content); @@ -275,10 +340,9 @@ void QueryDb_OnIndexed(QueueManager* queue, } } -void LaunchStdinLoop(std::unordered_map* request_times) { +void LaunchStdin(std::unordered_map* request_times) { std::thread([request_times]() { set_thread_name("stdin"); - auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; std::optional err = @@ -295,7 +359,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { out.id = id; out.error.code = lsErrorCodes::InvalidParams; out.error.message = std::move(*err); - queue->WriteStdout(kMethodType_Unknown, out); + WriteStdout(kMethodType_Unknown, out); } } continue; @@ -305,7 +369,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { MethodType method_type = message->GetMethodType(); (*request_times)[method_type] = Timer(); - queue->for_querydb.PushBack(std::move(message)); + on_request->PushBack(std::move(message)); // If the message was to exit then querydb will take care of the actual // exit. Stop reading from stdin since it might be detached. @@ -315,16 +379,14 @@ void LaunchStdinLoop(std::unordered_map* request_times) { }).detach(); } -void LaunchStdoutThread(std::unordered_map* request_times, - MultiQueueWaiter* waiter) { +void LaunchStdout(std::unordered_map* request_times) { std::thread([=]() { set_thread_name("stdout"); - auto* queue = QueueManager::instance(); while (true) { - std::vector messages = queue->for_stdout.DequeueAll(); + std::vector messages = for_stdout->DequeueAll(); if (messages.empty()) { - waiter->Wait(&queue->for_stdout); + stdout_waiter->Wait(for_stdout); continue; } @@ -341,8 +403,7 @@ void LaunchStdoutThread(std::unordered_map* request_times, }).detach(); } -void MainLoop(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter) { +void MainLoop() { Project project; SemanticHighlightSymbolCache semantic_cache; WorkingFiles working_files; @@ -362,7 +423,7 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, out.error.message = "Dropping completion request; a newer request " "has come in that will be serviced instead."; - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } }); @@ -389,11 +450,8 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, handler->signature_cache = signature_cache.get(); } - // Run query db main loop. - auto* queue = QueueManager::instance(); while (true) { - std::vector> messages = - queue->for_querydb.DequeueAll(); + std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); for (auto& message : messages) { // TODO: Consider using std::unordered_map to lookup the handler @@ -409,19 +467,40 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, } for (int i = 80; i--;) { - std::optional response = queue->on_indexed.TryPopFront(); + std::optional response = on_indexed->TryPopFront(); if (!response) break; did_work = true; - QueryDb_OnIndexed(queue, &db, &semantic_cache, &working_files, &*response); + Main_OnIndexed(&db, &semantic_cache, &working_files, &*response); } // Cleanup and free any unused memory. FreeUnusedMemory(); - if (!did_work) { - auto* queue = QueueManager::instance(); - querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb); - } + if (!did_work) + main_waiter->Wait(on_indexed, on_request); } } + +void Index(const std::string& path, + const std::vector& args, + bool interactive, + lsRequestId id) { + index_request->PushBack({path, args, interactive, id}, interactive); +} + +std::optional LoadCachedFileContents(const std::string& path) { + return ReadContent(GetCachePath(path)); +} + +void WriteStdout(MethodType method, lsBaseOutMessage& response) { + std::ostringstream sstream; + response.Write(sstream); + + Stdout_Request out; + out.content = sstream.str(); + out.method = method; + for_stdout->PushBack(std::move(out)); +} + +} diff --git a/src/pipeline.hh b/src/pipeline.hh index 87076be90..760ac190c 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,28 +1,35 @@ #pragma once -#include "queue_manager.h" +#include "method.h" +#include "query.h" #include "timer.h" -#include +#include #include +#include -struct ClangTranslationUnit; class DiagnosticsEngine; struct VFS; -struct ICacheManager; struct Project; -struct QueryDatabase; -struct SemanticHighlightSymbolCache; struct WorkingFiles; +struct lsBaseOutMessage; +namespace ccls::pipeline { + +void Init(); +void LaunchStdin(std::unordered_map* request_times); +void LaunchStdout(std::unordered_map* request_times); void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, Project* project, - WorkingFiles* working_files, - MultiQueueWaiter* waiter); + WorkingFiles* working_files); +void MainLoop(); + +void Index(const std::string& path, + const std::vector& args, + bool is_interactive, + lsRequestId id = {}); -void LaunchStdinLoop(std::unordered_map* request_times); -void LaunchStdoutThread(std::unordered_map* request_times, - MultiQueueWaiter* waiter); -void MainLoop(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter); +std::optional LoadCachedFileContents(const std::string& path); +void WriteStdout(MethodType method, lsBaseOutMessage& response); +} diff --git a/src/port.cc b/src/port.cc deleted file mode 100644 index d48df06ab..000000000 --- a/src/port.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "port.h" - -#include -#include - -void ccls_unreachable_internal(const char* msg, const char* file, int line) { - fprintf(stderr, "unreachable %s:%d %s\n", file, line, msg); - CCLS_BUILTIN_UNREACHABLE; - abort(); -} diff --git a/src/port.h b/src/port.h deleted file mode 100644 index da3da3138..000000000 --- a/src/port.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif - -#if defined(__GNUC__) -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#else -#define ATTRIBUTE_UNUSED -#endif - -#ifdef __clang__ -#define GUARDED_BY(x) __attribute__((guarded_by(x))) -#else -#define GUARDED_BY(x) -#endif - -// TODO GCC -#if __has_builtin(__builtin_unreachable) -#define CCLS_BUILTIN_UNREACHABLE __builtin_unreachable() -#elif defined(_MSC_VER) -#define CCLS_BUILTIN_UNREACHABLE __assume(false) -#else -#define CCLS_BUILTIN_UNREACHABLE -#endif - -void ccls_unreachable_internal(const char* msg, const char* file, int line); -#ifndef NDEBUG -#define CCLS_UNREACHABLE(msg) \ - ccls_unreachable_internal(msg, __FILE__, __LINE__) -#else -#define CCLS_UNREACHABLE(msg) -#endif diff --git a/src/project.cc b/src/project.cc index 44682d98c..90abbb8ec 100644 --- a/src/project.cc +++ b/src/project.cc @@ -1,17 +1,17 @@ #include "project.h" -#include "cache_manager.h" #include "clang_utils.h" #include "filesystem.hh" #include "language.h" #include "log.hh" #include "match.h" #include "platform.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "serializers/json.h" #include "timer.h" #include "utils.h" #include "working_files.h" +using namespace ccls; #include #include @@ -454,17 +454,15 @@ void Project::ForAllFilteredFiles( } } -void Project::Index(QueueManager* queue, - WorkingFiles* wfiles, +void Project::Index(WorkingFiles* wfiles, lsRequestId id) { ForAllFilteredFiles([&](int i, const Project::Entry& entry) { bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - queue->index_request.PushBack( - Index_Request(entry.filename, entry.args, is_interactive, id)); + pipeline::Index(entry.filename, entry.args, is_interactive, id); }); // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - queue->index_request.PushBack(Index_Request("", {}, false)); + pipeline::Index("", {}, false); } TEST_SUITE("Project") { diff --git a/src/project.h b/src/project.h index 4b5220b93..d6d3f3960 100644 --- a/src/project.h +++ b/src/project.h @@ -5,12 +5,10 @@ #include #include -#include #include #include #include -class QueueManager; struct WorkingFiles; struct Project { @@ -29,7 +27,7 @@ struct Project { std::vector entries; std::mutex mutex_; - std::unordered_map absolute_path_to_entry_index_ GUARDED_BY(mutex_); + std::unordered_map absolute_path_to_entry_index_; // Loads a project for the given |directory|. // @@ -58,5 +56,5 @@ struct Project { void ForAllFilteredFiles( std::function action); - void Index(QueueManager* queue, WorkingFiles* wfiles, lsRequestId id); + void Index(WorkingFiles* wfiles, lsRequestId id); }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 9f801ced8..04031dedd 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -1,6 +1,6 @@ #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" #include #include diff --git a/src/queue_manager.cc b/src/queue_manager.cc deleted file mode 100644 index 623c72dfb..000000000 --- a/src/queue_manager.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "queue_manager.h" - -#include "cache_manager.h" -#include "lsp.h" -#include "query.h" - -#include - -Index_Request::Index_Request(const std::string& path, - const std::vector& args, - bool is_interactive, - lsRequestId id) - : path(path), args(args), is_interactive(is_interactive), id(id) {} - -Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update, - PerformanceImportFile perf) - : update(std::move(update)), perf(perf) {} - -std::unique_ptr QueueManager::instance_; - -// static -void QueueManager::Init(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter) { - instance_ = std::unique_ptr( - new QueueManager(querydb_waiter, indexer_waiter, stdout_waiter)); -} - -// static -void QueueManager::WriteStdout(MethodType method, lsBaseOutMessage& response) { - std::ostringstream sstream; - response.Write(sstream); - - Stdout_Request out; - out.content = sstream.str(); - out.method = method; - instance()->for_stdout.PushBack(std::move(out)); -} - -QueueManager::QueueManager(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter) - : for_stdout(stdout_waiter), - for_querydb(querydb_waiter), - on_indexed(querydb_waiter), - index_request(indexer_waiter) {} diff --git a/src/queue_manager.h b/src/queue_manager.h deleted file mode 100644 index 13ee57b47..000000000 --- a/src/queue_manager.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "method.h" -#include "query.h" -#include "threaded_queue.h" - -#include - -struct ICacheManager; -struct lsBaseOutMessage; - -struct Stdout_Request { - MethodType method; - std::string content; -}; - -struct Index_Request { - std::string path; - // TODO: make |args| a string that is parsed lazily. - std::vector args; - bool is_interactive; - lsRequestId id; - - Index_Request(const std::string& path, - const std::vector& args, - bool is_interactive, - lsRequestId id = {}); -}; - -struct Index_OnIdMapped { - std::shared_ptr cache_manager; - std::unique_ptr previous; - std::unique_ptr current; - - PerformanceImportFile perf; - bool is_interactive; - bool write_to_disk; - - Index_OnIdMapped(const std::shared_ptr& cache_manager, - std::unique_ptr previous, - std::unique_ptr current, - PerformanceImportFile perf, - bool is_interactive, - bool write_to_disk) - : cache_manager(cache_manager), - previous(std::move(previous)), - current(std::move(current)), - perf(perf), - is_interactive(is_interactive), - write_to_disk(write_to_disk) {} -}; - -struct Index_OnIndexed { - IndexUpdate update; - PerformanceImportFile perf; - - Index_OnIndexed(IndexUpdate&& update, PerformanceImportFile perf); -}; - -class QueueManager { - static std::unique_ptr instance_; - - public: - static QueueManager* instance() { return instance_.get(); } - static void Init(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter); - static void WriteStdout(MethodType method, lsBaseOutMessage& response); - - // Messages received by "stdout" thread. - ThreadedQueue for_stdout; - - // Runs on querydb thread. - ThreadedQueue> for_querydb; - ThreadedQueue on_indexed; - - // Runs on indexer threads. - ThreadedQueue index_request; - - private: - explicit QueueManager(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter); -}; diff --git a/src/serializer.h b/src/serializer.h index cc296c796..28f284813 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -2,7 +2,8 @@ #include "maybe.h" #include "nt_string.h" -#include "port.h" + +#include #include @@ -83,15 +84,15 @@ struct IndexFile; #define MAKE_REFLECT_TYPE_PROXY(type_name) \ MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) -#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ - ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ - as_type value0; \ - ::Reflect(visitor, value0); \ - value = static_cast(value0); \ - } \ - ATTRIBUTE_UNUSED inline void Reflect(Writer& visitor, type& value) { \ - auto value0 = static_cast(value); \ - ::Reflect(visitor, value0); \ +#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ + as_type value0; \ + ::Reflect(visitor, value0); \ + value = static_cast(value0); \ + } \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer& visitor, type& value) { \ + auto value0 = static_cast(value); \ + ::Reflect(visitor, value0); \ } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); diff --git a/src/test.cc b/src/test.cc index 00dec8261..e9b5d8b34 100644 --- a/src/test.cc +++ b/src/test.cc @@ -284,8 +284,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { &all_expected_output); // Build flags. - if (!AnyStartsWith(flags, "-x")) - flags.push_back("-xc++"); flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); flags.push_back(path); diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 93f1ccf1f..6e3bc9d70 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -94,26 +94,6 @@ struct ThreadedQueue : public BaseThreadQueue { Push<&std::deque::push_back>(std::move(t), priority); } - // Add a set of elements to the queue. - void EnqueueAll(std::vector&& elements, bool priority = false) { - if (elements.empty()) - return; - - std::lock_guard lock(mutex_); - - total_count_ += elements.size(); - - for (T& element : elements) { - if (priority) - priority_.push_back(std::move(element)); - else - queue_.push_back(std::move(element)); - } - elements.clear(); - - waiter_->cv.notify_all(); - } - // Return all elements in the queue. std::vector DequeueAll() { std::lock_guard lock(mutex_); diff --git a/src/utils.cc b/src/utils.cc index cc4484765..68de51894 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -48,15 +48,6 @@ bool StartsWith(std::string_view s, std::string_view prefix) { std::equal(prefix.begin(), prefix.end(), s.begin()); } -bool AnyStartsWith(const std::vector& xs, - std::string_view prefix) { - return std::any_of(xs.begin(), xs.end(), std::bind(StartsWith, _1, prefix)); -} - -bool StartsWithAny(std::string_view s, const std::vector& ps) { - return std::any_of(ps.begin(), ps.end(), std::bind(StartsWith, s, _1)); -} - bool EndsWithAny(std::string_view s, const std::vector& ss) { return std::any_of(ss.begin(), ss.end(), std::bind(EndsWith, s, _1)); } diff --git a/src/utils.h b/src/utils.h index 4258ae498..b1febec3c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -17,8 +17,6 @@ uint64_t HashUsr(std::string_view s); // Returns true if |value| starts/ends with |start| or |ending|. bool StartsWith(std::string_view value, std::string_view start); bool EndsWith(std::string_view value, std::string_view ending); -bool AnyStartsWith(const std::vector& xs, std::string_view prefix); -bool StartsWithAny(std::string_view s, const std::vector& ps); bool EndsWithAny(std::string_view s, const std::vector& ss); bool FindAnyPartial(const std::string& value, const std::vector& values); From 23c9c3a0619f85f9ccc45ca8c33bc38166ce3a78 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 28 May 2018 17:03:14 -0700 Subject: [PATCH 107/378] $ccls/memberHierarchy: add field offset --- .../declaration_vs_definition/class_member.cc | 5 ++- .../class_member_static.cc | 5 ++- index_tests/namespaces/namespace_alias.cc | 5 ++- index_tests/namespaces/namespace_reference.cc | 5 ++- .../implicit_variable_instantiation.cc | 13 +++++- .../templates/member_ref_in_template.cc | 5 ++- ...ass_template_func_usage_folded_into_one.cc | 8 +++- ...ace_template_type_usage_folded_into_one.cc | 8 +++- index_tests/types/anonymous_struct.cc | 16 ++++++- index_tests/unions/union_decl.cc | 8 +++- index_tests/unions/union_usage.cc | 8 +++- .../usage/func_usage_class_inline_var_def.cc | 5 ++- index_tests/usage/type_usage_declare_field.cc | 8 +++- index_tests/usage/usage_inside_of_call.cc | 8 +++- index_tests/usage/var_usage_class_member.cc | 8 +++- index_tests/usage/var_usage_cstyle_cast.cc | 5 ++- index_tests/vars/class_member.cc | 5 ++- index_tests/vars/class_static_member.cc | 5 ++- src/indexer.cc | 5 ++- src/indexer.h | 2 +- src/messages/ccls_member_hierarchy.cc | 28 +++++++++--- src/messages/ccls_random.cc | 2 +- src/project.cc | 5 +-- src/serializer.h | 45 +++++++++++-------- src/serializers/binary.h | 12 ++--- src/serializers/json.h | 4 +- 26 files changed, 173 insertions(+), 60 deletions(-) diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index 02495c025..b0feb85bf 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -37,7 +37,10 @@ class Foo { "derived": [], "types": [], "funcs": [], - "vars": [9736582033442720743], + "vars": [{ + "L": 9736582033442720743, + "R": 0 + }], "instances": [], "uses": [] }], diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 7b4e00ec6..4abc45239 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -39,7 +39,10 @@ int Foo::foo; "derived": [], "types": [], "funcs": [], - "vars": [8942920329766232482], + "vars": [{ + "L": 8942920329766232482, + "R": -1 + }], "instances": [], "uses": ["5:5-5:8|0|1|4"] }], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 8a7e8ef68..50af62917 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -113,7 +113,10 @@ void func() { "derived": [], "types": [], "funcs": [], - "vars": [15042442838933090518], + "vars": [{ + "L": 15042442838933090518, + "R": -1 + }], "instances": [], "uses": ["3:20-3:23|17805385787823406700|2|4", "9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] }, { diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 3ffedd6d5..73d50bd95 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -76,7 +76,10 @@ void Runner() { "derived": [], "types": [], "funcs": [17328473273923617489], - "vars": [12898699035586282159], + "vars": [{ + "L": 12898699035586282159, + "R": -1 + }], "instances": [], "uses": ["1:11-1:13|0|1|4", "7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] }, { diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 845721cb8..b45508b80 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -81,7 +81,13 @@ namespace ns { "derived": [], "types": [], "funcs": [], - "vars": [12898699035586282159, 9008550860229740818], + "vars": [{ + "L": 12898699035586282159, + "R": -1 + }, { + "L": 9008550860229740818, + "R": -1 + }], "instances": [], "uses": ["1:11-1:13|0|1|4"] }, { @@ -98,7 +104,10 @@ namespace ns { "derived": [], "types": [], "funcs": [], - "vars": [4731849186641714451], + "vars": [{ + "L": 4731849186641714451, + "R": -1 + }], "instances": [], "uses": ["10:26-10:32|0|1|4", "13:13-13:19|0|1|4", "14:14-14:20|0|1|4"] }, { diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index 43c19f790..fd71e2db5 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -70,7 +70,10 @@ void foo() { "derived": [], "types": [], "funcs": [8905286151237717330], - "vars": [5866801090710377175], + "vars": [{ + "L": 5866801090710377175, + "R": -1 + }], "instances": [], "uses": [] }, { diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 3880a11db..a6a609ce2 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -62,7 +62,13 @@ namespace ns { "derived": [], "types": [], "funcs": [], - "vars": [15768138241775955040, 3182917058194750998], + "vars": [{ + "L": 15768138241775955040, + "R": -1 + }, { + "L": 3182917058194750998, + "R": -1 + }], "instances": [], "uses": ["1:11-1:13|0|1|4"] }, { diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 4c00e09ab..3b7f23e78 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -26,7 +26,13 @@ namespace ns { "derived": [], "types": [], "funcs": [], - "vars": [15768138241775955040, 3182917058194750998], + "vars": [{ + "L": 15768138241775955040, + "R": -1 + }, { + "L": 3182917058194750998, + "R": -1 + }], "instances": [], "uses": ["1:11-1:13|0|1|4"] }, { diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 362b11a47..087cd8dec 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -38,7 +38,16 @@ union vector3 { "derived": [], "types": [], "funcs": [], - "vars": [3348817847649945564, 4821094820988543895, 15292551660437765731], + "vars": [{ + "L": 3348817847649945564, + "R": 0 + }, { + "L": 4821094820988543895, + "R": 32 + }, { + "L": 15292551660437765731, + "R": 64 + }], "instances": [], "uses": [] }, { @@ -55,7 +64,10 @@ union vector3 { "derived": [], "types": [], "funcs": [], - "vars": [1963212417280098348], + "vars": [{ + "L": 1963212417280098348, + "R": 0 + }], "instances": [], "uses": [] }], diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index ad1c9e7e0..87949e04b 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -53,7 +53,13 @@ union Foo { "derived": [], "types": [], "funcs": [], - "vars": [9529311430721959843, 8804696910588009104], + "vars": [{ + "L": 9529311430721959843, + "R": 0 + }, { + "L": 8804696910588009104, + "R": 0 + }], "instances": [], "uses": [] }], diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 3de937b68..3329ecd57 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -77,7 +77,13 @@ void act(Foo*) { "derived": [], "types": [], "funcs": [], - "vars": [9529311430721959843, 8804696910588009104], + "vars": [{ + "L": 9529311430721959843, + "R": 0 + }, { + "L": 8804696910588009104, + "R": 0 + }], "instances": [2933643612409209903], "uses": ["6:1-6:4|0|1|4", "8:10-8:13|0|1|4"] }], diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 2c5c3db30..3d62897e1 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -57,7 +57,10 @@ class Foo { "derived": [], "types": [], "funcs": [], - "vars": [4220150017963593039], + "vars": [{ + "L": 4220150017963593039, + "R": 0 + }], "instances": [], "uses": [] }], diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index d5814ff92..e24018323 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -58,7 +58,13 @@ struct Foo { "derived": [], "types": [], "funcs": [], - "vars": [14314859014962085433, 14727441168849658842], + "vars": [{ + "L": 14314859014962085433, + "R": 0 + }, { + "L": 14727441168849658842, + "R": 64 + }], "instances": [], "uses": [] }], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 93875bafe..9642d1d9f 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -93,7 +93,13 @@ void foo() { "derived": [], "types": [], "funcs": [], - "vars": [9648311402855509901, 11489549839875479478], + "vars": [{ + "L": 9648311402855509901, + "R": 0 + }, { + "L": 11489549839875479478, + "R": -1 + }], "instances": [], "uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"] }], diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 9eeeb6e8e..d10749eb7 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -96,7 +96,13 @@ void foo() { "derived": [], "types": [], "funcs": [], - "vars": [4220150017963593039, 3873837747174060388], + "vars": [{ + "L": 4220150017963593039, + "R": 0 + }, { + "L": 3873837747174060388, + "R": 32 + }], "instances": [14669930844300034456], "uses": ["11:3-11:6|0|1|4"] }], diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 21839e12c..b554c29e9 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -44,7 +44,10 @@ const VarType Holder::static_var; "derived": [], "types": [], "funcs": [], - "vars": [7057400933868440116], + "vars": [{ + "L": 7057400933868440116, + "R": -1 + }], "instances": [], "uses": ["7:15-7:21|0|1|4"] }], diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 548da9808..191c62cae 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -21,7 +21,10 @@ class Foo { "derived": [], "types": [], "funcs": [], - "vars": [13799811842374292251], + "vars": [{ + "L": 13799811842374292251, + "R": 0 + }], "instances": [13799811842374292251], "uses": ["2:3-2:6|0|1|4"] }], diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index ba6fbbe79..426090c81 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -23,7 +23,10 @@ Foo* Foo::member = nullptr; "derived": [], "types": [], "funcs": [], - "vars": [5844987037615239736], + "vars": [{ + "L": 5844987037615239736, + "R": -1 + }], "instances": [5844987037615239736], "uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] }], diff --git a/src/indexer.cc b/src/indexer.cc index 0794a5f31..48dffa655 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -681,7 +681,7 @@ void OnIndexReference_Function(IndexFile* db, } // namespace // static -const int IndexFile::kMajorVersion = 15; +const int IndexFile::kMajorVersion = 16; const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(const std::string& path, const std::string& contents) @@ -1491,8 +1491,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { } case SymbolKind::Type: if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) { + long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor); db->ToType(decl->semanticContainer->cursor) - .def.vars.push_back(var.usr); + .def.vars.emplace_back(var.usr, offset); } break; default: diff --git a/src/indexer.h b/src/indexer.h index ae29f918b..d79cd66e5 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -171,7 +171,7 @@ struct TypeDef : NameMixin { // Types, functions, and variables defined in this type. std::vector types; std::vector funcs; - std::vector vars; + std::vector> vars; // If set, then this is the same underlying type as the given value (ie, this // type comes from a using or typedef statement). diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 2ac6045da..6cc9b7550 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -74,17 +74,29 @@ bool Expand(MessageHandler* m, void DoField(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, const QueryVar& var, + int64_t offset, bool qualified, int levels) { const QueryVar::Def* def1 = var.AnyDef(); if (!def1) return; Out_CclsMemberHierarchy::Entry entry1; + // With multiple inheritance, the offset is incorrect. + if (offset >= 0) { + if (offset / 8 < 10) + entry1.fieldName += ' '; + entry1.fieldName += std::to_string(offset / 8); + if (offset % 8) { + entry1.fieldName += '.'; + entry1.fieldName += std::to_string(offset % 8); + } + entry1.fieldName += ' '; + } if (qualified) - entry1.fieldName = def1->detailed_name; + entry1.fieldName += def1->detailed_name; else - entry1.fieldName = def1->detailed_name.substr(0, def1->qual_name_offset) + - std::string(def1->Name(false)); + entry1.fieldName += def1->detailed_name.substr(0, def1->qual_name_offset) + + std::string(def1->Name(false)); if (def1->spell) { if (std::optional loc = GetLsLocation(m->db, m->working_files, *def1->spell)) @@ -158,9 +170,11 @@ bool Expand(MessageHandler* m, entry->children.push_back(std::move(entry1)); } } else { - EachDefinedEntity(m->db->usr2var, def->vars, [&](QueryVar& var) { - DoField(m, entry, var, qualified, levels - 1); - }); + for (auto it : def->vars) { + QueryVar& var = m->db->usr2var[it.first]; + if (!var.def.empty()) + DoField(m, entry, var, it.second, qualified, levels - 1); + } } } } @@ -195,7 +209,7 @@ struct Handler_CclsMemberHierarchy entry.location = *loc; } EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) { - DoField(this, &entry, var, qualified, levels - 1); + DoField(this, &entry, var, -1, qualified, levels - 1); }); return entry; } diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index 382bba348..a5fabdb2e 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -80,7 +80,7 @@ struct Handler_CclsRandom : BaseMessageHandler { Add(sym2id, adj, it.second.instances, n); Add(sym2id, adj, def->funcs, n); Add(sym2id, adj, def->types, n); - Add(sym2id, adj, def->vars, n); + //Add(sym2id, adj, def->vars, n); n++; } for (auto& it : db->usr2var) diff --git a/src/project.cc b/src/project.cc index 90abbb8ec..a7d0534bf 100644 --- a/src/project.cc +++ b/src/project.cc @@ -269,9 +269,8 @@ std::vector LoadCompilationEntriesFromDirectory( #endif } if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { - LOG_S(INFO) << "unable to load " << Path.c_str() - << "; using directory listing instead."; - return LoadFromDirectoryListing(project); + LOG_S(WARNING) << "unable to load " << Path.c_str(); + return {}; } LOG_S(INFO) << "loaded " << Path.c_str(); diff --git a/src/serializer.h b/src/serializer.h index 28f284813..d2ee11915 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -48,7 +48,7 @@ class Reader { virtual std::unique_ptr operator[](const char* x) = 0; virtual void IterArray(std::function fn) = 0; - virtual void DoMember(const char* name, std::function fn) = 0; + virtual void Member(const char* name, std::function fn) = 0; }; class Writer { @@ -75,8 +75,8 @@ class Writer { struct IndexFile; -#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) -#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); +#define REFLECT_MEMBER_START() ReflectMemberStart(visitor) +#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) #define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) @@ -265,6 +265,19 @@ void ReflectMember(Writer& visitor, Reflect(visitor, value); } +template +void Reflect(Reader& vis, std::pair& v) { + vis.Member("L", [&]() { Reflect(vis, v.first); }); + vis.Member("R", [&]() { Reflect(vis, v.second); }); +} +template +void Reflect(Writer& vis, std::pair& v) { + vis.StartObject(); + ReflectMember(vis, "L", v.first); + ReflectMember(vis, "R", v.second); + vis.EndObject(); +} + // std::vector template void Reflect(Reader& visitor, std::vector& values) { @@ -284,31 +297,27 @@ void Reflect(Writer& visitor, std::vector& values) { // ReflectMember -template -bool ReflectMemberStart(Reader& visitor, T& value) { +inline bool ReflectMemberStart(Reader& vis) { return false; } -template -bool ReflectMemberStart(Writer& visitor, T& value) { - visitor.StartObject(); +inline bool ReflectMemberStart(Writer& vis) { + vis.StartObject(); return true; } -template -void ReflectMemberEnd(Reader& visitor, T& value) {} -template -void ReflectMemberEnd(Writer& visitor, T& value) { - visitor.EndObject(); +inline void ReflectMemberEnd(Reader& vis) {} +inline void ReflectMemberEnd(Writer& vis) { + vis.EndObject(); } template -void ReflectMember(Reader& visitor, const char* name, T& value) { - visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); }); +void ReflectMember(Reader& vis, const char* name, T& v) { + vis.Member(name, [&]() { Reflect(vis, v); }); } template -void ReflectMember(Writer& visitor, const char* name, T& value) { - visitor.Key(name); - Reflect(visitor, value); +void ReflectMember(Writer& vis, const char* name, T& v) { + vis.Key(name); + Reflect(vis, v); } // API diff --git a/src/serializers/binary.h b/src/serializers/binary.h index ad6d64fe5..821c4367b 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -39,10 +39,10 @@ class BinaryReader : public Reader { // Abuse how the function is called in serializer.h bool IsNull() override { return !*p_++; } bool IsInt() override { return true; } - bool IsInt64() override {return true;} - bool IsUInt64() override {return true;} - bool IsDouble() override {return true;}; - bool IsString() override {return true;} + bool IsInt64() override { return true; } + bool IsUInt64() override { return true; } + bool IsDouble() override { return true; } + bool IsString() override { return true; } void GetNull() override {} bool GetBool() override { return Get(); } @@ -69,8 +69,8 @@ class BinaryReader : public Reader { fn(*this); } - void DoMember(const char*, std::function fn) override { - fn(*this); + void Member(const char*, std::function fn) override { + fn(); } }; diff --git a/src/serializers/json.h b/src/serializers/json.h index d4f25f489..b5c84c04b 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -51,13 +51,13 @@ class JsonReader : public Reader { path_.pop_back(); } - void DoMember(const char* name, std::function fn) override { + void Member(const char* name, std::function fn) override { path_.push_back(name); auto it = m_->FindMember(name); if (it != m_->MemberEnd()) { auto saved = m_; m_ = &it->value; - fn(*this); + fn(); m_ = saved; } path_.pop_back(); From b35d3c8fa81af64495748abf4a80b0ae74f6c7b5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 29 May 2018 23:56:14 -0700 Subject: [PATCH 108/378] Remove $ccls/random; remove DB::symbols; decrease DB::entities grow rate --- CMakeLists.txt | 1 - src/indexer.h | 7 +- src/message_handler.cc | 4 +- src/message_handler.h | 8 +- src/messages/ccls_base.cc | 8 +- src/messages/ccls_call_hierarchy.cc | 6 +- src/messages/ccls_inheritance_hierarchy.cc | 4 +- src/messages/ccls_member_hierarchy.cc | 8 +- src/messages/ccls_random.cc | 134 -------------- src/messages/ccls_vars.cc | 6 +- src/messages/text_document_code_lens.cc | 10 +- src/messages/text_document_definition.cc | 34 ++-- src/messages/text_document_hover.cc | 4 +- src/messages/text_document_implementation.cc | 8 +- src/messages/text_document_rename.cc | 2 +- src/messages/workspace_symbol.cc | 84 +++++---- src/pipeline.cc | 4 +- src/query.cc | 182 +++++++++---------- src/query.h | 63 ++++--- src/query_utils.cc | 88 ++++++--- src/query_utils.h | 107 ++++++----- 21 files changed, 349 insertions(+), 423 deletions(-) delete mode 100644 src/messages/ccls_random.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 52f0f269a..d3db90e07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,7 +230,6 @@ target_sources(ccls PRIVATE src/messages/ccls_freshen_index.cc src/messages/ccls_inheritance_hierarchy.cc src/messages/ccls_member_hierarchy.cc - src/messages/ccls_random.cc src/messages/ccls_vars.cc src/messages/exit.cc src/messages/initialize.cc diff --git a/src/indexer.h b/src/indexer.h index d79cd66e5..6921a8dd3 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -64,7 +64,7 @@ struct SymbolRef : Reference { : Reference{range, usr, kind, role} {} }; -// Represents an occurrence of a variable/type, |id,kind| refer to the lexical +// Represents an occurrence of a variable/type, |usr,kind| refer to the lexical // parent. struct Use : Reference { // |file| is used in Query* but not in Index* @@ -239,7 +239,10 @@ struct VarDef : NameMixin { // (declaration). StorageClass storage = StorageClass::Invalid; - bool is_local() const { return kind == lsSymbolKind::Variable; } + bool is_local() const { + return spell && spell->kind != SymbolKind::File && + storage == StorageClass::None; + } std::vector GetBases() const { return {}; } bool operator==(const VarDef& o) const { diff --git a/src/message_handler.cc b/src/message_handler.cc index cd7915e5b..ab8719003 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -125,7 +125,7 @@ MessageHandler::MessageHandler() { // static std::vector* MessageHandler::message_handlers = nullptr; -bool FindFileOrFail(QueryDatabase* db, +bool FindFileOrFail(DB* db, Project* project, std::optional id, const std::string& absolute_path, @@ -186,7 +186,7 @@ void EmitInactiveLines(WorkingFile* working_file, pipeline::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); } -void EmitSemanticHighlighting(QueryDatabase* db, +void EmitSemanticHighlighting(DB* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFile* working_file, QueryFile* file) { diff --git a/src/message_handler.h b/src/message_handler.h index d836c8737..f73dc4831 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -20,7 +20,7 @@ struct ImportManager; struct IncludeComplete; struct MultiQueueWaiter; struct Project; -struct QueryDatabase; +struct DB; struct WorkingFile; struct WorkingFiles; @@ -101,7 +101,7 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, static type type##message_handler_instance_; struct MessageHandler { - QueryDatabase* db = nullptr; + DB* db = nullptr; MultiQueueWaiter* waiter = nullptr; Project* project = nullptr; DiagnosticsEngine* diag_engine = nullptr; @@ -134,7 +134,7 @@ struct BaseMessageHandler : MessageHandler { } }; -bool FindFileOrFail(QueryDatabase* db, +bool FindFileOrFail(DB* db, Project* project, std::optional id, const std::string& absolute_path, @@ -144,7 +144,7 @@ bool FindFileOrFail(QueryDatabase* db, void EmitInactiveLines(WorkingFile* working_file, const std::vector& inactive_regions); -void EmitSemanticHighlighting(QueryDatabase* db, +void EmitSemanticHighlighting(DB* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFile* working_file, QueryFile* file); diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index fa04a498e..dc29162bc 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -34,13 +34,13 @@ struct Handler_CclsBase : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { if (const auto* def = db->GetType(sym).AnyDef()) - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db->usr2type, def->bases)); + out.result = GetLsLocationExs(db, working_files, + GetTypeDeclarations(db, def->bases)); break; } else if (sym.kind == SymbolKind::Func) { if (const auto* def = db->GetFunc(sym).AnyDef()) - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db->usr2func, def->bases)); + out.result = GetLsLocationExs(db, working_files, + GetFuncDeclarations(db, def->bases)); break; } } diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 2911d75da..bff5ca84b 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -136,7 +136,7 @@ bool Expand(MessageHandler* m, const QueryFunc& func1 = *stack.back(); stack.pop_back(); if (auto* def1 = func1.AnyDef()) { - EachDefinedEntity(m->db->usr2func, def1->bases, [&](QueryFunc& func2) { + EachDefinedFunc(m->db, def1->bases, [&](QueryFunc& func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -153,7 +153,7 @@ bool Expand(MessageHandler* m, while (stack.size()) { const QueryFunc& func1 = *stack.back(); stack.pop_back(); - EachDefinedEntity(m->db->usr2func, func1.derived, [&](QueryFunc& func2) { + EachDefinedFunc(m->db, func1.derived, [&](QueryFunc& func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -206,7 +206,7 @@ struct Handler_CclsCallHierarchy entry.id = std::to_string(params.usr); entry.usr = params.usr; entry.callType = CallType::Direct; - if (db->usr2func.count(params.usr)) + if (db->HasFunc(params.usr)) Expand(this, &entry, params.callee, params.callType, params.qualified, params.levels); out.result = std::move(entry); diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index c6fccaff9..3d477fa60 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -169,8 +169,8 @@ struct Handler_CclsInheritanceHierarchy entry.id = std::to_string(params.usr); entry.usr = params.usr; entry.kind = params.kind; - if (((entry.kind == SymbolKind::Func && db->usr2func.count(entry.usr)) || - (entry.kind == SymbolKind::Type && db->usr2type.count(entry.usr))) && + if (((entry.kind == SymbolKind::Func && db->HasFunc(entry.usr)) || + (entry.kind == SymbolKind::Type && db->HasType(entry.usr))) && Expand(this, &entry, params.derived, params.qualified, params.levels)) out.result = std::move(entry); } else { diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 6cc9b7550..9fa7cd6eb 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -138,7 +138,7 @@ bool Expand(MessageHandler* m, const auto* def = stack.back()->AnyDef(); stack.pop_back(); if (def) { - EachDefinedEntity(m->db->usr2type, def->bases, [&](QueryType& type1) { + EachDefinedType(m->db, def->bases, [&](QueryType& type1) { if (!seen.count(type1.usr)) { seen.insert(type1.usr); stack.push_back(&type1); @@ -171,7 +171,7 @@ bool Expand(MessageHandler* m, } } else { for (auto it : def->vars) { - QueryVar& var = m->db->usr2var[it.first]; + QueryVar& var = m->db->Var(it.first); if (!var.def.empty()) DoField(m, entry, var, it.second, qualified, levels - 1); } @@ -208,7 +208,7 @@ struct Handler_CclsMemberHierarchy GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) { + EachDefinedVar(db, def->vars, [&](QueryVar& var) { DoField(this, &entry, var, -1, qualified, levels - 1); }); return entry; @@ -247,7 +247,7 @@ struct Handler_CclsMemberHierarchy entry.id = std::to_string(params.usr); entry.usr = params.usr; // entry.name is empty as it is known by the client. - if (db->usr2type.count(entry.usr) && + if (db->HasType(entry.usr) && Expand(this, &entry, params.qualified, params.levels)) out.result = std::move(entry); } else { diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc deleted file mode 100644 index a5fabdb2e..000000000 --- a/src/messages/ccls_random.cc +++ /dev/null @@ -1,134 +0,0 @@ -#include "message_handler.h" -#include "query_utils.h" -#include "pipeline.hh" -using namespace ccls; - -#include -#include -#include - -MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); - -namespace { -MethodType kMethodType = "$ccls/random"; - -struct In_CclsRandom : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } -}; -MAKE_REFLECT_STRUCT(In_CclsRandom, id); -REGISTER_IN_MESSAGE(In_CclsRandom); - -const double kDeclWeight = 3; -const double kDamping = 0.1; - -template -void Add(const std::unordered_map& sym2id, - std::vector>& adj, - const std::vector& collection, - int n, - double w = 1) { - for (Usr usr : collection) { - auto it = sym2id.find(SymbolIdx{usr, Q}); - if (it != sym2id.end()) - adj[it->second][n] += w; - } -} - -struct Handler_CclsRandom : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_CclsRandom* request) override { - std::unordered_map sym2id; - std::vector syms; - int n = 0; - - for (auto& it : db->usr2func) - if (it.second.AnyDef()) { - syms.push_back(SymbolIdx{it.first, SymbolKind::Func}); - sym2id[syms.back()] = n++; - } - for (auto& it : db->usr2type) - if (it.second.AnyDef()) { - syms.push_back(SymbolIdx{it.first, SymbolKind::Type}); - sym2id[syms.back()] = n++; - } - for (auto& it : db->usr2var) - if (it.second.AnyDef()) { - syms.push_back(SymbolIdx{it.first, SymbolKind::Var}); - sym2id[syms.back()] = n++; - } - - std::vector> adj(n); - auto add = [&](const std::vector& uses, double w) { - for (Use use : uses) { - auto it = sym2id.find(use); - if (it != sym2id.end()) - adj[it->second][n] += w; - } - }; - n = 0; - for (auto& it : db->usr2func) - if (it.second.AnyDef()) { - add(it.second.declarations, kDeclWeight); - add(it.second.uses, 1); - Add(sym2id, adj, it.second.derived, n); - n++; - } - for (auto& it : db->usr2type) - if (const auto* def = it.second.AnyDef()) { - add(it.second.uses, 1); - Add(sym2id, adj, it.second.instances, n); - Add(sym2id, adj, def->funcs, n); - Add(sym2id, adj, def->types, n); - //Add(sym2id, adj, def->vars, n); - n++; - } - for (auto& it : db->usr2var) - if (it.second.AnyDef()) { - add(it.second.declarations, kDeclWeight); - add(it.second.uses, 1); - n++; - } - for (int i = 0; i < n; i++) { - double sum = 0; - adj[i][i] += 1; - for (auto& it : adj[i]) - sum += it.second; - for (auto& it : adj[i]) - it.second = it.second / sum * (1 - kDamping); - } - - std::vector x(n, 1), y; - for (int j = 0; j < 8; j++) { - y.assign(n, kDamping); - for (int i = 0; i < n; i++) - for (auto& it : adj[i]) - y[it.first] += x[i] * it.second; - double d = 0; - for (int i = 0; i < n; i++) - d = std::max(d, fabs(x[i] - y[i])); - if (d < 1e-5) - break; - x.swap(y); - } - - double sum = std::accumulate(x.begin(), x.end(), 0.); - Out_LocationList out; - out.id = request->id; - double roulette = rand() / (RAND_MAX + 1.0) * sum; - sum = 0; - for (int i = 0; i < n; i++) { - sum += x[i]; - if (sum >= roulette) { - if (Maybe use = GetDefinitionExtent(db, syms[i])) - if (auto ls_loc = GetLsLocationEx(db, working_files, *use, - g_config->xref.container)) - out.result.push_back(*ls_loc); - break; - } - } - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsRandom); -} // namespace diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 31e0c7790..95d8ff91e 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -43,9 +43,9 @@ struct Handler_CclsVars : BaseMessageHandler { [[fallthrough]]; } case SymbolKind::Type: - out.result = GetLsLocationExs( - db, working_files, - GetDeclarations(db->usr2var, db->Type(usr).instances)); + out.result = + GetLsLocationExs(db, working_files, + GetVarDeclarations(db, db->Type(usr).instances)); break; } } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index a5b32fb65..0691ac30e 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -31,7 +31,7 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result); struct CommonCodeLensParams { std::vector* result; - QueryDatabase* db; + DB* db; WorkingFiles* working_files; WorkingFile* working_file; }; @@ -118,10 +118,10 @@ struct Handler_TextDocumentCodeLens AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), type.uses, true /*force_display*/); AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), - GetDeclarations(db->usr2type, type.derived), + GetTypeDeclarations(db, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetDeclarations(db->usr2var, type.instances), + GetVarDeclarations(db, type.instances), false /*force_display*/); break; } @@ -168,7 +168,7 @@ struct Handler_TextDocumentCodeLens AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, offset++), - GetDeclarations(db->usr2func, func.derived), + GetFuncDeclarations(db, func.derived), false /*force_display*/); // "Base" @@ -196,7 +196,7 @@ struct Handler_TextDocumentCodeLens } } else { AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), - GetDeclarations(db->usr2type, def->bases), + GetTypeDeclarations(db, def->bases), false /*force_display*/); } diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 80aaf9a15..b65682a5d 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -25,7 +25,7 @@ struct Out_TextDocumentDefinition }; MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); -std::vector GetNonDefDeclarationTargets(QueryDatabase* db, SymbolRef sym) { +std::vector GetNonDefDeclarationTargets(DB* db, SymbolRef sym) { switch (sym.kind) { case SymbolKind::Var: { std::vector ret = GetNonDefDeclarations(db, sym); @@ -135,18 +135,16 @@ struct Handler_TextDocumentDefinition // substring, we use the tuple to find the best match. std::tuple best_score{INT_MAX, 0, true, 0}; - int best_i = -1; - for (int i = 0; i < (int)db->symbols.size(); ++i) { - if (db->symbols[i].kind == SymbolKind::Invalid) - continue; - - std::string_view short_name = db->GetSymbolName(i, false), + SymbolIdx best_sym; + best_sym.kind = SymbolKind::Invalid; + auto fn = [&](SymbolIdx sym) { + std::string_view short_name = db->GetSymbolName(sym, false), name = short_query.size() < query.size() - ? db->GetSymbolName(i, true) + ? db->GetSymbolName(sym, true) : short_name; if (short_name != short_query) - continue; - if (Maybe use = GetDefinitionSpell(db, db->symbols[i])) { + return; + if (Maybe use = GetDefinitionSpell(db, sym)) { std::tuple score{ int(name.size() - short_query.size()), 0, use->file_id != file_id, @@ -160,12 +158,20 @@ struct Handler_TextDocumentDefinition } if (score < best_score) { best_score = score; - best_i = i; + best_sym = sym; } } - } - if (best_i != -1) { - Maybe use = GetDefinitionSpell(db, db->symbols[best_i]); + }; + for (auto& func : db->funcs) + fn({func.usr, SymbolKind::Func}); + for (auto& type : db->types) + fn({type.usr, SymbolKind::Type}); + for (auto& var : db->vars) + if (var.def.size() && !var.def[0].is_local()) + fn({var.usr, SymbolKind::Var}); + + if (best_sym.kind != SymbolKind::Invalid) { + Maybe use = GetDefinitionSpell(db, best_sym); assert(use); if (auto ls_loc = GetLsLocationEx(db, working_files, *use, g_config->xref.container)) diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index f3f282186..043953d34 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -7,7 +7,7 @@ namespace { MethodType kMethodType = "textDocument/hover"; // Find the comments for |sym|, if any. -std::optional GetComments(QueryDatabase* db, SymbolRef sym) { +std::optional GetComments(DB* db, SymbolRef sym) { std::optional ret; WithEntity(db, sym, [&](const auto& entity) { if (const auto* def = entity.AnyDef()) @@ -21,7 +21,7 @@ std::optional GetComments(QueryDatabase* db, SymbolRef sym) { } // Returns the hover or detailed name for `sym`, if any. -std::optional GetHoverOrName(QueryDatabase* db, +std::optional GetHoverOrName(DB* db, LanguageId lang, SymbolRef sym) { std::optional ret; diff --git a/src/messages/text_document_implementation.cc b/src/messages/text_document_implementation.cc index 8c10fbacf..56bf2f233 100644 --- a/src/messages/text_document_implementation.cc +++ b/src/messages/text_document_implementation.cc @@ -32,13 +32,13 @@ struct Handler_TextDocumentImplementation FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { QueryType& type = db->GetType(sym); - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db->usr2type, type.derived)); + out.result = GetLsLocationExs(db, working_files, + GetTypeDeclarations(db, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); - out.result = GetLsLocationExs( - db, working_files, GetDeclarations(db->usr2func, func.derived)); + out.result = GetLsLocationExs(db, working_files, + GetFuncDeclarations(db, func.derived)); break; } } diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index 6e2844bbc..096b79b91 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -6,7 +6,7 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/rename"; -lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, +lsWorkspaceEdit BuildWorkspaceEdit(DB* db, WorkingFiles* working_files, SymbolRef sym, const std::string& new_text) { diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index d9e88dca8..2515b1fc6 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -15,22 +15,21 @@ MethodType kMethodType = "workspace/symbol"; // Lookup |symbol| in |db| and insert the value into |result|. bool AddSymbol( - QueryDatabase* db, + DB* db, WorkingFiles* working_files, - int i, + SymbolIdx sym, bool use_detailed, - std::vector>* result) { - SymbolIdx symbol = db->symbols[i]; + std::vector>* result) { std::optional info = - GetSymbolInfo(db, working_files, symbol, true); + GetSymbolInfo(db, working_files, sym, true); if (!info) return false; Use loc; - if (Maybe location = GetDefinitionExtent(db, symbol)) + if (Maybe location = GetDefinitionExtent(db, sym)) loc = *location; else { - auto decls = GetNonDefDeclarations(db, symbol); + auto decls = GetNonDefDeclarations(db, sym); if (decls.empty()) return false; loc = decls[0]; @@ -40,7 +39,7 @@ bool AddSymbol( if (!ls_location) return false; info->location = *ls_location; - result->emplace_back(*info, use_detailed, i); + result->emplace_back(*info, int(use_detailed), sym); return true; } @@ -72,7 +71,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { std::string query = request->params.query; // {symbol info, matching detailed_name or short_name, index} - std::vector> unsorted; + std::vector> cands; bool sensitive = g_config->workspaceSymbol.caseSensitivity; // Find subsequence matches. @@ -82,47 +81,52 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { if (!isspace(c)) query_without_space += c; - for (int i = 0; i < (int)db->symbols.size(); ++i) { - std::string_view detailed_name = db->GetSymbolName(i, true); + auto Add = [&](SymbolIdx sym) { + std::string_view detailed_name = db->GetSymbolName(sym, true); int pos = ReverseSubseqMatch(query_without_space, detailed_name, sensitive); - if (pos >= 0 && - AddSymbol(db, working_files, i, - detailed_name.find(':', pos) != std::string::npos, - &unsorted) && - unsorted.size() >= g_config->workspaceSymbol.maxNum) - break; - } + return pos >= 0 && + AddSymbol(db, working_files, sym, + detailed_name.find(':', pos) != std::string::npos, + &cands) && + cands.size() >= g_config->workspaceSymbol.maxNum; + }; + for (auto& func : db->funcs) + if (Add({func.usr, SymbolKind::Func})) + goto done_add; + for (auto& type : db->types) + if (Add({type.usr, SymbolKind::Type})) + goto done_add; + for (auto& var : db->vars) + if (var.def.size() && !var.def[0].is_local() && + Add({var.usr, SymbolKind::Var})) + goto done_add; + done_add: if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { // Sort results with a fuzzy matching algorithm. int longest = 0; - for (int i = 0; i < int(unsorted.size()); i++) { + for (auto& cand : cands) longest = std::max( - longest, - int(db->GetSymbolName(std::get<2>(unsorted[i]), true).size())); - } + longest, int(db->GetSymbolName(std::get<2>(cand), true).size())); FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); - std::vector> permutation(unsorted.size()); - for (int i = 0; i < int(unsorted.size()); i++) { - permutation[i] = { - fuzzy.Match(db->GetSymbolName(std::get<2>(unsorted[i]), - std::get<1>(unsorted[i]))), - i}; + for (auto& cand : cands) + std::get<1>(cand) = fuzzy.Match( + db->GetSymbolName(std::get<2>(cand), std::get<1>(cand))); + std::sort(cands.begin(), cands.end(), [](const auto& l, const auto& r) { + return std::get<1>(l) > std::get<1>(r); + }); + out.result.reserve(cands.size()); + for (auto& cand: cands) { + // Discard awful candidates. + if (std::get<1>(cand) <= FuzzyMatcher::kMinScore) + break; + out.result.push_back(std::get<0>(cand)); } - std::sort(permutation.begin(), permutation.end(), - std::greater>()); - out.result.reserve(unsorted.size()); - // Discard awful candidates. - for (int i = 0; i < int(unsorted.size()) && - permutation[i].first > FuzzyMatcher::kMinScore; - i++) - out.result.push_back( - std::move(std::get<0>(unsorted[permutation[i].second]))); } else { - out.result.reserve(unsorted.size()); - for (auto& entry : unsorted) - out.result.push_back(std::get<0>(entry)); + out.result.reserve(cands.size()); + for (auto& cand : cands) + out.result.push_back(std::get<0>(cand)); } pipeline::WriteStdout(kMethodType, out); diff --git a/src/pipeline.cc b/src/pipeline.cc index 1b06cca79..d65b1db5d 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -299,7 +299,7 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, indexer_waiter->Wait(index_request); } -void Main_OnIndexed(QueryDatabase* db, +void Main_OnIndexed(DB* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, Index_OnIndexed* response) { @@ -431,7 +431,7 @@ void MainLoop() { auto global_code_complete_cache = std::make_unique(); auto non_global_code_complete_cache = std::make_unique(); auto signature_cache = std::make_unique(); - QueryDatabase db; + DB db; // Setup shared references. for (MessageHandler* handler : *MessageHandler::message_handlers) { diff --git a/src/query.cc b/src/query.cc index 256d5fa3c..c221c3f82 100644 --- a/src/query.cc +++ b/src/query.cc @@ -14,7 +14,7 @@ #include #include -// Used by |HANDLE_MERGEABLE| so only |range| is needed. +// Used by |REMOVE_ADD| so only |range| is needed. MAKE_HASHABLE(Use, t.range, t.file_id); namespace { @@ -178,6 +178,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.files_def_update = BuildFileDefUpdate(std::move(*current)); + r.funcs_hint = current->usr2func.size() - previous->usr2func.size(); for (auto& it : previous->usr2func) { auto& func = it.second; if (func.def.spell) @@ -195,6 +196,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.funcs_derived[func.usr].second = std::move(func.derived); } + r.types_hint = current->usr2type.size() - previous->usr2type.size(); for (auto& it : previous->usr2type) { auto& type = it.second; if (type.def.spell) @@ -214,6 +216,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.types_instances[type.usr].second = std::move(type.instances); }; + r.vars_hint = current->usr2var.size() - previous->usr2var.size(); for (auto& it : previous->usr2var) { auto& var = it.second; if (var.def.spell) @@ -232,34 +235,14 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, return r; } -// ------------------------ -// QUERYDB THREAD FUNCTIONS -// ------------------------ - -void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, - const std::vector& to_remove) { - switch (usr_kind) { - case SymbolKind::Type: { - for (Usr usr : to_remove) { - QueryType& type = usr2type[usr]; - if (type.symbol_idx >= 0) - symbols[type.symbol_idx].kind = SymbolKind::Invalid; - type.def.clear(); - } - break; - } - default: - break; - } -} - -void QueryDatabase::RemoveUsrs( - SymbolKind kind, - int file_id, - const std::vector& to_remove) { +void DB::RemoveUsrs(SymbolKind kind, + int file_id, + const std::vector& to_remove) { switch (kind) { case SymbolKind::Func: { - for (auto usr : to_remove) { + for (Usr usr : to_remove) { + // FIXME + if (!HasFunc(usr)) continue; QueryFunc& func = Func(usr); auto it = llvm::find_if(func.def, [=](const QueryFunc::Def& def) { return def.spell->file_id == file_id; @@ -269,8 +252,23 @@ void QueryDatabase::RemoveUsrs( } break; } + case SymbolKind::Type: { + for (Usr usr : to_remove) { + // FIXME + if (!HasType(usr)) continue; + QueryType& type = Type(usr); + auto it = llvm::find_if(type.def, [=](const QueryType::Def& def) { + return def.spell->file_id == file_id; + }); + if (it != type.def.end()) + type.def.erase(it); + } + break; + } case SymbolKind::Var: { - for (auto usr : to_remove) { + for (Usr usr : to_remove) { + // FIXME + if (!HasVar(usr)) continue; QueryVar& var = Var(usr); auto it = llvm::find_if(var.def, [=](const QueryVar::Def& def) { return def.spell->file_id == file_id; @@ -281,26 +279,21 @@ void QueryDatabase::RemoveUsrs( break; } default: - assert(false); break; } } -void QueryDatabase::ApplyIndexUpdate(IndexUpdate* u) { -// This function runs on the querydb thread. - -// Example types: -// storage_name => std::vector> -// merge_update => QueryType::DerivedUpdate => -// MergeableUpdate def => QueryType -// def->def_var_name => std::vector -#define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \ - for (auto& it : u->update_var_name) { \ - auto& entity = storage_name[it.first]; \ - AssignFileId(u->file_id, it.second.first); \ - RemoveRange(entity.def_var_name, it.second.first); \ - AssignFileId(u->file_id, it.second.second); \ - AddRange(u->file_id, entity.def_var_name, it.second.second); \ +void DB::ApplyIndexUpdate(IndexUpdate* u) { +#define REMOVE_ADD(C, F) \ + for (auto& it : u->C##s_##F) { \ + auto R = C##_usr.try_emplace({it.first}, C##_usr.size()); \ + if (R.second) \ + C##s.emplace_back().usr = it.first; \ + auto& entity = C##s[R.first->second]; \ + AssignFileId(u->file_id, it.second.first); \ + RemoveRange(entity.F, it.second.first); \ + AssignFileId(u->file_id, it.second.second); \ + AddRange(u->file_id, entity.F, it.second.second); \ } if (u->files_removed) @@ -308,101 +301,108 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* u) { std::nullopt; u->file_id = u->files_def_update ? Update(std::move(*u->files_def_update)) : -1; + const double grow = 1.3; + size_t t; + + if ((t = funcs.size() + u->funcs_hint) > funcs.capacity()) { + t = size_t(t * grow); + funcs.reserve(t); + func_usr.reserve(t); + } RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); Update(u->file_id, std::move(u->funcs_def_update)); - HANDLE_MERGEABLE(funcs_declarations, declarations, usr2func); - HANDLE_MERGEABLE(funcs_derived, derived, usr2func); - HANDLE_MERGEABLE(funcs_uses, uses, usr2func); - - RemoveUsrs(SymbolKind::Type, u->types_removed); + REMOVE_ADD(func, declarations); + REMOVE_ADD(func, derived); + REMOVE_ADD(func, uses); + + if ((t = types.size() + u->types_hint) > types.capacity()) { + t = size_t(t * grow); + types.reserve(t); + type_usr.reserve(t); + } + RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); Update(u->file_id, std::move(u->types_def_update)); - HANDLE_MERGEABLE(types_declarations, declarations, usr2type); - HANDLE_MERGEABLE(types_derived, derived, usr2type); - HANDLE_MERGEABLE(types_instances, instances, usr2type); - HANDLE_MERGEABLE(types_uses, uses, usr2type); - + REMOVE_ADD(type, declarations); + REMOVE_ADD(type, derived); + REMOVE_ADD(type, instances); + REMOVE_ADD(type, uses); + + if ((t = vars.size() + u->vars_hint) > vars.capacity()) { + t = size_t(t * grow); + vars.reserve(t); + var_usr.reserve(t); + } RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(u->file_id, std::move(u->vars_def_update)); - HANDLE_MERGEABLE(vars_declarations, declarations, usr2var); - HANDLE_MERGEABLE(vars_uses, uses, usr2var); + REMOVE_ADD(var, declarations); + REMOVE_ADD(var, uses); -#undef HANDLE_MERGEABLE +#undef REMOVE_ADD } -int QueryDatabase::Update(QueryFile::DefUpdate&& u) { +int DB::Update(QueryFile::DefUpdate&& u) { int id = files.size(); auto it = name2file_id.try_emplace(LowerPathIfInsensitive(u.value.path), id); if (it.second) files.emplace_back().id = id; QueryFile& existing = files[it.first->second]; existing.def = u.value; - UpdateSymbols(&existing.symbol_idx, SymbolKind::File, it.first->second); return existing.id; } -void QueryDatabase::Update(int file_id, - std::vector>&& us) { +void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); AssignFileId(file_id, def.callees); - QueryFunc& existing = Func(u.first); + auto R = func_usr.try_emplace({u.first}, func_usr.size()); + if (R.second) + funcs.emplace_back(); + QueryFunc& existing = funcs[R.first->second]; existing.usr = u.first; - if (!TryReplaceDef(existing.def, std::move(def))) { + if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, u.first); - } } } -void QueryDatabase::Update(int file_id, - std::vector>&& us) { +void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); - QueryType& existing = Type(u.first); + auto R = type_usr.try_emplace({u.first}, type_usr.size()); + if (R.second) + types.emplace_back(); + QueryType& existing = types[R.first->second]; existing.usr = u.first; - if (!TryReplaceDef(existing.def, std::move(def))) { + if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); - UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, u.first); - } + } } -void QueryDatabase::Update(int file_id, - std::vector>&& us) { +void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; assert(!def.detailed_name.empty()); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); - QueryVar& existing = Var(u.first); + auto R = var_usr.try_emplace({u.first}, var_usr.size()); + if (R.second) + vars.emplace_back(); + QueryVar& existing = vars[R.first->second]; existing.usr = u.first; - if (!TryReplaceDef(existing.def, std::move(def))) { + if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); - if (!existing.def.front().is_local()) - UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first); - } - } -} - -void QueryDatabase::UpdateSymbols(int* symbol_idx, - SymbolKind kind, - Usr usr) { - if (*symbol_idx < 0) { - *symbol_idx = symbols.size(); - symbols.push_back(SymbolIdx{usr, kind}); } } -std::string_view QueryDatabase::GetSymbolName(int symbol_idx, - bool qualified) { - Usr usr = symbols[symbol_idx].usr; - switch (symbols[symbol_idx].kind) { +std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) { + Usr usr = sym.usr; + switch (sym.kind) { default: break; case SymbolKind::File: diff --git a/src/query.h b/src/query.h index 0186e0704..d7621f1bd 100644 --- a/src/query.h +++ b/src/query.h @@ -3,13 +3,14 @@ #include "indexer.h" #include "serializer.h" +#include #include struct QueryFile; struct QueryType; struct QueryFunc; struct QueryVar; -struct QueryDatabase; +struct DB; template struct WithFileContent { @@ -41,7 +42,6 @@ struct QueryFile { int id = -1; std::optional def; - int symbol_idx = -1; }; template @@ -66,7 +66,6 @@ using UsrUpdate = struct QueryFunc : QueryEntity { Usr usr; - int symbol_idx = -1; llvm::SmallVector def; std::vector declarations; std::vector uses; @@ -75,7 +74,6 @@ struct QueryFunc : QueryEntity { struct QueryType : QueryEntity { Usr usr; - int symbol_idx = -1; llvm::SmallVector def; std::vector declarations; std::vector uses; @@ -85,7 +83,6 @@ struct QueryType : QueryEntity { struct QueryVar : QueryEntity { Usr usr; - int symbol_idx = -1; llvm::SmallVector def; std::vector declarations; std::vector uses; @@ -107,6 +104,7 @@ struct IndexUpdate { std::optional files_def_update; // Function updates. + int funcs_hint; std::vector funcs_removed; std::vector> funcs_def_update; UseUpdate funcs_declarations; @@ -114,6 +112,7 @@ struct IndexUpdate { UsrUpdate funcs_derived; // Type updates. + int types_hint; std::vector types_removed; std::vector> types_def_update; UseUpdate types_declarations; @@ -122,23 +121,42 @@ struct IndexUpdate { UsrUpdate types_instances; // Variable updates. + int vars_hint; std::vector vars_removed; std::vector> vars_def_update; UseUpdate vars_declarations; UseUpdate vars_uses; }; +template +struct EntityToIndex { + using argument_type = const Q&; + llvm::DenseMap m; + unsigned operator()(const Q& entity) const { + return m[entity.usr]; + } +}; + +struct WrappedUsr { + Usr usr; +}; +template <> +struct llvm::DenseMapInfo { + static inline WrappedUsr getEmptyKey() { return {0}; } + static inline WrappedUsr getTombstoneKey() { return {~0ULL}; } + static unsigned getHashValue(WrappedUsr w) { return w.usr; } + static bool isEqual(WrappedUsr l, WrappedUsr r) { return l.usr == r.usr; } +}; + // The query database is heavily optimized for fast queries. It is stored // in-memory. -struct QueryDatabase { - // All File/Func/Type/Var symbols. - std::vector symbols; - +struct DB { std::vector files; llvm::StringMap name2file_id; - std::unordered_map usr2func; - std::unordered_map usr2type; - std::unordered_map usr2var; + llvm::DenseMap func_usr, type_usr, var_usr; + std::vector funcs; + std::vector types; + std::vector vars; // Marks the given Usrs as invalid. void RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove); @@ -149,15 +167,18 @@ struct QueryDatabase { void Update(int file_id, std::vector>&& us); void Update(int file_id, std::vector>&& us); void Update(int file_id, std::vector>&& us); - void UpdateSymbols(int* symbol_idx, SymbolKind kind, Usr usr); - std::string_view GetSymbolName(int symbol_idx, bool qualified); + std::string_view GetSymbolName(SymbolIdx sym, bool qualified); - QueryFile& GetFile(SymbolIdx ref) { return files[ref.usr]; } - QueryFunc& GetFunc(SymbolIdx ref) { return usr2func[ref.usr]; } - QueryType& GetType(SymbolIdx ref) { return usr2type[ref.usr]; } - QueryVar& GetVar(SymbolIdx ref) { return usr2var[ref.usr]; } + bool HasFunc(Usr usr) const { return func_usr.count({usr}); } + bool HasType(Usr usr) const { return type_usr.count({usr}); } + bool HasVar(Usr usr) const { return var_usr.count({usr}); } - QueryFunc& Func(Usr usr) { return usr2func[usr]; } - QueryType& Type(Usr usr) { return usr2type[usr]; } - QueryVar& Var(Usr usr) { return usr2var[usr]; } + QueryFunc& Func(Usr usr) { return funcs[func_usr[{usr}]]; } + QueryType& Type(Usr usr) { return types[type_usr[{usr}]]; } + QueryVar& Var(Usr usr) { return vars[var_usr[{usr}]]; } + + QueryFile& GetFile(SymbolIdx ref) { return files[ref.usr]; } + QueryFunc& GetFunc(SymbolIdx ref) { return Func(ref.usr); } + QueryType& GetType(SymbolIdx ref) { return Type(ref.usr); } + QueryVar& GetVar(SymbolIdx ref) { return Var(ref.usr); } }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 04031dedd..6ffdb4af2 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -14,15 +14,36 @@ int ComputeRangeSize(const Range& range) { return range.end.column - range.start.column; } +template +std::vector GetDeclarations(llvm::DenseMap& entity_usr, + std::vector& entities, + const std::vector& usrs) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + Q& entity = entities[entity_usr[{usr}]]; + bool has_def = false; + for (auto& def : entity.def) + if (def.spell) { + ret.push_back(*def.spell); + has_def = true; + break; + } + if (!has_def && entity.declarations.size()) + ret.push_back(entity.declarations[0]); + } + return ret; +} + } // namespace -Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym) { +Maybe GetDefinitionSpell(DB* db, SymbolIdx sym) { Maybe ret; EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.spell); }); return ret; } -Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym) { +Maybe GetDefinitionExtent(DB* db, SymbolIdx sym) { // Used to jump to file. if (sym.kind == SymbolKind::File) return Use{{Range{{0, 0}, {0, 0}}, sym.usr, sym.kind, Role::None}, @@ -32,7 +53,17 @@ Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym) { return ret; } -std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym) { +std::vector GetFuncDeclarations(DB* db, const std::vector& usrs) { + return GetDeclarations(db->func_usr, db->funcs, usrs); +} +std::vector GetTypeDeclarations(DB* db, const std::vector& usrs) { + return GetDeclarations(db->type_usr, db->types, usrs); +} +std::vector GetVarDeclarations(DB* db, const std::vector& usrs) { + return GetDeclarations(db->var_usr, db->vars, usrs); +} + +std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym) { switch (sym.kind) { case SymbolKind::Func: return db->GetFunc(sym).declarations; @@ -45,7 +76,7 @@ std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym) { } } -std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root) { +std::vector GetUsesForAllBases(DB* db, QueryFunc& root) { std::vector ret; std::vector stack{&root}; std::unordered_set seen; @@ -54,7 +85,7 @@ std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root) { QueryFunc& func = *stack.back(); stack.pop_back(); if (auto* def = func.AnyDef()) { - EachDefinedEntity(db->usr2func, def->bases, [&](QueryFunc& func1) { + EachDefinedFunc(db, def->bases, [&](QueryFunc& func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -67,7 +98,7 @@ std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root) { return ret; } -std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { +std::vector GetUsesForAllDerived(DB* db, QueryFunc& root) { std::vector ret; std::vector stack{&root}; std::unordered_set seen; @@ -75,7 +106,7 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { while (!stack.empty()) { QueryFunc& func = *stack.back(); stack.pop_back(); - EachDefinedEntity(db->usr2func, func.derived, [&](QueryFunc& func1) { + EachDefinedFunc(db, func.derived, [&](QueryFunc& func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -88,7 +119,7 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { } std::optional GetLsPosition(WorkingFile* working_file, - const Position& position) { + const Position& position) { if (!working_file) return lsPosition{position.line, position.column}; @@ -99,7 +130,8 @@ std::optional GetLsPosition(WorkingFile* working_file, return std::nullopt; } -std::optional GetLsRange(WorkingFile* working_file, const Range& location) { +std::optional GetLsRange(WorkingFile* working_file, + const Range& location) { if (!working_file) { return lsRange{lsPosition{location.start.line, location.start.column}, lsPosition{location.end.line, location.end.column}}; @@ -108,8 +140,8 @@ std::optional GetLsRange(WorkingFile* working_file, const Range& locati int start_column = location.start.column, end_column = location.end.column; std::optional start = working_file->GetBufferPosFromIndexPos( location.start.line, &start_column, false); - std::optional end = working_file->GetBufferPosFromIndexPos(location.end.line, - &end_column, true); + std::optional end = working_file->GetBufferPosFromIndexPos( + location.end.line, &end_column, true); if (!start || !end) return std::nullopt; @@ -128,9 +160,7 @@ std::optional GetLsRange(WorkingFile* working_file, const Range& locati lsPosition{*end, end_column}}; } -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, - int file_id, - std::string* path) { +lsDocumentUri GetLsDocumentUri(DB* db, int file_id, std::string* path) { QueryFile& file = db->files[file_id]; if (file.def) { *path = file.def->path; @@ -141,7 +171,7 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, } } -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, int file_id) { +lsDocumentUri GetLsDocumentUri(DB* db, int file_id) { QueryFile& file = db->files[file_id]; if (file.def) { return lsDocumentUri::FromPath(file.def->path); @@ -150,9 +180,9 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, int file_id) { } } -std::optional GetLsLocation(QueryDatabase* db, - WorkingFiles* working_files, - Use use) { +std::optional GetLsLocation(DB* db, + WorkingFiles* working_files, + Use use) { std::string path; lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); std::optional range = @@ -162,10 +192,10 @@ std::optional GetLsLocation(QueryDatabase* db, return lsLocation{uri, *range}; } -std::optional GetLsLocationEx(QueryDatabase* db, - WorkingFiles* working_files, - Use use, - bool container) { +std::optional GetLsLocationEx(DB* db, + WorkingFiles* working_files, + Use use, + bool container) { std::optional ls_loc = GetLsLocation(db, working_files, use); if (!ls_loc) return std::nullopt; @@ -181,7 +211,7 @@ std::optional GetLsLocationEx(QueryDatabase* db, return ret; } -std::vector GetLsLocationExs(QueryDatabase* db, +std::vector GetLsLocationExs(DB* db, WorkingFiles* working_files, const std::vector& uses) { std::vector ret; @@ -196,7 +226,7 @@ std::vector GetLsLocationExs(QueryDatabase* db, return ret; } -lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym) { +lsSymbolKind GetSymbolKind(DB* db, SymbolIdx sym) { lsSymbolKind ret; if (sym.kind == SymbolKind::File) ret = lsSymbolKind::File; @@ -213,10 +243,10 @@ lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym) { } // Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(QueryDatabase* db, - WorkingFiles* working_files, - SymbolIdx sym, - bool detailed_name) { +std::optional GetSymbolInfo(DB* db, + WorkingFiles* working_files, + SymbolIdx sym, + bool detailed_name) { switch (sym.kind) { case SymbolKind::Invalid: break; @@ -254,7 +284,7 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, std::vector symbols; if (working_file) { if (auto line = working_file->GetIndexPosFromBufferPos( - ls_pos.line, &ls_pos.character, false)) { + ls_pos.line, &ls_pos.character, false)) { ls_pos.line = *line; } else { ls_pos.line = -1; diff --git a/src/query_utils.h b/src/query_utils.h index 1e65b2a3c..239738cbd 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -5,66 +5,49 @@ #include -Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym); -Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); +Maybe GetDefinitionSpell(DB* db, SymbolIdx sym); +Maybe GetDefinitionExtent(DB* db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. -template -std::vector GetDeclarations(std::unordered_map& usr2entity, - const std::vector& usrs) { - std::vector ret; - ret.reserve(usrs.size()); - for (Usr usr : usrs) { - Q& entity = usr2entity[usr]; - bool has_def = false; - for (auto& def : entity.def) - if (def.spell) { - ret.push_back(*def.spell); - has_def = true; - break; - } - if (!has_def && entity.declarations.size()) - ret.push_back(entity.declarations[0]); - } - return ret; -} +std::vector GetFuncDeclarations(DB*, const std::vector&); +std::vector GetTypeDeclarations(DB*, const std::vector&); +std::vector GetVarDeclarations(DB*, const std::vector&); // Get non-defining declarations. -std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym); +std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym); -std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root); -std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root); +std::vector GetUsesForAllBases(DB* db, QueryFunc& root); +std::vector GetUsesForAllDerived(DB* db, QueryFunc& root); std::optional GetLsPosition(WorkingFile* working_file, - const Position& position); -std::optional GetLsRange(WorkingFile* working_file, const Range& location); -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, - int file_id, - std::string* path); -lsDocumentUri GetLsDocumentUri(QueryDatabase* db, int file_id); - -std::optional GetLsLocation(QueryDatabase* db, - WorkingFiles* working_files, - Use use); -std::optional GetLsLocationEx(QueryDatabase* db, - WorkingFiles* working_files, - Use use, - bool container); -std::vector GetLsLocationExs(QueryDatabase* db, + const Position& position); +std::optional GetLsRange(WorkingFile* working_file, + const Range& location); +lsDocumentUri GetLsDocumentUri(DB* db, int file_id, std::string* path); +lsDocumentUri GetLsDocumentUri(DB* db, int file_id); + +std::optional GetLsLocation(DB* db, + WorkingFiles* working_files, + Use use); +std::optional GetLsLocationEx(DB* db, + WorkingFiles* working_files, + Use use, + bool container); +std::vector GetLsLocationExs(DB* db, WorkingFiles* working_files, const std::vector& refs); // Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(QueryDatabase* db, - WorkingFiles* working_files, - SymbolIdx sym, - bool detailed_name); +std::optional GetSymbolInfo(DB* db, + WorkingFiles* working_files, + SymbolIdx sym, + bool detailed_name); std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, lsPosition& ls_pos); template -void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { +void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) { switch (sym.kind) { case SymbolKind::Invalid: case SymbolKind::File: @@ -82,7 +65,7 @@ void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { } template -void EachEntityDef(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { +void EachEntityDef(DB* db, SymbolIdx sym, Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { for (auto& def : entity.def) if (!fn(def)) @@ -91,10 +74,7 @@ void EachEntityDef(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { } template -void EachOccurrence(QueryDatabase* db, - SymbolIdx sym, - bool include_decl, - Fn&& fn) { +void EachOccurrence(DB* db, SymbolIdx sym, bool include_decl, Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { for (Use use : entity.uses) fn(use); @@ -108,14 +88,31 @@ void EachOccurrence(QueryDatabase* db, }); } -lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym); +lsSymbolKind GetSymbolKind(DB* db, SymbolIdx sym); + +template +void EachDefinedFunc(DB* db, const std::vector& usrs, Fn&& fn) { + for (Usr usr : usrs) { + auto& obj = db->Func(usr); + if (!obj.def.empty()) + fn(obj); + } +} + + +template +void EachDefinedType(DB* db, const std::vector& usrs, Fn&& fn) { + for (Usr usr : usrs) { + auto& obj = db->Type(usr); + if (!obj.def.empty()) + fn(obj); + } +} -template -void EachDefinedEntity(std::unordered_map& collection, - const std::vector& usrs, - Fn&& fn) { +template +void EachDefinedVar(DB* db, const std::vector& usrs, Fn&& fn) { for (Usr usr : usrs) { - Q& obj = collection[usr]; + auto& obj = db->Var(usr); if (!obj.def.empty()) fn(obj); } From ec00f854a0f914de40db74154cf055ff8a967cd5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 31 May 2018 16:28:47 -0700 Subject: [PATCH 109/378] $ccls/vars: differentiate local/field/parameter --- src/messages/ccls_vars.cc | 24 ++++++++++++------- src/messages/text_document_code_lens.cc | 2 +- src/query_utils.cc | 31 +++++++++++++++++++++++-- src/query_utils.h | 2 +- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 95d8ff91e..706168453 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -8,9 +8,17 @@ MethodType kMethodType = "$ccls/vars"; struct In_CclsVars : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } - - lsTextDocumentPositionParams params; + struct Params : lsTextDocumentPositionParams { + // 1: field + // 2: local + // 4: parameter + unsigned kind = ~0u; + } params; }; +MAKE_REFLECT_STRUCT(In_CclsVars::Params, + textDocument, + position, + kind); MAKE_REFLECT_STRUCT(In_CclsVars, id, params); REGISTER_IN_MESSAGE(In_CclsVars); @@ -18,11 +26,11 @@ struct Handler_CclsVars : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_CclsVars* request) override { + auto& params = request->params; QueryFile* file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { + params.textDocument.uri.GetPath(), &file)) return; - } WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); @@ -30,7 +38,7 @@ struct Handler_CclsVars : BaseMessageHandler { Out_LocationList out; out.id = request->id; for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + FindSymbolsAtLocation(working_file, file, params.position)) { Usr usr = sym.usr; switch (sym.kind) { default: @@ -43,9 +51,9 @@ struct Handler_CclsVars : BaseMessageHandler { [[fallthrough]]; } case SymbolKind::Type: - out.result = - GetLsLocationExs(db, working_files, - GetVarDeclarations(db, db->Type(usr).instances)); + out.result = GetLsLocationExs( + db, working_files, + GetVarDeclarations(db, db->Type(usr).instances, params.kind)); break; } } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 0691ac30e..bd6704fd7 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -121,7 +121,7 @@ struct Handler_TextDocumentCodeLens GetTypeDeclarations(db, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetVarDeclarations(db, type.instances), + GetVarDeclarations(db, type.instances, true), false /*force_display*/); break; } diff --git a/src/query_utils.cc b/src/query_utils.cc index 6ffdb4af2..0ced17ba3 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -59,8 +59,35 @@ std::vector GetFuncDeclarations(DB* db, const std::vector& usrs) { std::vector GetTypeDeclarations(DB* db, const std::vector& usrs) { return GetDeclarations(db->type_usr, db->types, usrs); } -std::vector GetVarDeclarations(DB* db, const std::vector& usrs) { - return GetDeclarations(db->var_usr, db->vars, usrs); +std::vector GetVarDeclarations(DB* db, + const std::vector& usrs, + unsigned kind) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + QueryVar& var = db->Var(usr); + bool has_def = false; + for (auto& def : var.def) + if (def.spell) { + has_def = true; + // See messages/ccls_vars.cc + if (def.kind == lsSymbolKind::Field) { + if (!(kind & 1)) + break; + } else if (def.kind == lsSymbolKind::Variable) { + if (!(kind & 2)) + break; + } else if (def.kind == lsSymbolKind::Parameter) { + if (!(kind & 4)) + break; + } + ret.push_back(*def.spell); + break; + } + if (!has_def && var.declarations.size()) + ret.push_back(var.declarations[0]); + } + return ret; } std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym) { diff --git a/src/query_utils.h b/src/query_utils.h index 239738cbd..523970000 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -12,7 +12,7 @@ Maybe GetDefinitionExtent(DB* db, SymbolIdx sym); // for each id. std::vector GetFuncDeclarations(DB*, const std::vector&); std::vector GetTypeDeclarations(DB*, const std::vector&); -std::vector GetVarDeclarations(DB*, const std::vector&); +std::vector GetVarDeclarations(DB*, const std::vector&, unsigned); // Get non-defining declarations. std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym); From 39a17a9fd7f064a076addc618dde0aa43cf7acc3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 31 May 2018 20:06:09 -0700 Subject: [PATCH 110/378] Remove WithFileContent & lex_utils.{cc,h} --- CMakeLists.txt | 1 - src/indexer.cc | 13 +-- src/indexer.h | 14 --- src/lex_utils.cc | 87 ------------------- src/lex_utils.h | 16 ---- src/main.cc | 6 +- src/message_handler.cc | 1 - src/messages/text_document_completion.cc | 2 - src/messages/text_document_definition.cc | 1 - .../text_document_range_formatting.cc | 72 --------------- src/messages/workspace_symbol.cc | 1 - src/pipeline.cc | 41 +++------ src/pipeline.hh | 5 +- src/query.cc | 6 +- src/query.h | 17 +--- src/utils.cc | 18 ++++ src/utils.h | 4 + src/working_files.cc | 44 +++++++++- src/working_files.h | 5 ++ 19 files changed, 100 insertions(+), 254 deletions(-) delete mode 100644 src/lex_utils.cc delete mode 100644 src/lex_utils.h delete mode 100644 src/messages/text_document_range_formatting.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d3db90e07..fb5a8e8fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,7 +202,6 @@ target_sources(ccls PRIVATE src/indexer.cc src/method.cc src/language.cc - src/lex_utils.cc src/log.cc src/lsp.cc src/match.cc diff --git a/src/indexer.cc b/src/indexer.cc index 48dffa655..760d02a94 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -3,9 +3,11 @@ #include "log.hh" #include "platform.h" #include "serializer.h" -#include "timer.h" #include "type_printer.h" +#include +using namespace llvm; + #include #include #include @@ -2016,7 +2018,8 @@ std::vector> ClangIndexer::Index( file = NormalizePath(file); - Timer timer; + Timer timer("parse", "parse tu"); + timer.startTimer(); std::vector unsaved_files; for (const FileContents& contents : file_contents) { @@ -2034,7 +2037,7 @@ std::vector> ClangIndexer::Index( if (!tu) return {}; - perf->index_parse = timer.ElapsedMicrosecondsAndReset(); + timer.stopTimer(); return ParseWithTu(vfs, perf, tu.get(), &index, file, args, unsaved_files); } @@ -2048,6 +2051,7 @@ std::vector> ParseWithTu( const std::vector& args, const std::vector& file_contents) { Timer timer; + timer.startTimer(); IndexerCallbacks callback = {0}; // Available callbacks: @@ -2085,13 +2089,12 @@ std::vector> ParseWithTu( << " failed with errno=" << index_result; return {}; } - clang_IndexAction_dispose(index_action); ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); - perf->index_build = timer.ElapsedMicrosecondsAndReset(); + timer.stopTimer(); std::unordered_map inc_to_line; // TODO diff --git a/src/indexer.h b/src/indexer.h index 6921a8dd3..6c2465820 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -27,8 +27,6 @@ struct IndexFunc; struct IndexVar; struct QueryFile; -using RawId = uint32_t; - struct SymbolIdx { Usr usr; SymbolKind kind; @@ -153,19 +151,9 @@ struct TypeDef : NameMixin { NtString hover; NtString comments; - // While a class/type can technically have a separate declaration/definition, - // it doesn't really happen in practice. The declaration never contains - // comments or insightful information. The user always wants to jump from - // the declaration to the definition - never the other way around like in - // functions and (less often) variables. - // - // It's also difficult to identify a `class Foo;` statement with the clang - // indexer API (it's doable using cursor AST traversal), so we don't bother - // supporting the feature. Maybe spell; Maybe extent; - // Immediate parent types. std::vector bases; // Types, functions, and variables defined in this type. @@ -221,8 +209,6 @@ struct VarDef : NameMixin { std::string detailed_name; NtString hover; NtString comments; - // TODO: definitions should be a list of ranges, since there can be more - // than one - when?? Maybe spell; Maybe extent; diff --git a/src/lex_utils.cc b/src/lex_utils.cc deleted file mode 100644 index 9380f723f..000000000 --- a/src/lex_utils.cc +++ /dev/null @@ -1,87 +0,0 @@ -#include "lex_utils.h" - -#include - -#include - -// VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent -// text documents. -// We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). -// This is good enough and fails only for UTF-16 surrogate pairs. -int GetOffsetForPosition(lsPosition position, std::string_view content) { - size_t i = 0; - for (; position.line > 0 && i < content.size(); i++) - if (content[i] == '\n') - position.line--; - for (; position.character > 0 && i < content.size(); position.character--) - if (uint8_t(content[i++]) >= 128) { - // Skip 0b10xxxxxx - while (i < content.size() && uint8_t(content[i]) >= 128 && - uint8_t(content[i]) < 192) - i++; - } - return int(i); -} - -std::string_view LexIdentifierAroundPos(lsPosition position, - std::string_view content) { - int start = GetOffsetForPosition(position, content); - int end = start + 1; - char c; - - // We search for :: before the cursor but not after to get the qualifier. - for (; start > 0; start--) { - c = content[start - 1]; - if (isalnum(c) || c == '_') - ; - else if (c == ':' && start > 1 && content[start - 2] == ':') - start--; - else - break; - } - - for (; end < (int)content.size(); end++) - if (c = content[end], !(isalnum(c) || c == '_')) - break; - - return content.substr(start, end - start); -} - -// Find discontinous |search| in |content|. -// Return |found| and the count of skipped chars before found. -int ReverseSubseqMatch(std::string_view pat, - std::string_view text, - int case_sensitivity) { - if (case_sensitivity == 1) - case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0; - int j = pat.size(); - if (!j) - return text.size(); - for (int i = text.size(); i--;) - if ((case_sensitivity ? text[i] == pat[j - 1] - : tolower(text[i]) == tolower(pat[j - 1])) && - !--j) - return i; - return -1; -} - -TEST_SUITE("Offset") { - TEST_CASE("past end") { - std::string content = "foo"; - int offset = GetOffsetForPosition(lsPosition{10, 10}, content); - REQUIRE(offset <= content.size()); - } - - TEST_CASE("in middle of content") { - std::string content = "abcdefghijk"; - for (int i = 0; i < content.size(); ++i) { - int offset = GetOffsetForPosition(lsPosition{0, i}, content); - REQUIRE(i == offset); - } - } - - TEST_CASE("at end of content") { - REQUIRE(GetOffsetForPosition(lsPosition{0, 0}, "") == 0); - REQUIRE(GetOffsetForPosition(lsPosition{0, 1}, "a") == 1); - } -} diff --git a/src/lex_utils.h b/src/lex_utils.h deleted file mode 100644 index 4206a1204..000000000 --- a/src/lex_utils.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "lsp.h" - -#include -#include - -// Utility method to map |position| to an offset inside of |content|. -int GetOffsetForPosition(lsPosition position, std::string_view content); - -std::string_view LexIdentifierAroundPos(lsPosition position, - std::string_view content); - -int ReverseSubseqMatch(std::string_view pat, - std::string_view text, - int case_sensitivity); diff --git a/src/main.cc b/src/main.cc index 03936f5c7..ebb6b4888 100644 --- a/src/main.cc +++ b/src/main.cc @@ -129,12 +129,10 @@ int main(int argc, char** argv) { } } - std::unordered_map request_times; - // The thread that reads from stdin and dispatchs commands to the main thread. - pipeline::LaunchStdin(&request_times); + pipeline::LaunchStdin(); // The thread that writes responses from the main thread to stdout. - pipeline::LaunchStdout(&request_times); + pipeline::LaunchStdout(); // Main thread which also spawns indexer threads upon the "initialize" request. pipeline::MainLoop(); } diff --git a/src/message_handler.cc b/src/message_handler.cc index ab8719003..168fa605f 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -1,6 +1,5 @@ #include "message_handler.h" -#include "lex_utils.h" #include "log.hh" #include "project.h" #include "query_utils.h" diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 399986557..488f42b2b 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -7,8 +7,6 @@ #include "working_files.h" using namespace ccls; -#include "lex_utils.h" - #include namespace { diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index b65682a5d..93786c3e1 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -1,4 +1,3 @@ -#include "lex_utils.h" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc deleted file mode 100644 index 8ffe41f8e..000000000 --- a/src/messages/text_document_range_formatting.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "clang_format.h" -#include "lex_utils.h" -#include "message_handler.h" -#include "pipeline.hh" -using namespace ccls; -#include "working_files.h" - -#include - -namespace { -MethodType kMethodType = "textDocument/rangeFormatting"; - -struct lsTextDocumentRangeFormattingParams { - lsTextDocumentIdentifier textDocument; - lsRange range; - lsFormattingOptions options; -}; -MAKE_REFLECT_STRUCT(lsTextDocumentRangeFormattingParams, - textDocument, - range, - options); - -struct In_TextDocumentRangeFormatting : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentRangeFormattingParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentRangeFormatting); - -struct Out_TextDocumentRangeFormatting - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentRangeFormatting, jsonrpc, id, result); - -struct Handler_TextDocumentRangeFormatting - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentRangeFormatting* request) override { - Out_TextDocumentRangeFormatting response; - response.id = request->id; -#if USE_CLANG_CXX - QueryFile* file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile* working_file = - working_files->GetFileByFilename(file->def->path); - - int start = GetOffsetForPosition(request->params.range.start, - working_file->buffer_content), - end = GetOffsetForPosition(request->params.range.end, - working_file->buffer_content); - response.result = ConvertClangReplacementsIntoTextEdits( - working_file->buffer_content, - ClangFormatDocument(working_file, start, end, request->params.options)); -#else - LOG_S(WARNING) << "You must compile ccls with --use-clang-cxx to use " - "textDocument/rangeFormatting."; - // TODO: Fallback to execute the clang-format binary? - response.result = {}; -#endif - - pipeline::WriteStdout(kMethodType, response); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); -} // namespace diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 2515b1fc6..3b6086354 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -1,5 +1,4 @@ #include "fuzzy_match.h" -#include "lex_utils.h" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/pipeline.cc b/src/pipeline.cc index d65b1db5d..2a96e5224 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -11,10 +11,10 @@ #include "project.h" #include "query_utils.h" #include "pipeline.hh" -#include "timer.h" #include #include +#include using namespace llvm; #include @@ -237,14 +237,15 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, // Write current index to disk if requested. LOG_S(INFO) << "store index for " << path; - Timer time; { + Timer timer("write", "store index"); + timer.startTimer(); std::string cache_path = GetCachePath(path); WriteToFile(cache_path, curr->file_contents); WriteToFile(AppendSerializationFormat(cache_path), Serialize(g_config->cacheFormat, *curr)); + timer.stopTimer(); } - perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); vfs->Reset(path_to_index); if (entry.id >= 0) { @@ -255,7 +256,6 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, // Build delta update. IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); - perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; on_indexed->PushBack({std::move(update), perf}, request.is_interactive); @@ -264,15 +264,6 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, return true; } -// This function returns true if e2e timing should be displayed for the given -// MethodId. -bool ShouldDisplayMethodTiming(MethodType type) { - return - type != kMethodType_TextDocumentPublishDiagnostics && - type != kMethodType_CclsPublishInactiveRegions && - type != kMethodType_Unknown; -} - } // namespace void Init() { @@ -316,20 +307,22 @@ void Main_OnIndexed(DB* db, return; } - Timer time; + Timer timer("apply", "apply index"); + timer.startTimer(); db->ApplyIndexUpdate(&response->update); + timer.stopTimer(); // Update indexed content, inactive lines, and semantic highlighting. if (response->update.files_def_update) { auto& update = *response->update.files_def_update; - time.ResetAndPrint("apply index for " + update.value.path); + LOG_S(INFO) << "apply index for " << update.first.path; if (WorkingFile* working_file = - working_files->GetFileByFilename(update.value.path)) { + working_files->GetFileByFilename(update.first.path)) { // Update indexed content. - working_file->SetIndexContent(update.file_content); + working_file->SetIndexContent(update.second); // Inactive lines. - EmitInactiveLines(working_file, update.value.inactive_regions); + EmitInactiveLines(working_file, update.first.inactive_regions); // Semantic highlighting. int file_id = @@ -340,8 +333,8 @@ void Main_OnIndexed(DB* db, } } -void LaunchStdin(std::unordered_map* request_times) { - std::thread([request_times]() { +void LaunchStdin() { + std::thread([]() { set_thread_name("stdin"); while (true) { std::unique_ptr message; @@ -367,7 +360,6 @@ void LaunchStdin(std::unordered_map* request_times) { // Cache |method_id| so we can access it after moving |message|. MethodType method_type = message->GetMethodType(); - (*request_times)[method_type] = Timer(); on_request->PushBack(std::move(message)); @@ -379,7 +371,7 @@ void LaunchStdin(std::unordered_map* request_times) { }).detach(); } -void LaunchStdout(std::unordered_map* request_times) { +void LaunchStdout() { std::thread([=]() { set_thread_name("stdout"); @@ -391,11 +383,6 @@ void LaunchStdout(std::unordered_map* request_times) { } for (auto& message : messages) { - if (ShouldDisplayMethodTiming(message.method)) { - Timer time = (*request_times)[message.method]; - time.ResetAndPrint("[e2e] Running " + std::string(message.method)); - } - fwrite(message.content.c_str(), message.content.size(), 1, stdout); fflush(stdout); } diff --git a/src/pipeline.hh b/src/pipeline.hh index 760ac190c..f21a44c73 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -2,7 +2,6 @@ #include "method.h" #include "query.h" -#include "timer.h" #include #include @@ -17,8 +16,8 @@ struct lsBaseOutMessage; namespace ccls::pipeline { void Init(); -void LaunchStdin(std::unordered_map* request_times); -void LaunchStdout(std::unordered_map* request_times); +void LaunchStdin(); +void LaunchStdout(); void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, Project* project, diff --git a/src/query.cc b/src/query.cc index c221c3f82..5ceef975a 100644 --- a/src/query.cc +++ b/src/query.cc @@ -148,7 +148,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { return a.range.start < b.range.start; }); - return QueryFile::DefUpdate(def, indexed.file_contents); + return {std::move(def), std::move(indexed.file_contents)}; } // Returns true if an element with the same file is found. @@ -342,11 +342,11 @@ void DB::ApplyIndexUpdate(IndexUpdate* u) { int DB::Update(QueryFile::DefUpdate&& u) { int id = files.size(); - auto it = name2file_id.try_emplace(LowerPathIfInsensitive(u.value.path), id); + auto it = name2file_id.try_emplace(LowerPathIfInsensitive(u.first.path), id); if (it.second) files.emplace_back().id = id; QueryFile& existing = files[it.first->second]; - existing.def = u.value; + existing.def = u.first; return existing.id; } diff --git a/src/query.h b/src/query.h index d7621f1bd..22b3982d3 100644 --- a/src/query.h +++ b/src/query.h @@ -6,21 +6,6 @@ #include #include -struct QueryFile; -struct QueryType; -struct QueryFunc; -struct QueryVar; -struct DB; - -template -struct WithFileContent { - T value; - std::string file_content; - - WithFileContent(const T& value, const std::string& file_content) - : value(value), file_content(file_content) {} -}; - struct QueryFile { struct Def { std::string path; @@ -38,7 +23,7 @@ struct QueryFile { std::vector dependencies; }; - using DefUpdate = WithFileContent; + using DefUpdate = std::pair; int id = -1; std::optional def; diff --git a/src/utils.cc b/src/utils.cc index 68de51894..9c17c1291 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -134,6 +134,24 @@ std::optional LastWriteTime(const std::string& filename) { return Status.getLastModificationTime().time_since_epoch().count(); } +// Find discontinous |search| in |content|. +// Return |found| and the count of skipped chars before found. +int ReverseSubseqMatch(std::string_view pat, + std::string_view text, + int case_sensitivity) { + if (case_sensitivity == 1) + case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0; + int j = pat.size(); + if (!j) + return text.size(); + for (int i = text.size(); i--;) + if ((case_sensitivity ? text[i] == pat[j - 1] + : tolower(text[i]) == tolower(pat[j - 1])) && + !--j) + return i; + return -1; +} + std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; } diff --git a/src/utils.h b/src/utils.h index b1febec3c..3b3bb511f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -58,6 +58,10 @@ std::optional ReadContent(const std::string& filename); void WriteToFile(const std::string& filename, const std::string& content); std::optional LastWriteTime(const std::string& filename); +int ReverseSubseqMatch(std::string_view pat, + std::string_view text, + int case_sensitivity); + // http://stackoverflow.com/a/38140932 // // struct SomeHashKey { diff --git a/src/working_files.cc b/src/working_files.cc index cfefda8a8..d2448daf9 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -1,6 +1,5 @@ #include "working_files.h" -#include "lex_utils.h" #include "log.hh" #include "position.h" @@ -545,3 +544,46 @@ WorkingFiles::Snapshot WorkingFiles::AsSnapshot( } return result; } + +// VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent +// text documents. +// We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). +// This is good enough and fails only for UTF-16 surrogate pairs. +int GetOffsetForPosition(lsPosition position, std::string_view content) { + size_t i = 0; + for (; position.line > 0 && i < content.size(); i++) + if (content[i] == '\n') + position.line--; + for (; position.character > 0 && i < content.size(); position.character--) + if (uint8_t(content[i++]) >= 128) { + // Skip 0b10xxxxxx + while (i < content.size() && uint8_t(content[i]) >= 128 && + uint8_t(content[i]) < 192) + i++; + } + return int(i); +} + +std::string_view LexIdentifierAroundPos(lsPosition position, + std::string_view content) { + int start = GetOffsetForPosition(position, content); + int end = start + 1; + char c; + + // We search for :: before the cursor but not after to get the qualifier. + for (; start > 0; start--) { + c = content[start - 1]; + if (isalnum(c) || c == '_') + ; + else if (c == ':' && start > 1 && content[start - 2] == ':') + start--; + else + break; + } + + for (; end < (int)content.size(); end++) + if (c = content[end], !(isalnum(c) || c == '_')) + break; + + return content.substr(start, end - start); +} diff --git a/src/working_files.h b/src/working_files.h index 46e71b996..690149893 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -117,3 +117,8 @@ struct WorkingFiles { std::vector> files; std::mutex files_mutex; // Protects |files|. }; + +int GetOffsetForPosition(lsPosition position, std::string_view content); + +std::string_view LexIdentifierAroundPos(lsPosition position, + std::string_view content); From a36e548e03c7d29381dc45d6b1c5343ed324ecb2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 31 May 2018 21:21:34 -0700 Subject: [PATCH 111/378] Remove Timer and PerformanceImportFile --- CMakeLists.txt | 1 - src/clang_complete.cc | 17 ------ src/file_consumer.h | 27 --------- src/include_complete.cc | 6 +- src/indexer.cc | 8 +-- src/indexer.h | 16 +----- src/messages/ccls_freshen_index.cc | 1 - src/messages/initialize.cc | 8 +-- src/messages/text_document_completion.cc | 21 ++----- src/messages/text_document_did_open.cc | 3 +- src/messages/text_document_signature_help.cc | 2 - .../workspace_did_change_configuration.cc | 10 +--- src/pipeline.cc | 56 +++++++------------ src/platform.h | 2 - src/project.cc | 18 ------ src/query.cc | 4 +- src/test.cc | 3 +- src/timer.cc | 51 ----------------- src/timer.h | 36 ------------ 19 files changed, 40 insertions(+), 250 deletions(-) delete mode 100644 src/timer.cc delete mode 100644 src/timer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fb5a8e8fd..c021a170c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,6 @@ target_sources(ccls PRIVATE src/serializer.cc src/test.cc src/third_party_impl.cc - src/timer.cc src/type_printer.cc src/utils.cc src/working_files.cc) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f35c9429d..9e54bfa84 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -4,7 +4,6 @@ #include "filesystem.hh" #include "log.hh" #include "platform.h" -#include "timer.h" #include #include @@ -454,21 +453,17 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { true /*create_if_needed*/); std::lock_guard lock(session->completion.lock); - Timer timer; TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, &session->completion.index, false); - timer.ResetAndPrint("[complete] TryEnsureDocumentParsed"); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. if (!session->completion.tu) continue; - timer.Reset(); WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector unsaved = snapshot.AsUnsavedFiles(); - timer.ResetAndPrint("[complete] Creating WorkingFile snapshot"); unsigned const kCompleteOptions = CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeBriefComments; @@ -476,7 +471,6 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { session->completion.tu->cx_tu, session->file.filename.c_str(), request->position.line + 1, request->position.character + 1, unsaved.data(), (unsigned)unsaved.size(), kCompleteOptions); - timer.ResetAndPrint("[complete] clangCodeCompleteAt"); if (!cx_results) { request->on_complete({}, false /*is_cached_result*/); continue; @@ -487,7 +481,6 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { // parameters, as they may be expanded into multiple items ls_result.reserve(cx_results->NumResults); - timer.Reset(); for (unsigned i = 0; i < cx_results->NumResults; ++i) { CXCompletionResult& result = cx_results->Results[i]; @@ -552,10 +545,6 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { } } - timer.ResetAndPrint("[complete] Building " + - std::to_string(ls_result.size()) + - " completion results"); - request->on_complete(ls_result, false /*is_cached_result*/); // Make sure |ls_results| is destroyed before clearing |cx_results|. @@ -578,28 +567,22 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { // At this point, we must have a translation unit. Block until we have one. std::lock_guard lock(session->diagnostics.lock); - Timer timer; TryEnsureDocumentParsed( completion_manager, session, &session->diagnostics.tu, &session->diagnostics.index, false /*emit_diagnostics*/); - timer.ResetAndPrint("[diagnostics] TryEnsureDocumentParsed"); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. if (!session->diagnostics.tu) continue; - timer.Reset(); WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector unsaved = snapshot.AsUnsavedFiles(); - timer.ResetAndPrint("[diagnostics] Creating WorkingFile snapshot"); // Emit diagnostics. - timer.Reset(); session->diagnostics.tu = ClangTranslationUnit::Reparse( std::move(session->diagnostics.tu), unsaved); - timer.ResetAndPrint("[diagnostics] clang_reparseTranslationUnit"); if (!session->diagnostics.tu) { LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " << path; diff --git a/src/file_consumer.h b/src/file_consumer.h index a7f7b2716..b00a228ea 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -78,30 +78,3 @@ struct FileConsumer { std::string parse_file_; int thread_id_; }; - -// Contains timing information for the entire pipeline for importing a file -// into the querydb. -struct PerformanceImportFile { - // All units are in microseconds. - - // [indexer] clang parsing the file - uint64_t index_parse = 0; - // [indexer] build the IndexFile object from clang parse - uint64_t index_build = 0; - // [indexer] save the IndexFile to disk - uint64_t index_save_to_disk = 0; - // [indexer] loading previously cached index - uint64_t index_load_cached = 0; - // [indexer] create delta IndexUpdate object - uint64_t index_make_delta = 0; - // [querydb] update WorkingFile indexed file state - // uint64_t querydb_update_working_file = 0; - // [querydb] apply IndexUpdate - // uint64_t querydb_apply_index_update = 0; -}; -MAKE_REFLECT_STRUCT(PerformanceImportFile, - index_parse, - index_build, - index_save_to_disk, - index_load_cached, - index_make_delta); diff --git a/src/include_complete.cc b/src/include_complete.cc index 5fb6c9b1d..89c082c8e 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -4,10 +4,10 @@ #include "match.h" #include "platform.h" #include "project.h" -#include "timer.h" #include #include +#include using namespace llvm; #include @@ -108,14 +108,14 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { set_thread_name("include"); - Timer timer; + Timer timer("include", "scan include paths"); + TimeRegion region(timer); for (const std::string& dir : project_->quote_include_directories) InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); for (const std::string& dir : project_->angle_include_directories) InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/); - timer.ResetAndPrint("[perf] Scanning for includes"); is_scanning = false; }).detach(); } diff --git a/src/indexer.cc b/src/indexer.cc index 760d02a94..de393f9c4 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -664,7 +664,7 @@ void OnIndexReference_Function(IndexFile* db, case SymbolKind::Func: { IndexFunc& parent = db->ToFunc(parent_cursor.cx_cursor); parent.def.callees.push_back( - SymbolRef{loc, called.usr, SymbolKind::Func, role}); + SymbolRef{{loc, called.usr, SymbolKind::Func, role}}); called.uses.push_back(Use{{loc, parent.usr, SymbolKind::Func, role}}); break; } @@ -2011,8 +2011,7 @@ std::vector> ClangIndexer::Index( VFS* vfs, std::string file, const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) { + const std::vector& file_contents) { if (!g_config->index.enabled) return {}; @@ -2039,12 +2038,11 @@ std::vector> ClangIndexer::Index( timer.stopTimer(); - return ParseWithTu(vfs, perf, tu.get(), &index, file, args, unsaved_files); + return ParseWithTu(vfs, tu.get(), &index, file, args, unsaved_files); } std::vector> ParseWithTu( VFS* vfs, - PerformanceImportFile* perf, ClangTranslationUnit* tu, ClangIndex* index, const std::string& file, diff --git a/src/indexer.h b/src/indexer.h index 6c2465820..70619e9d7 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -21,12 +21,6 @@ #include #include -struct IndexFile; -struct IndexType; -struct IndexFunc; -struct IndexVar; -struct QueryFile; - struct SymbolIdx { Usr usr; SymbolKind kind; @@ -56,11 +50,7 @@ struct Reference { }; // |id,kind| refer to the referenced entity. -struct SymbolRef : Reference { - SymbolRef() = default; - SymbolRef(Range range, Usr usr, SymbolKind kind, Role role) - : Reference{range, usr, kind, role} {} -}; +struct SymbolRef : Reference {}; // Represents an occurrence of a variable/type, |usr,kind| refer to the lexical // parent. @@ -322,7 +312,6 @@ struct NamespaceHelper { std::vector> ParseWithTu( VFS* vfs, - PerformanceImportFile* perf, ClangTranslationUnit* tu, ClangIndex* index, const std::string& file, @@ -338,8 +327,7 @@ struct ClangIndexer { VFS* vfs, std::string file, const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf); + const std::vector& file_contents); // Note: constructing this acquires a global lock ClangIndex index; diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 6584b373a..1773b612b 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -3,7 +3,6 @@ #include "platform.h" #include "project.h" #include "pipeline.hh" -#include "timer.h" #include "working_files.h" using namespace ccls; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 7a00ca81d..4045eda8b 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -7,7 +7,6 @@ #include "platform.h" #include "project.h" #include "serializers/json.h" -#include "timer.h" #include "working_files.h" using namespace ccls; @@ -493,14 +492,11 @@ struct Handler_Initialize : BaseMessageHandler { sys::fs::create_directories(g_config->cacheDirectory + '@' + EscapeFileName(g_config->projectRoot)); - Timer time; diag_engine->Init(); semantic_cache->Init(); // Open up / load the project. project->Load(project_path); - time.ResetAndPrint("[perf] Loaded compilation entries (" + - std::to_string(project->entries.size()) + " files)"); // Start indexer threads. Start this after loading the project, as that // may take a long time. Indexer threads will emit status/progress @@ -522,10 +518,8 @@ struct Handler_Initialize : BaseMessageHandler { // files, because that takes a long time. include_complete->Rescan(); - time.Reset(); + LOG_S(INFO) << "dispatch initial index requests"; project->Index(working_files, request->id); - // We need to support multiple concurrent index processes. - time.ResetAndPrint("[perf] Dispatched initial index requests"); } }; REGISTER_MESSAGE_HANDLER(Handler_Initialize); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 488f42b2b..a35732700 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -3,10 +3,12 @@ #include "include_complete.h" #include "message_handler.h" #include "pipeline.hh" -#include "timer.h" #include "working_files.h" using namespace ccls; +#include +using namespace llvm; + #include namespace { @@ -162,21 +164,8 @@ void FilterAndSortCompletionResponse( if (!g_config->completion.filterAndSort) return; - ScopedPerfTimer timer{"FilterAndSortCompletionResponse"}; - -// Used to inject more completions. -#if false - const size_t kNumIterations = 250; - size_t size = complete_response->result.items.size(); - complete_response->result.items.reserve(size * (kNumIterations + 1)); - for (size_t iteration = 0; iteration < kNumIterations; ++iteration) { - for (size_t i = 0; i < size; ++i) { - auto item = complete_response->result.items[i]; - item.label += "#" + std::to_string(iteration); - complete_response->result.items.push_back(item); - } - } -#endif + Timer timer("FilterAndSortCompletionResponse", ""); + TimeRegion region(timer); auto& items = complete_response->result.items; diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 0f45b5060..fcd937976 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -3,9 +3,8 @@ #include "message_handler.h" #include "project.h" #include "pipeline.hh" -using namespace ccls; -#include "timer.h" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didOpen"; diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index 608c4037a..0d7f056e1 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -2,7 +2,6 @@ #include "message_handler.h" #include "pipeline.hh" using namespace ccls; -#include "timer.h" #include @@ -142,7 +141,6 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { // Set signature to what we parsed from the working file. out.result.activeParameter = active_param; - Timer timer; pipeline::WriteStdout(kMethodType, out); if (!is_cached_result) { diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index 73775d426..3845b6adb 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -2,9 +2,8 @@ #include "message_handler.h" #include "project.h" #include "pipeline.hh" -using namespace ccls; -#include "timer.h" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "workspace/didChangeConfiguration"; @@ -25,15 +24,8 @@ struct Handler_WorkspaceDidChangeConfiguration : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_WorkspaceDidChangeConfiguration* request) override { - Timer time; project->Load(g_config->projectRoot); - time.ResetAndPrint("[perf] Loaded compilation entries (" + - std::to_string(project->entries.size()) + " files)"); - - time.Reset(); project->Index(working_files, lsRequestId()); - time.ResetAndPrint( - "[perf] Dispatched workspace/didChangeConfiguration index requests"); clang_complete->FlushAllSessions(); } diff --git a/src/pipeline.cc b/src/pipeline.cc index 2a96e5224..e5c1ce14b 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -26,11 +26,6 @@ struct Index_Request { lsRequestId id; }; -struct Index_OnIndexed { - IndexUpdate update; - PerformanceImportFile perf; -}; - struct Stdout_Request { MethodType method; std::string content; @@ -44,7 +39,7 @@ MultiQueueWaiter* indexer_waiter; MultiQueueWaiter* stdout_waiter; ThreadedQueue>* on_request; ThreadedQueue* index_request; -ThreadedQueue* on_indexed; +ThreadedQueue* on_indexed; ThreadedQueue* for_stdout; // Checks if |path| needs to be reparsed. This will modify cached state @@ -138,7 +133,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (request.path.empty()) { IndexUpdate dummy; dummy.refresh = true; - on_indexed->PushBack({std::move(dummy), PerformanceImportFile()}, false); + on_indexed->PushBack(std::move(dummy), false); return false; } @@ -185,17 +180,16 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, } if (reparse < 2) { - PerformanceImportFile perf; auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack({std::move(update), perf}, request.is_interactive); + on_indexed->PushBack(std::move(update), request.is_interactive); } for (const auto& dep : dependencies) if (vfs->Mark(dep.first().str(), 0, 2)) { prev = RawCacheLoad(dep.first().str()); IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack({std::move(update), perf}, request.is_interactive); + on_indexed->PushBack(std::move(update), request.is_interactive); } std::lock_guard lock(vfs->mutex); @@ -207,8 +201,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, LOG_S(INFO) << "parse " << path_to_index; - PerformanceImportFile perf; - auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}, &perf); + auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -258,7 +251,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; - on_indexed->PushBack({std::move(update), perf}, request.is_interactive); + on_indexed->PushBack(std::move(update), request.is_interactive); } return true; @@ -269,7 +262,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, void Init() { main_waiter = new MultiQueueWaiter; on_request = new ThreadedQueue>(main_waiter); - on_indexed = new ThreadedQueue(main_waiter); + on_indexed = new ThreadedQueue(main_waiter); indexer_waiter = new MultiQueueWaiter; index_request = new ThreadedQueue(indexer_waiter); @@ -293,8 +286,8 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, void Main_OnIndexed(DB* db, SemanticHighlightSymbolCache* semantic_cache, WorkingFiles* working_files, - Index_OnIndexed* response) { - if (response->update.refresh) { + IndexUpdate* update) { + if (update->refresh) { LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); for (auto& f : working_files->files) { @@ -309,26 +302,19 @@ void Main_OnIndexed(DB* db, Timer timer("apply", "apply index"); timer.startTimer(); - db->ApplyIndexUpdate(&response->update); + db->ApplyIndexUpdate(update); timer.stopTimer(); // Update indexed content, inactive lines, and semantic highlighting. - if (response->update.files_def_update) { - auto& update = *response->update.files_def_update; - LOG_S(INFO) << "apply index for " << update.first.path; + if (update->files_def_update) { + auto& def_u = *update->files_def_update; + LOG_S(INFO) << "apply index for " << def_u.first.path; if (WorkingFile* working_file = - working_files->GetFileByFilename(update.first.path)) { - // Update indexed content. - working_file->SetIndexContent(update.second); - - // Inactive lines. - EmitInactiveLines(working_file, update.first.inactive_regions); - - // Semantic highlighting. - int file_id = - db->name2file_id[LowerPathIfInsensitive(working_file->filename)]; - QueryFile* file = &db->files[file_id]; - EmitSemanticHighlighting(db, semantic_cache, working_file, file); + working_files->GetFileByFilename(def_u.first.path)) { + working_file->SetIndexContent(def_u.second); + EmitInactiveLines(working_file, def_u.first.inactive_regions); + EmitSemanticHighlighting(db, semantic_cache, working_file, + &db->files[update->file_id]); } } } @@ -454,11 +440,11 @@ void MainLoop() { } for (int i = 80; i--;) { - std::optional response = on_indexed->TryPopFront(); - if (!response) + std::optional update = on_indexed->TryPopFront(); + if (!update) break; did_work = true; - Main_OnIndexed(&db, &semantic_cache, &working_files, &*response); + Main_OnIndexed(&db, &semantic_cache, &working_files, &*update); } // Cleanup and free any unused memory. diff --git a/src/platform.h b/src/platform.h index 7d73549ad..561647b3f 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include #include diff --git a/src/project.cc b/src/project.cc index a7d0534bf..74c820800 100644 --- a/src/project.cc +++ b/src/project.cc @@ -8,7 +8,6 @@ #include "platform.h" #include "pipeline.hh" #include "serializers/json.h" -#include "timer.h" #include "utils.h" #include "working_files.h" using namespace ccls; @@ -275,20 +274,12 @@ std::vector LoadCompilationEntriesFromDirectory( LOG_S(INFO) << "loaded " << Path.c_str(); - Timer clang_time; - Timer our_time; - clang_time.Pause(); - our_time.Pause(); - - clang_time.Resume(); CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db); unsigned int num_commands = clang_CompileCommands_getSize(cx_commands); - clang_time.Pause(); std::vector result; for (unsigned int i = 0; i < num_commands; i++) { - clang_time.Resume(); CXCompileCommand cx_command = clang_CompileCommands_getCommand(cx_commands, i); @@ -304,25 +295,16 @@ std::vector LoadCompilationEntriesFromDirectory( entry.args.push_back( ToString(clang_CompileCommand_getArg(cx_command, j))); } - clang_time.Pause(); // TODO: don't call ToString in this block. - // LOG_S(INFO) << "Got args " << StringJoin(entry.args); - our_time.Resume(); entry.directory = directory; entry.file = entry.ResolveIfRelative(relative_filename); result.push_back( GetCompilationEntryFromCompileCommandEntry(project, entry)); - our_time.Pause(); } - clang_time.Resume(); clang_CompileCommands_dispose(cx_commands); clang_CompilationDatabase_dispose(cx_db); - clang_time.Pause(); - - clang_time.ResetAndPrint("compile_commands.json clang time"); - our_time.ResetAndPrint("compile_commands.json our time"); return result; } diff --git a/src/query.cc b/src/query.cc index 5ceef975a..c4ef41294 100644 --- a/src/query.cc +++ b/src/query.cc @@ -80,10 +80,10 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { def.language = indexed.language; auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { - def.all_symbols.push_back(SymbolRef(use.range, usr, kind, use.role)); + def.all_symbols.push_back(SymbolRef{{use.range, usr, kind, use.role}}); }; auto add_outline = [&](Use use, Usr usr, SymbolKind kind) { - def.outline.push_back(SymbolRef(use.range, usr, kind, use.role)); + def.outline.push_back(SymbolRef{{use.range, usr, kind, use.role}}); }; for (auto& it : indexed.usr2type) { diff --git a/src/test.cc b/src/test.cc index e9b5d8b34..f3001f6c9 100644 --- a/src/test.cc +++ b/src/test.cc @@ -290,8 +290,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // Run test. g_config = std::make_unique(); VFS vfs; - PerformanceImportFile perf; - auto dbs = index.Index(&vfs, path, flags, {}, &perf); + auto dbs = index.Index(&vfs, path, flags, {}); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; diff --git a/src/timer.cc b/src/timer.cc deleted file mode 100644 index 022ca22e3..000000000 --- a/src/timer.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include "timer.h" - -#include "log.hh" - -Timer::Timer() { - Reset(); -} - -long long Timer::ElapsedMicroseconds() const { - std::chrono::time_point end = Clock::now(); - return elapsed_ + - std::chrono::duration_cast(end - start_) - .count(); -} - -long long Timer::ElapsedMicrosecondsAndReset() { - long long elapsed = ElapsedMicroseconds(); - Reset(); - return elapsed; -} - -void Timer::Reset() { - start_ = Clock::now(); - elapsed_ = 0; -} - -void Timer::ResetAndPrint(const std::string& message) { - long long elapsed = ElapsedMicroseconds(); - long long milliseconds = elapsed / 1000; - long long remaining = elapsed - milliseconds; - LOG_S(INFO) << message << " took " << milliseconds << "." << remaining - << "ms"; - Reset(); -} - -void Timer::Pause() { - std::chrono::time_point end = Clock::now(); - long long elapsed = - std::chrono::duration_cast(end - start_) - .count(); - - elapsed_ += elapsed; -} - -void Timer::Resume() { - start_ = Clock::now(); -} - -ScopedPerfTimer::~ScopedPerfTimer() { - timer_.ResetAndPrint(message_); -} diff --git a/src/timer.h b/src/timer.h deleted file mode 100644 index 061801db9..000000000 --- a/src/timer.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -struct Timer { - using Clock = std::chrono::high_resolution_clock; - - // Creates a new timer. A timer is always running. - Timer(); - - // Returns elapsed microseconds. - long long ElapsedMicroseconds() const; - // Returns elapsed microseconds and restarts/resets the timer. - long long ElapsedMicrosecondsAndReset(); - // Restart/reset the timer. - void Reset(); - // Resets timer and prints a message like " took 5ms" - void ResetAndPrint(const std::string& message); - // Pause the timer. - void Pause(); - // Resume the timer after it has been paused. - void Resume(); - - // Raw start time. - std::chrono::time_point start_; - // Elapsed time. - long long elapsed_; -}; - -struct ScopedPerfTimer { - ~ScopedPerfTimer(); - - std::string message_; - Timer timer_; -}; From 66580104ba5a514c8d4743ec88985ea183f6c267 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Jun 2018 14:22:55 -0700 Subject: [PATCH 112/378] Add Config->largeFileSize; pure virtual or defaulted methods are definitions; fix $ccls/callHierarchy --- cmake/FindClang.cmake | 4 +++ src/config.cc | 2 +- src/config.h | 7 ++-- src/indexer.cc | 36 ++++++++++--------- src/indexer.h | 9 +++-- src/message_handler.cc | 17 +++++---- src/message_handler.h | 2 +- src/messages/ccls_call_hierarchy.cc | 4 +-- src/messages/initialize.cc | 4 +-- src/messages/text_document_document_symbol.cc | 6 ++-- src/project.cc | 8 +++-- src/symbol.h | 21 ----------- src/test.cc | 2 +- 13 files changed, 60 insertions(+), 62 deletions(-) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index ad085d483..6bfac108b 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -69,11 +69,15 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clang) +_Clang_find_add_library(clangAST) +_Clang_find_add_library(clangLex) _Clang_find_add_library(clangDriver) _Clang_find_add_library(clangBasic) if(USE_SHARED_LLVM) _Clang_find_add_library(LLVM) else() + _Clang_find_add_library(LLVMCore) + _Clang_find_add_library(LLVMBinaryFormat) _Clang_find_add_library(LLVMOption) _Clang_find_add_library(LLVMSupport) _Clang_find_add_library(LLVMDemangle) diff --git a/src/config.cc b/src/config.cc index 102d05a6e..27fac9c44 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,4 +1,4 @@ #include "config.h" -std::unique_ptr g_config; +Config* g_config; thread_local int g_thread_id; diff --git a/src/config.h b/src/config.h index 58946bac4..114f0c664 100644 --- a/src/config.h +++ b/src/config.h @@ -2,7 +2,6 @@ #include "serializer.h" -#include #include /* @@ -192,6 +191,9 @@ struct Config { std::vector whitelist; } index; + // Disable semantic highlighting for files larger than the size. + int64_t largeFileSize = 2 * 1024 * 1024; + struct WorkspaceSymbol { int caseSensitivity = 1; // Maximum workspace search results. @@ -252,8 +254,9 @@ MAKE_REFLECT_STRUCT(Config, diagnostics, highlight, index, + largeFileSize, workspaceSymbol, xref); -extern std::unique_ptr g_config; +extern Config* g_config; thread_local extern int g_thread_id; diff --git a/src/indexer.cc b/src/indexer.cc index de393f9c4..e714a6c27 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -5,7 +5,9 @@ #include "serializer.h" #include "type_printer.h" +#include #include +using namespace clang; using namespace llvm; #include @@ -151,26 +153,24 @@ lsSymbolKind GetSymbolKind(CXIdxEntityKind kind) { return lsSymbolKind::Unknown; } -StorageClass GetStorageClass(CX_StorageClass storage) { +StorageClass GetStorageC(CX_StorageClass storage) { switch (storage) { + default: case CX_SC_Invalid: case CX_SC_OpenCLWorkGroupLocal: - return StorageClass::Invalid; case CX_SC_None: - return StorageClass::None; + return SC_None; case CX_SC_Extern: - return StorageClass::Extern; + return SC_Extern; case CX_SC_Static: - return StorageClass::Static; + return SC_Static; case CX_SC_PrivateExtern: - return StorageClass::PrivateExtern; + return SC_PrivateExtern; case CX_SC_Auto: - return StorageClass::Auto; + return SC_Auto; case CX_SC_Register: - return StorageClass::Register; + return SC_Register; } - - return StorageClass::None; } // Caches all instances of constructors, regardless if they are indexed or not. @@ -583,7 +583,7 @@ void SetVarDetail(IndexVar& var, type_name = "lambda"; if (g_config->index.comments) def.comments = cursor.get_comments(); - def.storage = GetStorageClass(clang_Cursor_getStorageClass(cursor.cx_cursor)); + def.storage = GetStorageC(clang_Cursor_getStorageClass(cursor.cx_cursor)); // TODO how to make PrettyPrint'ed variable name qualified? #if 0 && CINDEX_HAVE_PRETTY @@ -1526,7 +1526,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { func.def.comments = cursor.get_comments(); func.def.kind = GetSymbolKind(decl->entityInfo->kind); func.def.storage = - GetStorageClass(clang_Cursor_getStorageClass(decl->cursor)); + GetStorageC(clang_Cursor_getStorageClass(decl->cursor)); // We don't actually need to know the return type, but we need to mark it // as an interesting usage. @@ -1536,11 +1536,13 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // Add definition or declaration. This is a bit tricky because we treat // template specializations as declarations, even though they are // technically definitions. - // TODO: Support multiple function definitions, which is common for - // template specializations. - if (decl->isDefinition && !is_template_specialization) { - // assert(!func->def.spell); - // assert(!func->def.extent); + bool is_def = decl->isDefinition; + if (!is_def) { + auto* D = static_cast(decl->cursor.data[0]); + auto* Method = dyn_cast_or_null(D->getAsFunction()); + is_def = Method && (Method->isDefaulted() || Method->isPure()); + } + if (is_def && !is_template_specialization) { func.def.spell = SetUse(db, spell, sem_parent, Role::Definition); func.def.extent = SetUse(db, extent, lex_parent, Role::None); } else { diff --git a/src/indexer.h b/src/indexer.h index 70619e9d7..156f7c662 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -12,6 +12,7 @@ #include "symbol.h" #include "utils.h" +#include #include #include @@ -62,6 +63,8 @@ struct Use : Reference { void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); +MAKE_REFLECT_TYPE_PROXY2(clang::StorageClass, uint8_t); + template struct NameMixin { std::string_view Name(bool qualified) const { @@ -99,7 +102,7 @@ struct FuncDef : NameMixin { int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; - StorageClass storage = StorageClass::Invalid; + clang::StorageClass storage = clang::SC_None; std::vector GetBases() const { return bases; } bool operator==(const FuncDef& o) const { @@ -213,11 +216,11 @@ struct VarDef : NameMixin { lsSymbolKind kind = lsSymbolKind::Unknown; // Note a variable may have instances of both |None| and |Extern| // (declaration). - StorageClass storage = StorageClass::Invalid; + clang::StorageClass storage = clang::SC_None; bool is_local() const { return spell && spell->kind != SymbolKind::File && - storage == StorageClass::None; + storage == clang::SC_None; } std::vector GetBases() const { return {}; } diff --git a/src/message_handler.cc b/src/message_handler.cc index 168fa605f..60aea6342 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -6,6 +6,8 @@ #include "pipeline.hh" using namespace ccls; +using namespace clang; + #include MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); @@ -187,10 +189,11 @@ void EmitInactiveLines(WorkingFile* working_file, void EmitSemanticHighlighting(DB* db, SemanticHighlightSymbolCache* semantic_cache, - WorkingFile* working_file, + WorkingFile* wfile, QueryFile* file) { assert(file->def); - if (!semantic_cache->match_->IsMatch(file->def->path)) + if (wfile->buffer_content.size() > g_config->largeFileSize || + !semantic_cache->match_->IsMatch(file->def->path)) return; auto semantic_cache_for_file = semantic_cache->GetCacheForFile(file->def->path); @@ -202,7 +205,7 @@ void EmitSemanticHighlighting(DB* db, std::string_view detailed_name; lsSymbolKind parent_kind = lsSymbolKind::Unknown; lsSymbolKind kind = lsSymbolKind::Unknown; - StorageClass storage = StorageClass::Invalid; + StorageClass storage = SC_None; // This switch statement also filters out symbols that are not highlighted. switch (sym.kind) { case SymbolKind::Func: { @@ -237,9 +240,9 @@ void EmitSemanticHighlighting(DB* db, detailed_name.substr(0, detailed_name.find('<')); int16_t start_line = sym.range.start.line; int16_t start_col = sym.range.start.column; - if (start_line < 0 || start_line >= working_file->index_lines.size()) + if (start_line < 0 || start_line >= wfile->index_lines.size()) continue; - std::string_view line = working_file->index_lines[start_line]; + std::string_view line = wfile->index_lines[start_line]; sym.range.end.line = start_line; if (!(start_col + concise_name.size() <= line.size() && line.compare(start_col, concise_name.size(), concise_name) == 0)) @@ -280,7 +283,7 @@ void EmitSemanticHighlighting(DB* db, continue; // applies to for loop } - std::optional loc = GetLsRange(working_file, sym.range); + std::optional loc = GetLsRange(wfile, sym.range); if (loc) { auto it = grouped_symbols.find(sym); if (it != grouped_symbols.end()) { @@ -339,7 +342,7 @@ void EmitSemanticHighlighting(DB* db, // Publish. Out_CclsPublishSemanticHighlighting out; - out.params.uri = lsDocumentUri::FromPath(working_file->filename); + out.params.uri = lsDocumentUri::FromPath(wfile->filename); for (auto& entry : grouped_symbols) if (entry.second.ranges.size()) out.params.symbols.push_back(entry.second); diff --git a/src/message_handler.h b/src/message_handler.h index f73dc4831..64e73e578 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -63,7 +63,7 @@ struct Out_CclsPublishSemanticHighlighting int stableId = 0; lsSymbolKind parentKind; lsSymbolKind kind; - StorageClass storage; + clang::StorageClass storage; std::vector ranges; }; struct Params { diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index bff5ca84b..92267d83e 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -95,7 +95,7 @@ bool Expand(MessageHandler* m, entry->numChildren = 0; if (!def) return false; - auto handle = [&](Use use, CallType call_type) { + auto handle = [&](Use use, CallType call_type1) { entry->numChildren++; if (levels > 0) { Out_CclsCallHierarchy::Entry entry1; @@ -103,7 +103,7 @@ bool Expand(MessageHandler* m, entry1.usr = use.usr; if (auto loc = GetLsLocation(m->db, m->working_files, use)) entry1.location = *loc; - entry1.callType = call_type; + entry1.callType = call_type1; if (Expand(m, &entry1, callee, call_type, qualified, levels - 1)) entry->children.push_back(std::move(entry1)); } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 4045eda8b..02d6c1db1 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -438,9 +438,9 @@ struct Handler_Initialize : BaseMessageHandler { { if (params.initializationOptions) - g_config = std::make_unique(*params.initializationOptions); + g_config = new Config(*params.initializationOptions); else - g_config = std::make_unique(); + g_config = new Config; rapidjson::Document reader; reader.Parse(g_init_options.c_str()); if (!reader.HasParseError()) { diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 959328e38..212994cd5 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -2,6 +2,7 @@ #include "pipeline.hh" #include "query_utils.h" using namespace ccls; +using namespace clang; namespace { MethodType kMethodType = "textDocument/documentSymbol"; @@ -51,9 +52,8 @@ struct Handler_TextDocumentDocumentSymbol if (!def || !def->spell) continue; // Ignore local variables. - if (def->spell->kind == SymbolKind::Func && - def->storage != StorageClass::Static && - def->storage != StorageClass::Extern) + if (def->spell->kind == SymbolKind::Func && def->storage != SC_Static && + def->storage != SC_Extern) continue; } diff --git a/src/project.cc b/src/project.cc index 74c820800..0ff3193ac 100644 --- a/src/project.cc +++ b/src/project.cc @@ -450,7 +450,9 @@ TEST_SUITE("Project") { void CheckFlags(const std::string& directory, const std::string& file, std::vector raw, std::vector expected) { - g_config = std::make_unique(); + if (g_config) + delete g_config; + g_config = new Config; g_config->clang.resourceDir = "/w/resource_dir/"; ProjectConfig project; project.project_dir = "/w/c/s/"; @@ -536,7 +538,9 @@ TEST_SUITE("Project") { } TEST_CASE("Directory extraction") { - g_config = std::make_unique(); + if (g_config) + delete g_config; + g_config = new Config; ProjectConfig config; config.project_dir = "/w/c/s/"; diff --git a/src/symbol.h b/src/symbol.h index 13b9f39ac..3a79ba073 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -8,27 +8,6 @@ enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; MAKE_REFLECT_TYPE_PROXY(SymbolKind); -// clang/Basic/Specifiers.h clang::StorageClass -enum class StorageClass : uint8_t { - // In |CX_StorageClass| but not in |clang::StorageClass| - // e.g. non-type template parameters - Invalid, - - // These are legal on both functions and variables. - // e.g. global functions/variables, local variables - None, - Extern, - Static, - // e.g. |__private_extern__ int a;| - PrivateExtern, - - // These are only legal on variables. - // e.g. explicit |auto int a;| - Auto, - Register -}; -MAKE_REFLECT_TYPE_PROXY(StorageClass); - enum class Role : uint16_t { None = 0, Declaration = 1 << 0, diff --git a/src/test.cc b/src/test.cc index f3001f6c9..c9dff5cf9 100644 --- a/src/test.cc +++ b/src/test.cc @@ -288,7 +288,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { flags.push_back(path); // Run test. - g_config = std::make_unique(); + g_config = new Config; VFS vfs; auto dbs = index.Index(&vfs, path, flags, {}); From 7b1ff448b9222eabe55eaa1a1de2db74a0263b70 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Jun 2018 16:51:39 -0700 Subject: [PATCH 113/378] Use clang::PrintingPolicy and remove type_printer --- CMakeLists.txt | 1 - index_tests/constructors/constructor.cc | 12 +- index_tests/constructors/destructor.cc | 16 +-- .../constructors/implicit_constructor.cc | 13 +- index_tests/constructors/invalid_reference.cc | 6 +- index_tests/constructors/make_functions.cc | 38 ++--- .../class_member_static.cc | 2 +- index_tests/declaration_vs_definition/func.cc | 2 +- .../func_associated_function_params.cc | 6 +- .../declaration_vs_definition/method.cc | 14 +- index_tests/enums/enum_usage.cc | 2 +- index_tests/foobar.cc | 4 +- index_tests/function_declaration.cc | 2 +- .../function_declaration_definition.cc | 2 +- index_tests/function_definition.cc | 2 +- index_tests/inheritance/function_override.cc | 10 +- .../inheritance/interface_pure_virtual.cc | 10 +- .../inheritance/multiple_base_functions.cc | 18 +-- index_tests/lambdas/lambda.cc | 8 +- index_tests/macros/complex.cc | 6 +- index_tests/macros/foo.cc | 8 +- index_tests/method_declaration.cc | 2 +- index_tests/method_definition.cc | 2 +- index_tests/method_inline_declaration.cc | 2 +- index_tests/multi_file/impl.cc | 8 +- index_tests/multi_file/simple_impl.cc | 4 +- index_tests/multi_file/static.cc | 8 +- index_tests/namespaces/anonymous_function.cc | 2 +- .../namespaces/function_declaration.cc | 2 +- index_tests/namespaces/function_definition.cc | 2 +- index_tests/namespaces/method_declaration.cc | 2 +- index_tests/namespaces/method_definition.cc | 2 +- .../namespaces/method_inline_declaration.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 8 +- index_tests/namespaces/namespace_reference.cc | 8 +- index_tests/operators/operator.cc | 8 +- .../outline/static_function_in_type.cc | 10 +- .../func_specialized_template_param.cc | 2 +- .../implicit_variable_instantiation.cc | 6 +- .../templates/member_ref_in_template.cc | 4 +- ...ass_template_func_usage_folded_into_one.cc | 10 +- ...ace_template_type_usage_folded_into_one.cc | 4 +- index_tests/templates/specialization.cc | 24 ++-- .../templates/specialized_func_definition.cc | 6 +- ...mplate_class_func_usage_folded_into_one.cc | 10 +- ...ass_template_func_usage_folded_into_one.cc | 10 +- ...mplate_class_type_usage_folded_into_one.cc | 4 +- ...emplate_class_var_usage_folded_into_one.cc | 6 +- .../template_func_usage_folded_into_one.cc | 10 +- .../template_type_usage_folded_into_one.cc | 4 +- .../template_var_usage_folded_into_one.cc | 7 +- index_tests/types/anonymous_struct.cc | 1 + index_tests/types/typedefs.cc | 6 +- index_tests/unions/union_usage.cc | 4 +- .../usage/func_called_from_constructor.cc | 8 +- .../usage/func_called_from_macro_argument.cc | 4 +- .../usage/func_called_from_template.cc | 6 +- .../usage/func_called_implicit_ctor.cc | 10 +- index_tests/usage/func_usage_addr_func.cc | 8 +- index_tests/usage/func_usage_addr_method.cc | 7 +- index_tests/usage/func_usage_call_func.cc | 4 +- index_tests/usage/func_usage_call_method.cc | 6 +- .../usage/func_usage_class_inline_var_def.cc | 6 +- .../usage/func_usage_forward_decl_func.cc | 4 +- .../usage/func_usage_forward_decl_method.cc | 6 +- index_tests/usage/func_usage_template_func.cc | 4 +- .../usage/type_usage_as_template_parameter.cc | 8 +- ...ype_usage_as_template_parameter_complex.cc | 12 +- ...type_usage_as_template_parameter_simple.cc | 2 +- .../usage/type_usage_declare_extern.cc | 2 +- index_tests/usage/type_usage_declare_local.cc | 6 +- index_tests/usage/type_usage_declare_param.cc | 6 +- .../type_usage_declare_param_prototype.cc | 4 +- .../usage/type_usage_declare_param_unnamed.cc | 2 +- .../usage/type_usage_declare_qualifiers.cc | 14 +- .../usage/type_usage_declare_static.cc | 2 +- .../usage/type_usage_on_return_type.cc | 18 +-- .../usage/type_usage_typedef_and_using.cc | 8 +- index_tests/usage/type_usage_various.cc | 6 +- index_tests/usage/usage_inside_of_call.cc | 10 +- .../usage/usage_inside_of_call_simple.cc | 6 +- index_tests/usage/var_usage_call_function.cc | 7 +- index_tests/usage/var_usage_class_member.cc | 8 +- .../usage/var_usage_class_member_static.cc | 6 +- index_tests/usage/var_usage_cstyle_cast.cc | 2 +- index_tests/usage/var_usage_extern.cc | 4 +- index_tests/usage/var_usage_func_parameter.cc | 4 +- index_tests/usage/var_usage_local.cc | 4 +- index_tests/usage/var_usage_shadowed_local.cc | 6 +- .../usage/var_usage_shadowed_parameter.cc | 6 +- index_tests/usage/var_usage_static.cc | 4 +- index_tests/vars/class_static_member.cc | 2 +- .../vars/class_static_member_decl_only.cc | 2 +- index_tests/vars/deduce_auto_type.cc | 8 +- index_tests/vars/function_local.cc | 4 +- index_tests/vars/function_param.cc | 6 +- index_tests/vars/function_param_unnamed.cc | 2 +- index_tests/vars/function_shadow_local.cc | 6 +- index_tests/vars/function_shadow_param.cc | 6 +- index_tests/vars/global_variable.cc | 2 +- index_tests/vars/global_variable_decl_only.cc | 2 +- .../vars/type_instance_on_using_type.cc | 4 +- src/indexer.cc | 136 ++++++++++-------- src/type_printer.cc | 107 -------------- src/type_printer.h | 8 -- 105 files changed, 406 insertions(+), 491 deletions(-) delete mode 100644 src/type_printer.cc delete mode 100644 src/type_printer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c021a170c..49a3061ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,6 @@ target_sources(ccls PRIVATE src/serializer.cc src/test.cc src/third_party_impl.cc - src/type_printer.cc src/utils.cc src/working_files.cc) diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index a6affdf3c..33c2ff6c0 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -15,11 +15,11 @@ void foo() { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 3385168158331140247, - "detailed_name": "void Foo::Foo()", - "qual_name_offset": 5, + "detailed_name": "Foo::Foo()", + "qual_name_offset": 0, "short_name": "Foo", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:3-3:6|15041163540773201510|2|2", "extent": "3:3-3:11|15041163540773201510|2|0", @@ -35,7 +35,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "6:6-6:9|0|1|2", "extent": "6:1-9:2|0|1|0", @@ -75,7 +75,7 @@ void foo() { "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 17165811951126099095, "detailed_name": "Foo *f2", @@ -88,7 +88,7 @@ void foo() { "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index e49e62c51..ff79a520c 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -20,11 +20,11 @@ void foo() { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 3385168158331140247, - "detailed_name": "void Foo::Foo()", - "qual_name_offset": 5, + "detailed_name": "Foo::Foo()", + "qual_name_offset": 0, "short_name": "Foo", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:3-3:6|15041163540773201510|2|2", "extent": "3:3-3:11|15041163540773201510|2|0", @@ -40,7 +40,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "7:6-7:9|0|1|2", "extent": "7:1-9:2|0|1|0", @@ -52,11 +52,11 @@ void foo() { "callees": ["8:7-8:8|3385168158331140247|3|288", "8:7-8:8|3385168158331140247|3|288"] }, { "usr": 7440261702884428359, - "detailed_name": "void Foo::~Foo() noexcept", - "qual_name_offset": 5, + "detailed_name": "Foo::~Foo() noexcept", + "qual_name_offset": 0, "short_name": "~Foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:3-4:7|15041163540773201510|2|2", "extent": "4:3-4:12|15041163540773201510|2|0", @@ -96,7 +96,7 @@ void foo() { "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index cc12e0235..6600ac372 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -18,7 +18,7 @@ void Make() { "qual_name_offset": 5, "short_name": "Make", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", @@ -30,11 +30,11 @@ void Make() { "callees": ["6:8-6:12|10530961286677896857|3|288", "6:8-6:12|10530961286677896857|3|288", "7:15-7:19|10530961286677896857|3|32", "7:15-7:19|10530961286677896857|3|32"] }, { "usr": 10530961286677896857, - "detailed_name": "void Type::Type()", - "qual_name_offset": 5, + "detailed_name": "Type::Type()", + "qual_name_offset": 0, "short_name": "Type", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:3-2:7|13487927231218873822|2|2", "extent": "2:3-2:12|13487927231218873822|2|0", @@ -74,19 +74,20 @@ void Make() { "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 17097499197730163115, "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", + "hover": "Type foo1 = Type()", "declarations": [], "spell": "7:8-7:12|3957104924306079513|3|2", "extent": "7:3-7:21|3957104924306079513|3|0", "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 38af29024..29118e1e5 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -14,11 +14,11 @@ Foo::Foo() {} "skipped_by_preprocessor": [], "usr2func": [{ "usr": 17319723337446061757, - "detailed_name": "void Foo::Foo()", - "qual_name_offset": 5, + "detailed_name": "Foo::Foo()", + "qual_name_offset": 0, "short_name": "Foo", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:6-4:9|15041163540773201510|2|2", "extent": "4:1-4:11|0|1|0", diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index a1f62b001..7407640a7 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -30,11 +30,11 @@ OUTPUT: make_functions.h "skipped_by_preprocessor": [], "usr2func": [{ "usr": 3765833212244435302, - "detailed_name": "void Foobar::Foobar(int &&, Bar *, bool *)", - "qual_name_offset": 5, + "detailed_name": "Foobar::Foobar(int &&, Bar *, bool *)", + "qual_name_offset": 0, "short_name": "Foobar", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "7:3-7:9|14935975554338052500|2|2", "extent": "7:3-7:32|14935975554338052500|2|0", @@ -46,11 +46,11 @@ OUTPUT: make_functions.h "callees": [] }, { "usr": 13028995015627606181, - "detailed_name": "void Foobar::Foobar(int)", - "qual_name_offset": 5, + "detailed_name": "Foobar::Foobar(int)", + "qual_name_offset": 0, "short_name": "Foobar", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "6:3-6:9|14935975554338052500|2|2", "extent": "6:3-6:17|14935975554338052500|2|0", @@ -62,11 +62,11 @@ OUTPUT: make_functions.h "callees": [] }, { "usr": 13131778807733950299, - "detailed_name": "void Foobar::Foobar()", - "qual_name_offset": 5, + "detailed_name": "Foobar::Foobar()", + "qual_name_offset": 0, "short_name": "Foobar", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:3-5:9|14935975554338052500|2|2", "extent": "5:3-5:14|14935975554338052500|2|0", @@ -78,11 +78,11 @@ OUTPUT: make_functions.h "callees": [] }, { "usr": 17321436359755983845, - "detailed_name": "void Foobar::Foobar(int, Bar *, bool *)", - "qual_name_offset": 5, + "detailed_name": "Foobar::Foobar(int, Bar *, bool *)", + "qual_name_offset": 0, "short_name": "Foobar", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:3-8:9|14935975554338052500|2|2", "extent": "8:3-8:30|14935975554338052500|2|0", @@ -139,11 +139,11 @@ OUTPUT: make_functions.cc "skipped_by_preprocessor": [], "usr2func": [{ "usr": 2532818908869373467, - "detailed_name": "T *maKE_NoRefs(Args... args)", + "detailed_name": "T *maKE_NoRefs(Args ...args)", "qual_name_offset": 3, "short_name": "maKE_NoRefs", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "9:4-9:15|0|1|2", "extent": "9:1-11:2|0|1|0", @@ -159,7 +159,7 @@ OUTPUT: make_functions.cc "qual_name_offset": 5, "short_name": "caller22", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "13:6-13:14|0|1|2", "extent": "13:1-18:2|0|1|0", @@ -213,11 +213,11 @@ OUTPUT: make_functions.cc "callees": [] }, { "usr": 15793662558620604611, - "detailed_name": "T *MakeUnique(Args &&... args)", + "detailed_name": "T *MakeUnique(Args &&...args)", "qual_name_offset": 3, "short_name": "MakeUnique", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:4-4:14|0|1|2", "extent": "4:1-6:2|0|1|0", @@ -352,7 +352,7 @@ OUTPUT: make_functions.cc "type": 0, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 8463700030555379526, "detailed_name": "Args &&... args", @@ -364,7 +364,7 @@ OUTPUT: make_functions.cc "type": 0, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 4abc45239..2de0195de 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -57,7 +57,7 @@ int Foo::foo; "type": 17, "uses": [], "kind": 8, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index c687a9eb5..4fa731026 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -15,7 +15,7 @@ void foo(); "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:14|0|1|0", diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index d16f8cef8..61cf8c6ed 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -15,7 +15,7 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], "spell": "5:5-5:8|0|1|2", "extent": "5:1-5:36|0|1|0", @@ -53,7 +53,7 @@ int foo(int a, int b) { return 0; } "type": 17, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 14555488990109936920, "detailed_name": "int a", @@ -65,7 +65,7 @@ int foo(int a, int b) { return 0; } "type": 17, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 038bd66a1..f3362df71 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -17,7 +17,7 @@ void Foo::def() {} "qual_name_offset": 5, "short_name": "declonly", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:16|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -27,12 +27,14 @@ void Foo::def() {} "callees": [] }, { "usr": 10939323144126021546, - "detailed_name": "void Foo::purevirtual()", - "qual_name_offset": 5, + "detailed_name": "virtual void Foo::purevirtual() = 0", + "qual_name_offset": 13, "short_name": "purevirtual", "kind": 6, - "storage": 1, - "declarations": ["3:16-3:27|15041163540773201510|2|1"], + "storage": 0, + "declarations": [], + "spell": "3:16-3:27|15041163540773201510|2|2", + "extent": "3:3-3:33|15041163540773201510|2|0", "declaring_type": 15041163540773201510, "bases": [], "derived": [], @@ -45,7 +47,7 @@ void Foo::def() {} "qual_name_offset": 5, "short_name": "def", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["4:8-4:11|15041163540773201510|2|1"], "spell": "7:11-7:14|15041163540773201510|2|2", "extent": "7:1-7:19|0|1|0", diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index f8b956b7e..745a5a6e0 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -54,7 +54,7 @@ Foo x = Foo::A; "type": 16985894625255407295, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 15962370213938840720, "detailed_name": "Foo::B", diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 64beb5a1c..79f3922ca 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -94,7 +94,7 @@ Foo b; "type": 10528472276654770367, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", @@ -106,7 +106,7 @@ Foo b; "type": 13938528237873543349, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index d0394c7ed..144fee637 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -11,7 +11,7 @@ void foo(int a, int b); "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "declaring_type": 0, "bases": [], diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index d914d1176..e38224531 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -13,7 +13,7 @@ void foo() {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:14|0|1|0", diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index 8a084daad..b92b0d370 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -11,7 +11,7 @@ void foo() {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-1:14|0|1|0", diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index b0503ebd9..34da20a68 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -12,11 +12,11 @@ class Derived : public Root { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 6666242542855173890, - "detailed_name": "void Derived::foo()", + "detailed_name": "void Derived::foo() override", "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:8-5:11|10963370434658308541|2|2", "extent": "5:3-5:25|10963370434658308541|2|0", @@ -28,11 +28,11 @@ class Derived : public Root { "callees": [] }, { "usr": 9948027785633571339, - "detailed_name": "void Root::foo()", - "qual_name_offset": 5, + "detailed_name": "virtual void Root::foo()", + "qual_name_offset": 13, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:16-2:19|3897841498936210886|2|1"], "declaring_type": 3897841498936210886, "bases": [], diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index e0bbfdf18..0d99ad9a3 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -9,12 +9,14 @@ class IFoo { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 3277829753446788562, - "detailed_name": "void IFoo::foo()", - "qual_name_offset": 5, + "detailed_name": "virtual void IFoo::foo() = 0", + "qual_name_offset": 13, "short_name": "foo", "kind": 6, - "storage": 1, - "declarations": ["2:16-2:19|9949214233977131946|2|1"], + "storage": 0, + "declarations": [], + "spell": "2:16-2:19|9949214233977131946|2|2", + "extent": "2:3-2:25|9949214233977131946|2|0", "declaring_type": 9949214233977131946, "bases": [], "derived": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 2b4a6535c..83fa7a9bc 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -15,11 +15,11 @@ struct Derived : Base0, Base1 { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 8401779086123965305, - "detailed_name": "void Base1::~Base1() noexcept", - "qual_name_offset": 5, + "detailed_name": "virtual Base1::~Base1() noexcept", + "qual_name_offset": 8, "short_name": "~Base1", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:11-5:17|15826803741381445676|2|2", "extent": "5:3-5:23|15826803741381445676|2|0", @@ -31,11 +31,11 @@ struct Derived : Base0, Base1 { "callees": [] }, { "usr": 13164726294460837993, - "detailed_name": "void Derived::~Derived() noexcept", - "qual_name_offset": 5, + "detailed_name": "Derived::~Derived() noexcept override", + "qual_name_offset": 0, "short_name": "~Derived", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:3-8:11|10963370434658308541|2|2", "extent": "8:3-8:26|10963370434658308541|2|0", @@ -47,11 +47,11 @@ struct Derived : Base0, Base1 { "callees": [] }, { "usr": 16347272523198263017, - "detailed_name": "void Base0::~Base0() noexcept", - "qual_name_offset": 5, + "detailed_name": "virtual Base0::~Base0() noexcept", + "qual_name_offset": 8, "short_name": "~Base0", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:11-2:17|11628904180681204356|2|2", "extent": "2:3-2:23|11628904180681204356|2|0", diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index b718b9625..b1bdc4516 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -22,7 +22,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-12:2|0|1|0", @@ -89,7 +89,7 @@ void foo() { "type": 14635009347499519042, "uses": ["9:3-9:14|4259594751088586730|3|4", "10:3-10:14|4259594751088586730|3|4", "11:3-11:14|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 12666114896600231317, "detailed_name": "int x", @@ -101,7 +101,7 @@ void foo() { "type": 17, "uses": ["5:7-5:8|0|1|4", "4:24-4:25|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 12879188959314906706, "detailed_name": "int y", @@ -113,7 +113,7 @@ void foo() { "type": 17, "uses": ["6:7-6:8|4259594751088586730|3|4"], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 72a7611b4..f29cfba38 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -22,7 +22,7 @@ FOO(make1(), make2); "qual_name_offset": 4, "short_name": "a", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["12:1-12:20|0|1|1"], "spell": "12:1-12:20|0|1|2", "extent": "12:1-12:20|0|1|0", @@ -38,7 +38,7 @@ FOO(make1(), make2); "qual_name_offset": 4, "short_name": "make1", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "6:5-6:10|0|1|2", "extent": "6:1-8:2|0|1|0", @@ -77,7 +77,7 @@ FOO(make1(), make2); "type": 17, "uses": ["12:14-12:19|9720930732776154610|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 4261071340275951718, "detailed_name": "FOO", diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index c513bd106..00cb44ed8 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -14,11 +14,11 @@ int x = A; "skipped_by_preprocessor": [], "usr2func": [{ "usr": 13788753348312146871, - "detailed_name": "void Foo::Foo(Foo &&)", - "qual_name_offset": 5, + "detailed_name": "Foo::Foo(Foo &&) = delete", + "qual_name_offset": 0, "short_name": "Foo", "kind": 9, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:12-5:15|15041163540773201510|2|2", "extent": "5:12-5:16|15041163540773201510|2|0", @@ -100,7 +100,7 @@ int x = A; "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index f576f2828..3eaf1f735 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -17,7 +17,7 @@ class Foo { "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 402089941..e9d2c040d 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -15,7 +15,7 @@ void Foo::foo() const {} "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1"], "spell": "5:11-5:14|15041163540773201510|2|2", "extent": "5:1-5:25|0|1|0", diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index e621ec2d9..08391d632 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -13,7 +13,7 @@ class Foo { "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:8-2:11|15041163540773201510|2|2", "extent": "2:3-2:16|15041163540773201510|2|0", diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 070c85645..1a52c2de6 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -15,7 +15,7 @@ OUTPUT: header.h "qual_name_offset": 5, "short_name": "Foo1", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "10:6-10:10|0|1|2", "extent": "10:1-10:15|0|1|0", @@ -139,7 +139,7 @@ OUTPUT: header.h "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 6141718166919284735, "detailed_name": "Foo3::A", @@ -177,7 +177,7 @@ OUTPUT: header.h "type": 17, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }, { "usr": 17716334512218775320, "detailed_name": "Foo3::B", @@ -206,7 +206,7 @@ OUTPUT: impl.cc "qual_name_offset": 5, "short_name": "Impl", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-5:2|0|1|0", diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 44e49cc63..3469d9fcb 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -15,7 +15,7 @@ OUTPUT: simple_header.h "qual_name_offset": 5, "short_name": "header", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["3:6-3:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -40,7 +40,7 @@ OUTPUT: simple_impl.cc "qual_name_offset": 5, "short_name": "impl", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-5:2|0|1|0", diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 88d473795..89bae0f7f 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -9,11 +9,11 @@ OUTPUT: static.h "skipped_by_preprocessor": [], "usr2func": [{ "usr": 14576076421851654759, - "detailed_name": "void Buffer::CreateSharedBuffer()", - "qual_name_offset": 5, + "detailed_name": "static void Buffer::CreateSharedBuffer()", + "qual_name_offset": 12, "short_name": "CreateSharedBuffer", "kind": 254, - "storage": 3, + "storage": 2, "declarations": ["4:15-4:33|9411323049603567600|2|1"], "declaring_type": 9411323049603567600, "bases": [], @@ -55,7 +55,7 @@ OUTPUT: static.cc "qual_name_offset": 5, "short_name": "CreateSharedBuffer", "kind": 254, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:14-3:32|9411323049603567600|2|2", "extent": "3:1-3:37|0|1|0", diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index bc7668e1b..359691cc3 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -13,7 +13,7 @@ void foo(); "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["2:6-2:9|7144845543074395457|2|1"], "declaring_type": 7144845543074395457, "bases": [], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index a9adedeee..81038adcc 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -13,7 +13,7 @@ void foo(int a, int b); "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["2:6-2:9|2029211996748007610|2|1"], "declaring_type": 2029211996748007610, "bases": [], diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index 7430cbdf8..c909296eb 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -13,7 +13,7 @@ void foo() {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:6-2:9|2029211996748007610|2|2", "extent": "2:1-2:14|2029211996748007610|2|0", diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index be6dd3a47..a50505d3c 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -15,7 +15,7 @@ class Foo { "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|1"], "declaring_type": 4508214972876735896, "bases": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 2b532db00..68f7f8d88 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -17,7 +17,7 @@ void Foo::foo() {} "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|1"], "spell": "6:11-6:14|4508214972876735896|2|2", "extent": "6:1-6:19|2029211996748007610|2|0", diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index b531b512a..97259490b 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -15,7 +15,7 @@ class Foo { "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:8-3:11|4508214972876735896|2|2", "extent": "3:3-3:16|4508214972876735896|2|0", diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 50af62917..9b768031a 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -24,7 +24,7 @@ void func() { "qual_name_offset": 5, "short_name": "func", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "11:6-11:10|0|1|2", "extent": "11:1-14:2|0|1|0", @@ -149,7 +149,7 @@ void func() { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 7657277353101371136, "detailed_name": "int b", @@ -162,7 +162,7 @@ void func() { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 15042442838933090518, "detailed_name": "int foo::bar::baz::qux", @@ -175,7 +175,7 @@ void func() { "type": 17, "uses": ["12:26-12:29|0|1|4", "13:16-13:19|0|1|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 73d50bd95..3d7ad72a7 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -20,7 +20,7 @@ void Runner() { "qual_name_offset": 5, "short_name": "Runner", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "6:6-6:12|0|1|2", "extent": "6:1-10:2|0|1|0", @@ -36,7 +36,7 @@ void Runner() { "qual_name_offset": 5, "short_name": "Accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:8-3:14|11072669167287398027|2|2", "extent": "3:3-3:24|11072669167287398027|2|0", @@ -109,7 +109,7 @@ void Runner() { "type": 17, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 12898699035586282159, "detailed_name": "int ns::Foo", @@ -121,7 +121,7 @@ void Runner() { "type": 17, "uses": ["7:18-7:21|631910859630953711|3|4", "9:10-9:13|631910859630953711|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index e44fa5bdc..a50ec0551 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -17,7 +17,7 @@ Foo &operator += (const Foo&, const int&); "qual_name_offset": 5, "short_name": "operator()", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["3:8-3:18|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -31,7 +31,7 @@ Foo &operator += (const Foo&, const int&); "qual_name_offset": 4, "short_name": "operator()", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["4:7-4:17|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -45,7 +45,7 @@ Foo &operator += (const Foo&, const int&); "qual_name_offset": 5, "short_name": "operator()", "kind": 6, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:8-2:18|15041163540773201510|2|2", "extent": "2:3-2:27|15041163540773201510|2|0", @@ -61,7 +61,7 @@ Foo &operator += (const Foo&, const int&); "qual_name_offset": 5, "short_name": "operator+=", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["7:6-7:17|0|1|1"], "declaring_type": 0, "bases": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 62f99811f..6bff6f6e5 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -13,11 +13,11 @@ OUTPUT: static_function_in_type.h "skipped_by_preprocessor": [], "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "void ns::Foo::Register(ns::Manager *)", - "qual_name_offset": 5, + "detailed_name": "static void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 12, "short_name": "Register", "kind": 254, - "storage": 3, + "storage": 2, "declarations": ["6:15-6:23|17262466801709381811|2|1"], "declaring_type": 17262466801709381811, "bases": [], @@ -106,7 +106,7 @@ OUTPUT: static_function_in_type.cc "qual_name_offset": 5, "short_name": "Register", "kind": 254, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|2", "extent": "5:1-6:2|11072669167287398027|2|0", @@ -191,7 +191,7 @@ OUTPUT: static_function_in_type.cc "type": 1972401196751872203, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ \ No newline at end of file diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index c1f4deaa0..ce0a4953a 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -18,7 +18,7 @@ void Foo::Bar(Template&) {} "qual_name_offset": 5, "short_name": "Bar", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["5:8-5:11|15041163540773201510|2|1"], "spell": "8:11-8:14|15041163540773201510|2|2", "extent": "8:1-8:36|0|1|0", diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index b45508b80..302086bfc 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -138,7 +138,7 @@ namespace ns { "type": 1532099849728741556, "uses": ["13:26-13:36|0|1|4", "14:27-14:37|0|1|4"], "kind": 8, - "storage": 1 + "storage": 0 }, { "usr": 9008550860229740818, "detailed_name": "int ns::Foo2", @@ -151,7 +151,7 @@ namespace ns { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 12898699035586282159, "detailed_name": "int ns::Foo", @@ -164,7 +164,7 @@ namespace ns { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index fd71e2db5..5e18a280a 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -31,7 +31,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-8:11|0|1|0", @@ -47,7 +47,7 @@ void foo() { "qual_name_offset": 5, "short_name": "bar", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["4:8-4:11|8402783583255987702|2|1"], "declaring_type": 8402783583255987702, "bases": [], diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index a6a609ce2..63b81fd93 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -18,11 +18,11 @@ namespace ns { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 8221803074608342407, - "detailed_name": "int ns::Foo::foo()", - "qual_name_offset": 4, + "detailed_name": "static int ns::Foo::foo()", + "qual_name_offset": 11, "short_name": "foo", "kind": 254, - "storage": 3, + "storage": 2, "declarations": [], "spell": "5:16-5:19|14042997404480181958|2|2", "extent": "5:5-7:6|14042997404480181958|2|0", @@ -116,7 +116,7 @@ namespace ns { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 15768138241775955040, "detailed_name": "int ns::a", @@ -129,7 +129,7 @@ namespace ns { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 3b7f23e78..519372a41 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -79,7 +79,7 @@ namespace ns { "type": 14042997404480181958, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 15768138241775955040, "detailed_name": "Foo ns::a", @@ -91,7 +91,7 @@ namespace ns { "type": 14042997404480181958, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index e788e7b64..3e4d59f77 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -49,11 +49,11 @@ void foo(float Value); "skipped_by_preprocessor": [], "usr2func": [{ "usr": 6113470698424012876, - "detailed_name": "void vector::clear()", - "qual_name_offset": 5, + "detailed_name": "void vector >::clear()", + "qual_name_offset": 31, "short_name": "clear", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["27:8-27:13|1663022413889915338|2|1"], "declaring_type": 1663022413889915338, "bases": [], @@ -67,7 +67,7 @@ void foo(float Value); "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["43:6-43:9|0|1|1"], "spell": "39:6-39:9|0|1|2", "extent": "39:1-39:21|0|1|0", @@ -83,7 +83,7 @@ void foo(float Value); "qual_name_offset": 5, "short_name": "clear", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["13:8-13:13|7440942986741176606|2|1"], "declaring_type": 7440942986741176606, "bases": [], @@ -338,7 +338,7 @@ void foo(float Value); "type": 16155717907537731864, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 2933643612409209903, "detailed_name": "function f", @@ -350,7 +350,7 @@ void foo(float Value); "type": 218068462278884837, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 3566687051827176322, "detailed_name": "vector vz1", @@ -362,7 +362,7 @@ void foo(float Value); "type": 7440942986741176606, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 4917621020431490070, "detailed_name": "Enum::Enum1", @@ -387,7 +387,7 @@ void foo(float Value); "type": 7440942986741176606, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 13914496963221806870, "detailed_name": "const int kOnst", @@ -400,7 +400,7 @@ void foo(float Value); "type": 17, "uses": ["43:27-43:32|0|1|4"], "kind": 13, - "storage": 3 + "storage": 2 }, { "usr": 15477793821005285152, "detailed_name": "Enum::Enum0", @@ -425,7 +425,7 @@ void foo(float Value); "type": 7440942986741176606, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 17826688417349629938, "detailed_name": "T Value", @@ -437,7 +437,7 @@ void foo(float Value); "type": 0, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 934063120..c9eaf9fb1 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -24,11 +24,11 @@ void Template::Foo() {} "skipped_by_preprocessor": [], "usr2func": [{ "usr": 11994188353303124840, - "detailed_name": "void Template::Foo()", - "qual_name_offset": 5, + "detailed_name": "template void Template::Foo()", + "qual_name_offset": 24, "short_name": "Foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["3:8-3:11|17107291254533526269|2|1", "10:22-10:25|0|1|1"], "spell": "7:19-7:22|17107291254533526269|2|2", "extent": "6:1-7:24|0|1|0", diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 3a7637b5d..0a109c29d 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -15,11 +15,11 @@ int b = Foo::foo(); "skipped_by_preprocessor": [], "usr2func": [{ "usr": 8340731781048851399, - "detailed_name": "int Foo::foo()", - "qual_name_offset": 4, + "detailed_name": "static int Foo::foo()", + "qual_name_offset": 11, "short_name": "foo", "kind": 254, - "storage": 3, + "storage": 2, "declarations": [], "spell": "3:14-3:17|10528472276654770367|2|2", "extent": "3:3-5:4|10528472276654770367|2|0", @@ -75,7 +75,7 @@ int b = Foo::foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "int a", @@ -88,7 +88,7 @@ int b = Foo::foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 81cf3b315..034a54edf 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -16,11 +16,11 @@ int b = Foo::foo(); "skipped_by_preprocessor": [], "usr2func": [{ "usr": 9034026360701857235, - "detailed_name": "int Foo::foo()", - "qual_name_offset": 4, + "detailed_name": "static int Foo::foo()", + "qual_name_offset": 11, "short_name": "foo", "kind": 254, - "storage": 3, + "storage": 2, "declarations": [], "spell": "4:14-4:17|10528472276654770367|2|2", "extent": "4:3-6:4|10528472276654770367|2|0", @@ -76,7 +76,7 @@ int b = Foo::foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "int a", @@ -89,7 +89,7 @@ int b = Foo::foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index fadf4c99f..15989f195 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -113,7 +113,7 @@ VarDecl b "type": 13938528237873543349, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", @@ -125,7 +125,7 @@ VarDecl b "type": 13938528237873543349, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index b1a2e8fb6..ab398ea8f 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -57,7 +57,7 @@ int b = Foo::var; "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 13545144895171991916, "detailed_name": "const int Foo::var", @@ -68,7 +68,7 @@ int b = Foo::var; "type": 17, "uses": ["6:19-6:22|0|1|4", "7:20-7:23|0|1|4"], "kind": 8, - "storage": 3 + "storage": 2 }, { "usr": 16721564935990383768, "detailed_name": "int a", @@ -81,7 +81,7 @@ int b = Foo::var; "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index e34b7505a..5e7722689 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -16,11 +16,11 @@ int b = foo(); "skipped_by_preprocessor": [], "usr2func": [{ "usr": 326583651986177228, - "detailed_name": "int foo()", - "qual_name_offset": 4, + "detailed_name": "static int foo()", + "qual_name_offset": 11, "short_name": "foo", "kind": 12, - "storage": 3, + "storage": 2, "declarations": [], "spell": "2:12-2:15|0|1|2", "extent": "2:1-4:2|0|1|0", @@ -59,7 +59,7 @@ int b = foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "int a", @@ -72,7 +72,7 @@ int b = foo(); "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 6693cd064..5eecc0044 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -39,7 +39,7 @@ Foo b; "type": 10528472276654770367, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "Foo a", @@ -51,7 +51,7 @@ Foo b; "type": 10528472276654770367, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index cd4ffa79e..61ee17ee3 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -91,13 +91,14 @@ UnexposedDecl var "detailed_name": "T var", "qual_name_offset": 2, "short_name": "var", + "hover": "T var = T()", "declarations": [], "spell": "5:3-5:6|0|1|2", "extent": "5:1-5:12|0|1|0", "type": 0, "uses": ["7:7-7:10|0|1|4", "8:7-8:10|0|1|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 12028309045033782423, "detailed_name": "B b", @@ -110,7 +111,7 @@ UnexposedDecl var "type": 13892793056005362145, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16721564935990383768, "detailed_name": "A a", @@ -123,7 +124,7 @@ UnexposedDecl var "type": 6697181287623958829, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 087cd8dec..5a70a8174 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -76,6 +76,7 @@ union vector3 { "detailed_name": "float [3] vector3::v", "qual_name_offset": 10, "short_name": "v", + "hover": "float [3] vector3::v[3]", "declarations": [], "spell": "3:9-3:10|17937907487590875128|2|2", "extent": "3:3-3:13|17937907487590875128|2|0", diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index a7e8c5201..45abe03a3 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -8,11 +8,11 @@ static func g; "skipped_by_preprocessor": [], "usr2func": [{ "usr": 8105378401105136463, - "detailed_name": "func g", - "qual_name_offset": 5, + "detailed_name": "static int g(const int *, const int *)", + "qual_name_offset": 11, "short_name": "g", "kind": 12, - "storage": 3, + "storage": 2, "declarations": ["2:13-2:14|0|1|1"], "declaring_type": 0, "bases": [], diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 3329ecd57..c856ca050 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -22,7 +22,7 @@ void act(Foo*) { "qual_name_offset": 5, "short_name": "act", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-10:2|0|1|0", @@ -98,7 +98,7 @@ void act(Foo*) { "type": 8501689086387244262, "uses": ["9:3-9:4|13982179977217945200|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 8804696910588009104, "detailed_name": "bool Foo::b", diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 67221d072..8213dac84 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -19,7 +19,7 @@ Foo::Foo() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", @@ -31,11 +31,11 @@ Foo::Foo() { "callees": [] }, { "usr": 3385168158331140247, - "detailed_name": "void Foo::Foo()", - "qual_name_offset": 5, + "detailed_name": "Foo::Foo()", + "qual_name_offset": 0, "short_name": "Foo", "kind": 9, - "storage": 1, + "storage": 0, "declarations": ["4:3-4:6|15041163540773201510|2|1"], "spell": "7:6-7:9|15041163540773201510|2|2", "extent": "7:1-9:2|0|1|0", diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 4388e551b..819b679e5 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -17,7 +17,7 @@ void caller() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["3:6-3:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -31,7 +31,7 @@ void caller() { "qual_name_offset": 5, "short_name": "caller", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:12|0|1|2", "extent": "5:1-7:2|0|1|0", diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 6647723de..c1f3a38b2 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -22,7 +22,7 @@ void foo() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -36,7 +36,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-10:2|0|1|0", @@ -52,7 +52,7 @@ void foo() { "qual_name_offset": 5, "short_name": "caller", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:6-4:12|0|1|2", "extent": "4:1-6:2|0|1|0", diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index 86a143645..a3a1b1c81 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -19,7 +19,7 @@ Wrapper caller() { "qual_name_offset": 4, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:5-5:11|0|1|2", "extent": "5:1-5:27|0|1|0", @@ -31,11 +31,11 @@ Wrapper caller() { "callees": [] }, { "usr": 10544127002917214589, - "detailed_name": "void Wrapper::Wrapper(int i)", - "qual_name_offset": 5, + "detailed_name": "Wrapper::Wrapper(int i)", + "qual_name_offset": 0, "short_name": "Wrapper", "kind": 9, - "storage": 1, + "storage": 0, "declarations": ["2:3-2:10|13611487872560323389|2|1"], "declaring_type": 13611487872560323389, "bases": [], @@ -49,7 +49,7 @@ Wrapper caller() { "qual_name_offset": 8, "short_name": "caller", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "7:9-7:15|0|1|2", "extent": "7:1-9:2|0|1|0", diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 88c6ff24f..19080a4c9 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -18,7 +18,7 @@ void user() { "qual_name_offset": 5, "short_name": "used", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-3:15|0|1|0", @@ -34,7 +34,7 @@ void user() { "qual_name_offset": 5, "short_name": "user", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", @@ -50,7 +50,7 @@ void user() { "qual_name_offset": 5, "short_name": "consume", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:13|0|1|2", "extent": "1:1-1:28|0|1|0", @@ -73,7 +73,7 @@ void user() { "type": 0, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index bc8e72b1c..7a33f6cb9 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -18,7 +18,7 @@ void user() { "qual_name_offset": 5, "short_name": "user", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-7:2|0|1|0", @@ -34,7 +34,7 @@ void user() { "qual_name_offset": 5, "short_name": "Used", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -66,13 +66,14 @@ void user() { "detailed_name": "void (Foo::*)() x", "qual_name_offset": 16, "short_name": "x", + "hover": "void (Foo::*)() x = &Foo::Used", "declarations": [], "spell": "6:8-6:9|9376923949268137283|3|2", "extent": "6:3-6:22|9376923949268137283|3|0", "type": 0, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 747b159e0..6c2db9e6b 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -14,7 +14,7 @@ void caller() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", @@ -30,7 +30,7 @@ void caller() { "qual_name_offset": 5, "short_name": "caller", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:6-2:12|0|1|2", "extent": "2:1-4:2|0|1|0", diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 4dd1244fd..842c3ec81 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -18,7 +18,7 @@ void user() { "qual_name_offset": 5, "short_name": "user", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", @@ -34,7 +34,7 @@ void user() { "qual_name_offset": 5, "short_name": "Used", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -73,7 +73,7 @@ void user() { "type": 15041163540773201510, "uses": ["7:3-7:4|9376923949268137283|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 3d62897e1..291322b4a 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -13,11 +13,11 @@ class Foo { "skipped_by_preprocessor": [], "usr2func": [{ "usr": 9630503130605430498, - "detailed_name": "int helper()", - "qual_name_offset": 4, + "detailed_name": "static int helper()", + "qual_name_offset": 11, "short_name": "helper", "kind": 12, - "storage": 3, + "storage": 2, "declarations": [], "spell": "1:12-1:18|0|1|2", "extent": "1:1-3:2|0|1|0", diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 1fbbbb1a3..f082dc33b 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -14,7 +14,7 @@ void usage() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "declaring_type": 0, "bases": [], @@ -28,7 +28,7 @@ void usage() { "qual_name_offset": 5, "short_name": "usage", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:11|0|1|2", "extent": "3:1-5:2|0|1|0", diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index fa3de2133..ae5bf98ac 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -17,7 +17,7 @@ void usage() { "qual_name_offset": 5, "short_name": "usage", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:11|0|1|2", "extent": "5:1-8:2|0|1|0", @@ -33,7 +33,7 @@ void usage() { "qual_name_offset": 5, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1"], "declaring_type": 15041163540773201510, "bases": [], @@ -72,7 +72,7 @@ void usage() { "type": 15041163540773201510, "uses": ["7:3-7:4|6767773193109753523|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 84330c569..48dcdfbdc 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -17,7 +17,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-7:2|0|1|0", @@ -33,7 +33,7 @@ void foo() { "qual_name_offset": 5, "short_name": "accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["2:6-2:12|0|1|1"], "declaring_type": 0, "bases": [], diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 6c9a99ba7..bc6eb0aac 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -21,7 +21,7 @@ unique_ptr* return_type() { "qual_name_offset": 15, "short_name": "return_type", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "9:16-9:27|0|1|2", "extent": "9:1-12:2|0|1|0", @@ -78,7 +78,7 @@ unique_ptr* return_type() { "type": 3286534761799572592, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 12857919739649552168, "detailed_name": "unique_ptr f0", @@ -90,7 +90,7 @@ unique_ptr* return_type() { "type": 3286534761799572592, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }, { "usr": 18075066956054788088, "detailed_name": "unique_ptr f1", @@ -102,7 +102,7 @@ unique_ptr* return_type() { "type": 3286534761799572592, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index fe9d3d94b..0236115c5 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -89,7 +89,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 36, "short_name": "as_return_type", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "33:37-33:51|0|1|2", "extent": "33:1-33:92|0|1|0", @@ -105,7 +105,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 5, "short_name": "no_return_type", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "40:6-40:20|0|1|2", "extent": "40:1-40:28|0|1|0", @@ -121,7 +121,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 20, "short_name": "foo", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["65:23-65:26|15041163540773201510|2|1"], "spell": "79:26-79:29|15041163540773201510|2|2", "extent": "79:1-79:51|0|1|0", @@ -137,7 +137,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 5, "short_name": "empty", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "53:6-53:11|0|1|2", "extent": "53:1-55:2|0|1|0", @@ -222,7 +222,7 @@ unique_ptr* Foo::foo() { return nullptr; } "type": 14209198335088845323, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 2933643612409209903, "detailed_name": "unique_ptr, S2> f", @@ -232,7 +232,7 @@ unique_ptr* Foo::foo() { return nullptr; } "type": 14209198335088845323, "uses": [], "kind": 13, - "storage": 2 + "storage": 1 }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index d06a630a0..7487a11eb 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -55,7 +55,7 @@ static unique_ptr foo; "type": 3286534761799572592, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index 7ca6501b8..813461cb4 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -34,7 +34,7 @@ extern T t; "type": 5673439900521455039, "uses": [], "kind": 13, - "storage": 2 + "storage": 1 }] } */ diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 436dbf71d..1a9218ed9 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -17,7 +17,7 @@ void Foo() { "qual_name_offset": 5, "short_name": "Foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-7:2|0|1|0", @@ -72,7 +72,7 @@ void Foo() { "type": 8508299082070213750, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 16374832544037266261, "detailed_name": "ForwardType *a", @@ -84,7 +84,7 @@ void Foo() { "type": 13749354388332789217, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 205b9da96..3de9198f0 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -14,7 +14,7 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-4:47|0|1|0", @@ -69,7 +69,7 @@ void foo(ForwardType* f, ImplementedType a) {} "type": 8508299082070213750, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 13058491096576226774, "detailed_name": "ForwardType *f", @@ -81,7 +81,7 @@ void foo(ForwardType* f, ImplementedType a) {} "type": 13749354388332789217, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index e66c6db2b..e96b64182 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -19,7 +19,7 @@ void foo(Foo* f, Foo*) {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["3:6-3:9|0|1|1"], "spell": "4:6-4:9|0|1|2", "extent": "4:1-4:26|0|1|0", @@ -57,7 +57,7 @@ void foo(Foo* f, Foo*) {} "type": 15041163540773201510, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index fb8c6e8fd..cc06d8a62 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -11,7 +11,7 @@ void foo(ForwardType*) {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:6-2:9|0|1|2", "extent": "2:1-2:26|0|1|0", diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index fbf7cac4b..22c1bf592 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -17,7 +17,7 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-8:2|0|1|0", @@ -57,7 +57,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 6081981442495435784, "detailed_name": "Type *a3", @@ -69,7 +69,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 7997456978847868736, "detailed_name": "Type &a0", @@ -81,7 +81,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 14939253431683105646, "detailed_name": "const Type *const a5", @@ -94,7 +94,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 15429032129697337561, "detailed_name": "Type a2", @@ -106,7 +106,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 17228576662112939520, "detailed_name": "const Type &a1", @@ -118,7 +118,7 @@ void foo(Type& a0, const Type& a1) { "type": 13487927231218873822, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index c2caccfce..d344aa6a9 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -35,7 +35,7 @@ static Type t; "type": 13487927231218873822, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 385f079f2..736caf8a8 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -28,7 +28,7 @@ static Type* bar() { return nullptr; } "qual_name_offset": 5, "short_name": "Empty", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["9:8-9:13|15041163540773201510|2|1"], "spell": "13:11-13:16|15041163540773201510|2|2", "extent": "13:1-13:21|0|1|0", @@ -44,7 +44,7 @@ static Type* bar() { return nullptr; } "qual_name_offset": 6, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "5:7-5:10|0|1|2", "extent": "5:1-5:32|0|1|0", @@ -56,11 +56,11 @@ static Type* bar() { return nullptr; } "callees": [] }, { "usr": 7746867874366499515, - "detailed_name": "const Type &external()", - "qual_name_offset": 12, + "detailed_name": "extern const Type &external()", + "qual_name_offset": 19, "short_name": "external", "kind": 12, - "storage": 2, + "storage": 1, "declarations": ["15:20-15:28|0|1|1"], "declaring_type": 0, "bases": [], @@ -74,7 +74,7 @@ static Type* bar() { return nullptr; } "qual_name_offset": 6, "short_name": "Get", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["8:9-8:12|15041163540773201510|2|1"], "spell": "12:12-12:15|15041163540773201510|2|2", "extent": "12:1-12:40|0|1|0", @@ -86,11 +86,11 @@ static Type* bar() { return nullptr; } "callees": [] }, { "usr": 18408440185620243373, - "detailed_name": "Type *bar()", - "qual_name_offset": 6, + "detailed_name": "static Type *bar()", + "qual_name_offset": 13, "short_name": "bar", "kind": 12, - "storage": 3, + "storage": 2, "declarations": ["17:14-17:17|0|1|1"], "spell": "18:14-18:17|0|1|2", "extent": "18:1-18:39|0|1|0", diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index 67b992fd3..02d1ebbbd 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -20,7 +20,7 @@ void accept3(Foo3*) {} "qual_name_offset": 5, "short_name": "accept1", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "8:6-8:13|0|1|2", "extent": "8:1-8:23|0|1|0", @@ -36,7 +36,7 @@ void accept3(Foo3*) {} "qual_name_offset": 5, "short_name": "accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "7:6-7:12|0|1|2", "extent": "7:1-7:21|0|1|0", @@ -52,7 +52,7 @@ void accept3(Foo3*) {} "qual_name_offset": 5, "short_name": "accept2", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "9:6-9:13|0|1|2", "extent": "9:1-9:23|0|1|0", @@ -68,7 +68,7 @@ void accept3(Foo3*) {} "qual_name_offset": 5, "short_name": "accept3", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "10:6-10:13|0|1|2", "extent": "10:1-10:23|0|1|0", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index 5ad5b235a..dc881608f 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -20,7 +20,7 @@ extern Foo foo; "qual_name_offset": 5, "short_name": "make", "kind": 6, - "storage": 1, + "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1"], "spell": "5:11-5:15|15041163540773201510|2|2", "extent": "5:1-8:2|0|1|0", @@ -58,7 +58,7 @@ extern Foo foo; "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 2 + "storage": 1 }, { "usr": 16380484338511689669, "detailed_name": "Foo f", @@ -70,7 +70,7 @@ extern Foo foo; "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 9642d1d9f..13229c6db 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -25,7 +25,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "12:6-12:9|0|1|2", "extent": "12:1-15:2|0|1|0", @@ -41,7 +41,7 @@ void foo() { "qual_name_offset": 4, "short_name": "gen", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["3:5-3:8|0|1|1"], "declaring_type": 0, "bases": [], @@ -55,7 +55,7 @@ void foo() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -115,7 +115,7 @@ void foo() { "type": 17, "uses": ["14:10-14:11|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 9648311402855509901, "detailed_name": "int Foo::field_var", @@ -140,7 +140,7 @@ void foo() { "type": 17, "uses": ["14:45-14:55|4259594751088586730|3|4"], "kind": 8, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 326e6592b..483cf69c8 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -17,7 +17,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "5:6-5:9|0|1|2", "extent": "5:1-7:2|0|1|0", @@ -33,7 +33,7 @@ void foo() { "qual_name_offset": 4, "short_name": "gen", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:5-3:8|0|1|2", "extent": "3:1-3:24|0|1|0", @@ -49,7 +49,7 @@ void foo() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["1:6-1:12|0|1|1"], "declaring_type": 0, "bases": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 33a835f65..3e6eaeffd 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -18,7 +18,7 @@ void caller() { "qual_name_offset": 5, "short_name": "called", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", @@ -34,7 +34,7 @@ void caller() { "qual_name_offset": 5, "short_name": "caller", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:12|0|1|2", "extent": "3:1-8:2|0|1|0", @@ -51,13 +51,14 @@ void caller() { "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", + "hover": "void (*)() x = &called", "declarations": [], "spell": "4:8-4:9|11404881820527069090|3|2", "extent": "4:3-4:19|11404881820527069090|3|0", "type": 0, "uses": ["5:3-5:4|11404881820527069090|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index d10749eb7..e8c6daffe 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -28,7 +28,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "10:6-10:9|0|1|2", "extent": "10:1-18:2|0|1|0", @@ -44,7 +44,7 @@ void foo() { "qual_name_offset": 5, "short_name": "accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["8:6-8:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -58,7 +58,7 @@ void foo() { "qual_name_offset": 5, "short_name": "accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["7:6-7:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -141,7 +141,7 @@ void foo() { "type": 15041163540773201510, "uses": ["12:3-12:4|4259594751088586730|3|4", "13:3-13:4|4259594751088586730|3|4", "14:10-14:11|4259594751088586730|3|4", "15:10-15:11|4259594751088586730|3|4", "16:11-16:12|4259594751088586730|3|4", "17:10-17:11|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 1f9dd67c7..d9d0b08cb 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -19,7 +19,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "7:6-7:9|0|1|2", "extent": "7:1-9:2|0|1|0", @@ -35,7 +35,7 @@ void foo() { "qual_name_offset": 5, "short_name": "accept", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["5:6-5:12|0|1|1"], "declaring_type": 0, "bases": [], @@ -86,7 +86,7 @@ void foo() { "type": 17, "uses": ["8:15-8:16|4259594751088586730|3|4"], "kind": 8, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index b554c29e9..1d7a86cfe 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -63,7 +63,7 @@ const VarType Holder::static_var; "type": 5792006888140599735, "uses": [], "kind": 8, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 81100735e..894dcadc2 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -14,7 +14,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", @@ -50,7 +50,7 @@ void foo() { "type": 17, "uses": ["4:3-4:4|4259594751088586730|3|4"], "kind": 13, - "storage": 2 + "storage": 1 }] } */ diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 72d2a1d74..2b833d1aa 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -12,7 +12,7 @@ void foo(int a) { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-3:2|0|1|0", @@ -50,7 +50,7 @@ void foo(int a) { "type": 17, "uses": ["2:3-2:4|11998306017310352355|3|4"], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 2a1e89fdc..1843caba4 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -13,7 +13,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-4:2|0|1|0", @@ -51,7 +51,7 @@ void foo() { "type": 17, "uses": ["3:3-3:4|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 307e22064..11590ae2b 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -18,7 +18,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-9:2|0|1|0", @@ -56,7 +56,7 @@ void foo() { "type": 17, "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 14036425367303419504, "detailed_name": "int a", @@ -68,7 +68,7 @@ void foo() { "type": 17, "uses": ["6:5-6:6|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index dfe22c82b..e10ac0f1a 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -18,7 +18,7 @@ void foo(int a) { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-8:2|0|1|0", @@ -56,7 +56,7 @@ void foo(int a) { "type": 17, "uses": ["5:5-5:6|11998306017310352355|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 11608231465452906059, "detailed_name": "int a", @@ -68,7 +68,7 @@ void foo(int a) { "type": 17, "uses": ["2:3-2:4|11998306017310352355|3|4", "7:3-7:4|11998306017310352355|3|4"], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 1b74d463e..9b4661a97 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -15,7 +15,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", @@ -53,7 +53,7 @@ void foo() { "type": 17, "uses": ["4:3-4:4|4259594751088586730|3|4"], "kind": 13, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 426090c81..0dfb2dc9e 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -42,7 +42,7 @@ Foo* Foo::member = nullptr; "type": 15041163540773201510, "uses": [], "kind": 8, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index 98781bc5f..61a741653 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -49,7 +49,7 @@ class Foo { "type": 17, "uses": [], "kind": 8, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 654e5bf4b..be3796f7b 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -15,7 +15,7 @@ void f() { "qual_name_offset": 5, "short_name": "f", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "2:6-2:7|0|1|2", "extent": "2:1-5:2|0|1|0", @@ -49,25 +49,27 @@ void f() { "detailed_name": "Foo *x", "qual_name_offset": 5, "short_name": "x", + "hover": "Foo *x = new Foo()", "declarations": [], "spell": "3:8-3:9|880549676430489861|3|2", "extent": "3:3-3:21|880549676430489861|3|0", "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 18422884837902130475, "detailed_name": "Foo *y", "qual_name_offset": 5, "short_name": "y", + "hover": "Foo *y = new Foo()", "declarations": [], "spell": "4:9-4:10|880549676430489861|3|2", "extent": "4:3-4:22|880549676430489861|3|0", "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 8ea4fbe00..d68ab3820 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -15,7 +15,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", @@ -53,7 +53,7 @@ void foo() { "type": 15041163540773201510, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 275078e19..ca65c7d34 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -13,7 +13,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:30|0|1|0", @@ -51,7 +51,7 @@ void foo(Foo* p0, Foo* p1) {} "type": 15041163540773201510, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 8730439006497971620, "detailed_name": "Foo *p0", @@ -63,7 +63,7 @@ void foo(Foo* p0, Foo* p1) {} "type": 15041163540773201510, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index 5615e382d..c63782085 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -10,7 +10,7 @@ void foo(int, int) {} "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-1:22|0|1|0", diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 2905c2255..e56738091 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -18,7 +18,7 @@ void foo() { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-9:2|0|1|0", @@ -56,7 +56,7 @@ void foo() { "type": 17, "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }, { "usr": 4508045017817092115, "detailed_name": "int a", @@ -68,7 +68,7 @@ void foo() { "type": 17, "uses": ["6:5-6:6|4259594751088586730|3|4"], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index 62d96aaaf..7aac0a2c2 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -12,7 +12,7 @@ void foo(int p) { "qual_name_offset": 5, "short_name": "foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-3:2|0|1|0", @@ -50,7 +50,7 @@ void foo(int p) { "type": 17, "uses": [], "kind": 253, - "storage": 1 + "storage": 0 }, { "usr": 11404600766177939811, "detailed_name": "int p", @@ -63,7 +63,7 @@ void foo(int p) { "type": 17, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index 48fe10ab0..24f01ca44 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -33,7 +33,7 @@ static int global = 0; "type": 17, "uses": [], "kind": 13, - "storage": 3 + "storage": 2 }] } */ diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index 947e42c84..a7d883724 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -30,7 +30,7 @@ extern int global; "type": 17, "uses": [], "kind": 13, - "storage": 2 + "storage": 1 }] } */ diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 88cd787ea..055024e1d 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -17,7 +17,7 @@ void Foo() { "qual_name_offset": 5, "short_name": "Foo", "kind": 12, - "storage": 1, + "storage": 0, "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", @@ -75,7 +75,7 @@ void Foo() { "type": 7434820806199665424, "uses": [], "kind": 13, - "storage": 1 + "storage": 0 }] } */ diff --git a/src/indexer.cc b/src/indexer.cc index e714a6c27..3777bfd6f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -3,12 +3,12 @@ #include "log.hh" #include "platform.h" #include "serializer.h" -#include "type_printer.h" #include +#include #include using namespace clang; -using namespace llvm; +using llvm::Timer; #include #include @@ -17,9 +17,6 @@ using namespace llvm; #include #include -#if CINDEX_VERSION >= 47 -#define CINDEX_HAVE_PRETTY 1 -#endif #if CINDEX_VERSION >= 48 #define CINDEX_HAVE_ROLE 1 #endif @@ -28,7 +25,18 @@ namespace { // For typedef/using spanning less than or equal to (this number) of lines, // display their declarations on hover. -constexpr int kMaxLinesDisplayTypeAliasDeclarations = 3; +constexpr int kMaxDetailedLines = 3; + +struct CXTranslationUnitImpl { + /* clang::CIndexer */ void *CIdx; + clang::ASTUnit *TheASTUnit; + /* clang::cxstring::CXStringPool */ void *StringPool; + void *Diagnostics; + void *OverridenCursorsPool; + /* clang::index::CommentToXMLConverter */ void *CommentToXML; + unsigned ParsingOptions; + std::vector Arguments; +}; // TODO How to check if a reference to type is a declaration? // This currently also includes constructors/destructors. @@ -295,37 +303,28 @@ struct IndexParam { NamespaceHelper ns; ConstructorCache ctors; - IndexParam(ClangTranslationUnit* tu, - FileConsumer* file_consumer) + IndexParam(ClangTranslationUnit* tu, FileConsumer* file_consumer) : tu(tu), file_consumer(file_consumer) {} -#if CINDEX_HAVE_PRETTY - CXPrintingPolicy print_policy = nullptr; - CXPrintingPolicy print_policy_more = nullptr; - ~IndexParam() { - clang_PrintingPolicy_dispose(print_policy); - clang_PrintingPolicy_dispose(print_policy_more); - } - std::tuple PrettyPrintCursor( - CXCursor cursor, + CXCursor Cursor, std::string_view short_name) { - if (!print_policy) { - print_policy = clang_getCursorPrintingPolicy(cursor); - clang_PrintingPolicy_setProperty(print_policy, - CXPrintingPolicy_TerseOutput, 1); - clang_PrintingPolicy_setProperty(print_policy, - CXPrintingPolicy_FullyQualifiedName, 1); - clang_PrintingPolicy_setProperty( - print_policy, CXPrintingPolicy_SuppressInitializers, 1); - print_policy_more = clang_getCursorPrintingPolicy(cursor); - clang_PrintingPolicy_setProperty(print_policy_more, - CXPrintingPolicy_FullyQualifiedName, 1); - clang_PrintingPolicy_setProperty(print_policy_more, - CXPrintingPolicy_TerseOutput, 1); - } - std::string name = - ToString(clang_getCursorPrettyPrinted(cursor, print_policy_more)); + auto TU = + static_cast(const_cast(Cursor.data[2])); + ASTContext& AST = TU->TheASTUnit->getASTContext(); + PrintingPolicy Policy = AST.getPrintingPolicy(); + Policy.TerseOutput = 1; + Policy.FullyQualifiedName = true; + + const Decl* D = static_cast(Cursor.data[0]); + if (!D) + return {"", 0, 0, 0}; + + llvm::SmallString<128> Str; + llvm::raw_svector_ostream OS(Str); + D->print(OS, Policy); + std::string name = OS.str(); + for (std::string::size_type i = 0;;) { if ((i = name.find("(anonymous ", i)) == std::string::npos) break; @@ -350,7 +349,6 @@ struct IndexParam { } return {name, i, short_name_offset, short_name_size}; } -#endif }; IndexFile* ConsumeFile(IndexParam* param, CXFile file) { @@ -610,8 +608,8 @@ void SetVarDetail(IndexVar& var, def.qual_name_offset = 0; def.hover = hover; } else { -#if 0 && CINDEX_HAVE_PRETTY - //def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false); +#if 0 + def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false); #else int offset = type_name.size(); offset += ConcatTypeAndName(type_name, qualified_name); @@ -623,23 +621,52 @@ void SetVarDetail(IndexVar& var, // int (*a)(); int (&a)(); int (&&a)(); int a[1]; auto x = ... // We can take these into consideration after we have better support for // inside-out syntax. - CXType deref = cx_type; - while (deref.kind == CXType_Pointer || deref.kind == CXType_MemberPointer || - deref.kind == CXType_LValueReference || - deref.kind == CXType_RValueReference) - deref = clang_getPointeeType(deref); - if (deref.kind != CXType_Unexposed && deref.kind != CXType_Auto && - clang_getResultType(deref).kind == CXType_Invalid && - clang_getElementType(deref).kind == CXType_Invalid) { + QualType T = QualType::getFromOpaquePtr(cx_type.data[0]); + while (1) { + const Type* TP = T.getTypePtrOrNull(); + if (!TP) + goto skip; + switch (TP->getTypeClass()) { + default: + break; + // case Type::Auto: + // case Type::ConstantArray: + // case Type::IncompleteArray: + // case Type::VariableArray: + // case Type::DependentSizedArray: + // case Type::Vector: + // case Type::Complex: + // goto skip; + case Type::Pointer: + T = cast(TP)->getPointeeType(); + continue; + case Type::LValueReference: + case Type::RValueReference: + T = cast(TP)->getPointeeType(); + continue; + case Type::MemberPointer: + T = cast(TP)->getPointeeType(); + continue; + } + break; + } + if (T->getAs()) + goto skip; + { const FileContents& fc = param->file_contents[db->path]; - std::optional spell_end = fc.ToOffset(cursor.get_spell().end); - std::optional extent_end = fc.ToOffset(cursor.get_extent().end); - if (extent_end && *spell_end < *extent_end) - def.hover = std::string(def.detailed_name.c_str()) + - fc.content.substr(*spell_end, *extent_end - *spell_end); + Position spell_p = cursor.get_spell().end, + extent_p = cursor.get_extent().end; + if (extent_p.line - spell_p.line < kMaxDetailedLines) { + std::optional spell_end = fc.ToOffset(spell_p), + extent_end = fc.ToOffset(extent_p); + if (extent_end && *spell_end < *extent_end) + def.hover = std::string(def.detailed_name.c_str()) + + fc.content.substr(*spell_end, *extent_end - *spell_end); + } + } + skip:; } #endif - } if (is_first_seen) { if (IndexType* var_type = @@ -1556,15 +1583,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) { -#if CINDEX_HAVE_PRETTY std::tie(func.def.detailed_name, func.def.qual_name_offset, func.def.short_name_offset, func.def.short_name_size) = param->PrettyPrintCursor(decl->cursor, decl->entityInfo->name); -#else - std::tie(func.def.detailed_name, func.def.qual_name_offset, - func.def.short_name_offset, func.def.short_name_size) = - GetFunctionSignature(db, ¶m->ns, decl); -#endif // CXCursor_OverloadedDeclRef in templates are not processed by // OnIndexReference, thus we use TemplateVisitor to collect function @@ -1642,8 +1663,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. - if (extent.end.line - extent.start.line < - kMaxLinesDisplayTypeAliasDeclarations) { + if (extent.end.line - extent.start.line < kMaxDetailedLines) { FileContents& fc = param->file_contents[db->path]; std::optional extent_start = fc.ToOffset(extent.start), spell_start = fc.ToOffset(spell.start), diff --git a/src/type_printer.cc b/src/type_printer.cc deleted file mode 100644 index eac5ad41b..000000000 --- a/src/type_printer.cc +++ /dev/null @@ -1,107 +0,0 @@ -#include "type_printer.h" - -namespace { - -int GetNameInsertingPosition(const std::string& type_desc, - const std::string& return_type) { - // Check if type_desc contains an (. - if (type_desc.size() <= return_type.size() || - type_desc.find("(", 0) == std::string::npos) - return type_desc.size(); - // Find the first character where the return_type differs from the - // function_type. In most cases this is the place where the function name - // should be inserted. - int ret = 0; - while (return_type[ret] == type_desc[ret]) - ret++; - - if (ret == 0) { - // If return type and function type do not overlap at all, - // check if it is `auto (...) ->` trailing return type. - if (type_desc.compare(0, 5, "auto ") == 0 && - type_desc.find(" -> ") != std::string::npos) - ret = 5; - } else { - // Otherwise return type is just a prefix of the function_type. - // Skip any eventual spaces after the return type. - while (type_desc[ret] == ' ') - ret++; - } - return ret; -} -} // namespace - -// Build a detailed function signature, including argument names. -std::tuple GetFunctionSignature( - IndexFile* db, - NamespaceHelper* ns, - const CXIdxDeclInfo* decl) { - int num_args = clang_Cursor_getNumArguments(decl->cursor); - int16_t qual_name_offset, short_name_offset, short_name_size; - std::string func_name; - std::tie(func_name, short_name_offset, short_name_size) = - ns->QualifiedName(decl->semanticContainer, decl->entityInfo->name); - - std::vector> args; - for (int i = 0; i < num_args; i++) { - args.emplace_back(-1, ::ToString(clang_getCursorDisplayName( - clang_Cursor_getArgument(decl->cursor, i)))); - } - if (clang_Cursor_isVariadic(decl->cursor)) { - args.emplace_back(-1, ""); - num_args++; - } - - std::string type_desc = ClangCursor(decl->cursor).get_type_description(); - qual_name_offset = GetNameInsertingPosition( - type_desc, ::ToString(clang_getTypeSpelling( - clang_getCursorResultType(decl->cursor)))); - - if (type_desc[qual_name_offset] == '(') { - // Find positions to insert argument names. - // Argument name are before ',' or closing ')'. - num_args = 0; - for (int balance = 0, i = qual_name_offset; - i < int(type_desc.size()) && num_args < int(args.size()); i++) { - if (type_desc[i] == '(' || type_desc[i] == '[') - balance++; - else if (type_desc[i] == ')' || type_desc[i] == ']') { - if (--balance <= 0) { - args[num_args].first = i; - break; - } - } else if (type_desc[i] == ',' && balance == 1) - args[num_args++].first = i; - } - - // Second pass: insert argument names before each comma and closing paren. - int i = qual_name_offset; - short_name_offset += qual_name_offset; - std::string type_desc_with_names(type_desc.begin(), type_desc.begin() + i); - type_desc_with_names.append(func_name); - for (auto& arg : args) { - if (arg.first < 0) - break; - if (arg.second.empty()) - continue; - // TODO Use inside-out syntax. Note, clang/lib/AST/TypePrinter.cpp does - // not print arg names. - type_desc_with_names.insert(type_desc_with_names.end(), &type_desc[i], - &type_desc[arg.first]); - i = arg.first; - ConcatTypeAndName(type_desc_with_names, arg.second); - } - type_desc_with_names.insert(type_desc_with_names.end(), - type_desc.begin() + i, type_desc.end()); - type_desc = std::move(type_desc_with_names); - } else { - // type_desc is either a typedef, or some complicated type we cannot handle. - // Append the func_name in this case. - int offset = type_desc.size(); - offset += ConcatTypeAndName(type_desc, func_name); - qual_name_offset = offset; - short_name_offset += offset; - } - - return {type_desc, qual_name_offset, short_name_offset, short_name_size}; -} diff --git a/src/type_printer.h b/src/type_printer.h deleted file mode 100644 index 87b39ca51..000000000 --- a/src/type_printer.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "indexer.h" - -std::tuple GetFunctionSignature( - IndexFile* db, - NamespaceHelper* ns, - const CXIdxDeclInfo* decl); From 0decb01a0f682baedb64369541eb7546904940d6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 2 Jun 2018 00:33:12 -0700 Subject: [PATCH 114/378] Add Config->reparseForDependency Specify 1 if for large projects you don't want to reparse dependents at load time when a common .h changes. --- src/config.h | 11 +++++---- src/log.hh | 2 +- src/messages/text_document_document_symbol.cc | 6 +---- src/pipeline.cc | 23 +++++++++++-------- src/project.cc | 9 +++++--- src/project.h | 2 ++ src/utils.cc | 1 - 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/config.h b/src/config.h index 114f0c664..1ba2f1c69 100644 --- a/src/config.h +++ b/src/config.h @@ -177,14 +177,15 @@ struct Config { // If false, the indexer will be disabled. bool enabled = true; - // If true, project paths that were skipped by the whitelist/blacklist will - // be logged. - bool logSkippedPaths = false; - // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onDidChange = false; + // Whether to reparse a file if write times of its dependencies have + // changed. The file will always be reparsed if its own write time changes. + // 0: no, 1: only after initial load of project, 2: yes + int reparseForDependency = 2; + // Number of indexer threads. If 0, 80% of cores are used. int threads = 0; @@ -235,8 +236,8 @@ MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, - logSkippedPaths, onDidChange, + reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); diff --git a/src/log.hh b/src/log.hh index caab81511..64fc63d6b 100644 --- a/src/log.hh +++ b/src/log.hh @@ -37,4 +37,4 @@ struct Message { #define LOG_IF_S(v, cond) \ LOG_IF(ccls::log::Verbosity_##v, \ (cond) && ccls::log::Verbosity_##v <= ccls::log::verbosity) -#define CHECK_S(cond) LOG_IF(FATAL, !(cond)) << "check failed: " #cond " " +#define LOG_V(v) LOG_IF(ccls::log::Verbosity(v), v <= ccls::log::verbosity) diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 212994cd5..6aec71ff9 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -49,11 +49,7 @@ struct Handler_TextDocumentDocumentSymbol if (sym.kind == SymbolKind::Var) { QueryVar& var = db->GetVar(sym); auto* def = var.AnyDef(); - if (!def || !def->spell) - continue; - // Ignore local variables. - if (def->spell->kind == SymbolKind::Func && def->storage != SC_Static && - def->storage != SC_Extern) + if (!def || !def->spell || def->is_local()) continue; } diff --git a/src/pipeline.cc b/src/pipeline.cc index e5c1ce14b..cece67d32 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -168,18 +168,22 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev, path_to_index, entry.args, std::nullopt)) reparse = 2; - for (const auto& dep : prev->dependencies) - if (auto write_time1 = LastWriteTime(dep.first().str())) { - if (dep.second < *write_time1) { + int reparseForDep = g_config->index.reparseForDependency; + if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded)) + for (const auto& dep : prev->dependencies) { + if (auto write_time1 = LastWriteTime(dep.first().str())) { + if (dep.second < *write_time1) { + reparse = 2; + std::lock_guard lock(vfs->mutex); + vfs->state[dep.first().str()].stage = 0; + } + } else reparse = 2; - std::lock_guard lock(vfs->mutex); - vfs->state[dep.first().str()].stage = 0; - } - } else - reparse = 2; + } } if (reparse < 2) { + LOG_S(INFO) << "load cache for " << path_to_index; auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); @@ -288,7 +292,8 @@ void Main_OnIndexed(DB* db, WorkingFiles* working_files, IndexUpdate* update) { if (update->refresh) { - LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; + Project::loaded = true; + LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); for (auto& f : working_files->files) { std::string filename = LowerPathIfInsensitive(f->filename); diff --git a/src/project.cc b/src/project.cc index 0ff3193ac..1310efc17 100644 --- a/src/project.cc +++ b/src/project.cc @@ -325,7 +325,10 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace +bool Project::loaded = false; + void Project::Load(const std::string& root_directory) { + Project::loaded = false; // Load data. ProjectConfig project; project.extra_flags = g_config->clang.extraArgs; @@ -428,9 +431,9 @@ void Project::ForAllFilteredFiles( std::string failure_reason; if (matcher.IsMatch(entry.filename, &failure_reason)) action(i, entries[i]); - else if (g_config->index.logSkippedPaths) { - LOG_S(INFO) << "[" << i + 1 << "/" << entries.size() << "]: Failed " - << failure_reason << "; skipping " << entry.filename; + else { + LOG_V(1) << "[" << i + 1 << "/" << entries.size() << "]: Failed " + << failure_reason << "; skipping " << entry.filename; } } } diff --git a/src/project.h b/src/project.h index d6d3f3960..f56f4b55b 100644 --- a/src/project.h +++ b/src/project.h @@ -57,4 +57,6 @@ struct Project { std::function action); void Index(WorkingFiles* wfiles, lsRequestId id); + + static bool loaded; }; diff --git a/src/utils.cc b/src/utils.cc index 9c17c1291..c10b92469 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -105,7 +105,6 @@ std::string EscapeFileName(std::string path) { } std::optional ReadContent(const std::string& filename) { - LOG_S(INFO) << "read " << filename; char buf[4096]; std::string ret; FILE* f = fopen(filename.c_str(), "rb"); From 134126629a6da61e198e0def0dac5b5ed60df573 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 3 Jun 2018 00:29:33 -0700 Subject: [PATCH 115/378] Infer system include paths from CompilerInvocation --- CMakeLists.txt | 2 +- cmake/FindClang.cmake | 6 +- ...ics_engine.cc => diagnostics_publisher.cc} | 10 +-- ...tics_engine.h => diagnostics_publisher.hh} | 2 +- src/indexer.cc | 5 -- src/message_handler.h | 4 +- src/messages/initialize.cc | 6 +- src/pipeline.cc | 16 ++--- src/pipeline.hh | 4 +- src/project.cc | 67 ++++++++++++++++--- 10 files changed, 85 insertions(+), 37 deletions(-) rename src/{diagnostics_engine.cc => diagnostics_publisher.cc} (79%) rename src/{diagnostics_engine.h => diagnostics_publisher.hh} (91%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49a3061ae..2e829ca71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -193,7 +193,7 @@ target_sources(ccls PRIVATE src/clang_tu.cc src/clang_utils.cc src/config.cc - src/diagnostics_engine.cc + src/diagnostics_publisher.cc src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 6bfac108b..4fd60949a 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -69,6 +69,8 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clang) +_Clang_find_add_library(clangFrontend) +_Clang_find_add_library(clangSerialization) _Clang_find_add_library(clangAST) _Clang_find_add_library(clangLex) _Clang_find_add_library(clangDriver) @@ -76,9 +78,11 @@ _Clang_find_add_library(clangBasic) if(USE_SHARED_LLVM) _Clang_find_add_library(LLVM) else() + _Clang_find_add_library(LLVMBitReader) + _Clang_find_add_library(LLVMOption) + _Clang_find_add_library(LLVMProfileData) _Clang_find_add_library(LLVMCore) _Clang_find_add_library(LLVMBinaryFormat) - _Clang_find_add_library(LLVMOption) _Clang_find_add_library(LLVMSupport) _Clang_find_add_library(LLVMDemangle) endif() diff --git a/src/diagnostics_engine.cc b/src/diagnostics_publisher.cc similarity index 79% rename from src/diagnostics_engine.cc rename to src/diagnostics_publisher.cc index c714ec9b9..6402d98c8 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_publisher.cc @@ -1,19 +1,19 @@ -#include "diagnostics_engine.h" +#include "diagnostics_publisher.hh" #include "pipeline.hh" using namespace ccls; #include -void DiagnosticsEngine::Init() { +void DiagnosticsPublisher::Init() { frequencyMs_ = g_config->diagnostics.frequencyMs; match_ = std::make_unique(g_config->diagnostics.whitelist, g_config->diagnostics.blacklist); } -void DiagnosticsEngine::Publish(WorkingFiles* working_files, - std::string path, - std::vector diagnostics) { +void DiagnosticsPublisher::Publish(WorkingFiles* working_files, + std::string path, + std::vector diagnostics) { // Cache diagnostics so we can show fixits. working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { if (working_file) diff --git a/src/diagnostics_engine.h b/src/diagnostics_publisher.hh similarity index 91% rename from src/diagnostics_engine.h rename to src/diagnostics_publisher.hh index 2d3e7aeeb..a6b5a6881 100644 --- a/src/diagnostics_engine.h +++ b/src/diagnostics_publisher.hh @@ -3,7 +3,7 @@ #include "match.h" #include "working_files.h" -class DiagnosticsEngine { +class DiagnosticsPublisher { std::unique_ptr match_; int64_t nextPublish_ = 0; int frequencyMs_; diff --git a/src/indexer.cc b/src/indexer.cc index 3777bfd6f..d8fd7ad9c 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -2070,9 +2070,6 @@ std::vector> ParseWithTu( const std::string& file, const std::vector& args, const std::vector& file_contents) { - Timer timer; - timer.startTimer(); - IndexerCallbacks callback = {0}; // Available callbacks: // - abortQuery @@ -2114,8 +2111,6 @@ std::vector> ParseWithTu( ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); - timer.stopTimer(); - std::unordered_map inc_to_line; // TODO if (param.primary_file) diff --git a/src/message_handler.h b/src/message_handler.h index 64e73e578..58bb1329b 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -14,7 +14,7 @@ struct ClangCompleteManager; struct CodeCompleteCache; struct Config; -class DiagnosticsEngine; +class DiagnosticsPublisher; struct VFS; struct ImportManager; struct IncludeComplete; @@ -104,7 +104,7 @@ struct MessageHandler { DB* db = nullptr; MultiQueueWaiter* waiter = nullptr; Project* project = nullptr; - DiagnosticsEngine* diag_engine = nullptr; + DiagnosticsPublisher* diag_pub = nullptr; VFS* vfs = nullptr; ImportManager* import_manager = nullptr; SemanticHighlightSymbolCache* semantic_cache = nullptr; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 02d6c1db1..55d8a2e67 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,4 +1,4 @@ -#include "diagnostics_engine.h" +#include "diagnostics_publisher.hh" #include "filesystem.hh" #include "include_complete.h" #include "log.hh" @@ -492,7 +492,7 @@ struct Handler_Initialize : BaseMessageHandler { sys::fs::create_directories(g_config->cacheDirectory + '@' + EscapeFileName(g_config->projectRoot)); - diag_engine->Init(); + diag_pub->Init(); semantic_cache->Init(); // Open up / load the project. @@ -510,7 +510,7 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); - pipeline::Indexer_Main(diag_engine, vfs, project, working_files); + pipeline::Indexer_Main(diag_pub, vfs, project, working_files); }).detach(); } diff --git a/src/pipeline.cc b/src/pipeline.cc index cece67d32..52d154f75 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -2,7 +2,7 @@ #include "clang_complete.h" #include "config.h" -#include "diagnostics_engine.h" +#include "diagnostics_publisher.hh" #include "include_complete.h" #include "log.hh" #include "lsp.h" @@ -119,7 +119,7 @@ std::unique_ptr RawCacheLoad( *file_content, IndexFile::kMajorVersion); } -bool Indexer_Parse(DiagnosticsEngine* diag_engine, +bool Indexer_Parse(DiagnosticsPublisher* diag_pub, WorkingFiles* working_files, Project* project, VFS* vfs, @@ -224,7 +224,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, // to identify indexing problems. For interactive sessions, diagnostics are // handled by code completion. if (!request.is_interactive) - diag_engine->Publish(working_files, curr->path, curr->diagnostics_); + diag_pub->Publish(working_files, curr->path, curr->diagnostics_); std::string path = curr->path; if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) @@ -275,7 +275,7 @@ void Init() { for_stdout = new ThreadedQueue(stdout_waiter); } -void Indexer_Main(DiagnosticsEngine* diag_engine, +void Indexer_Main(DiagnosticsPublisher* diag_pub, VFS* vfs, Project* project, WorkingFiles* working_files) { @@ -283,7 +283,7 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, ClangIndexer indexer; while (true) - if (!Indexer_Parse(diag_engine, working_files, project, vfs, &indexer)) + if (!Indexer_Parse(diag_pub, working_files, project, vfs, &indexer)) indexer_waiter->Wait(index_request); } @@ -386,12 +386,12 @@ void MainLoop() { SemanticHighlightSymbolCache semantic_cache; WorkingFiles working_files; VFS vfs; - DiagnosticsEngine diag_engine; + DiagnosticsPublisher diag_pub; ClangCompleteManager clang_complete( &project, &working_files, [&](std::string path, std::vector diagnostics) { - diag_engine.Publish(&working_files, path, diagnostics); + diag_pub.Publish(&working_files, path, diagnostics); }, [](lsRequestId id) { if (id.Valid()) { @@ -416,7 +416,7 @@ void MainLoop() { handler->db = &db; handler->waiter = indexer_waiter; handler->project = &project; - handler->diag_engine = &diag_engine; + handler->diag_pub = &diag_pub; handler->vfs = &vfs; handler->semantic_cache = &semantic_cache; handler->working_files = &working_files; diff --git a/src/pipeline.hh b/src/pipeline.hh index f21a44c73..a3926594b 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -7,7 +7,7 @@ #include #include -class DiagnosticsEngine; +class DiagnosticsPublisher; struct VFS; struct Project; struct WorkingFiles; @@ -18,7 +18,7 @@ namespace ccls::pipeline { void Init(); void LaunchStdin(); void LaunchStdout(); -void Indexer_Main(DiagnosticsEngine* diag_engine, +void Indexer_Main(DiagnosticsPublisher* diag_pub, VFS* vfs, Project* project, WorkingFiles* working_files); diff --git a/src/project.cc b/src/project.cc index 1310efc17..4c7bf7371 100644 --- a/src/project.cc +++ b/src/project.cc @@ -12,7 +12,10 @@ #include "working_files.h" using namespace ccls; +#include +#include #include +#include #include #include #include @@ -97,6 +100,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( args.insert(args.end(), config->extra_flags.begin(), config->extra_flags.end()); +#if 1 std::unique_ptr Opts = driver::createDriverOptTable(); unsigned MissingArgIndex, MissingArgCount; std::vector cargs; @@ -105,18 +109,63 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( InputArgList Args = Opts->ParseArgs(makeArrayRef(cargs), MissingArgIndex, MissingArgCount, driver::options::CC1Option); - using namespace clang::driver::options; - for (const auto* A : - Args.filtered(OPT_I, OPT_c_isystem, OPT_cxx_isystem, OPT_isystem)) + for (const auto* A : Args.filtered(OPT_I, OPT_c_isystem, OPT_cxx_isystem, + OPT_isystem, OPT_idirafter)) config->angle_dirs.insert(entry.ResolveIfRelative(A->getValue())); for (const auto* A : Args.filtered(OPT_I, OPT_iquote)) config->quote_dirs.insert(entry.ResolveIfRelative(A->getValue())); - for (const auto* A : Args.filtered(OPT_idirafter)) { - std::string dir = entry.ResolveIfRelative(A->getValue()); - config->angle_dirs.insert(dir); - config->quote_dirs.insert(dir); +#else + // a weird C++ deduction guide heap-use-after-free causes libclang to crash. + IgnoringDiagConsumer DiagC; + IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); + DiagnosticsEngine Diags( + IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, + &DiagC, false); + + driver::Driver Driver(args[0], llvm::sys::getDefaultTargetTriple(), Diags); + auto TargetAndMode = + driver::ToolChain::getTargetAndModeFromProgramName(args[0]); + if (!TargetAndMode.TargetPrefix.empty()) { + const char* arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()}; + args.insert(args.begin() + 1, std::begin(arr), std::end(arr)); + Driver.setTargetAndMode(TargetAndMode); } + Driver.setCheckInputsExist(false); + + std::vector cargs; + for (auto& arg : args) + cargs.push_back(arg.c_str()); + cargs.push_back("-fsyntax-only"); + std::unique_ptr C(Driver.BuildCompilation(cargs)); + const driver::JobList& Jobs = C->getJobs(); + if (Jobs.size() != 1) + return result; + const driver::ArgStringList& CCArgs = Jobs.begin()->getArguments(); + + auto Invocation = std::make_unique(); + CompilerInvocation::CreateFromArgs(*Invocation, CCArgs.data(), + CCArgs.data() + CCArgs.size(), Diags); + Invocation->getFrontendOpts().DisableFree = false; + Invocation->getCodeGenOpts().DisableFree = false; + + HeaderSearchOptions& HeaderOpts = Invocation->getHeaderSearchOpts(); + for (auto& E : HeaderOpts.UserEntries) { + std::string path = entry.ResolveIfRelative(E.Path); + switch (E.Group) { + default: + config->angle_dirs.insert(path); + break; + case frontend::Quoted: + config->quote_dirs.insert(path); + break; + case frontend::Angled: + config->angle_dirs.insert(path); + config->quote_dirs.insert(path); + break; + } + } +#endif for (size_t i = 1; i < args.size(); i++) // This is most likely the file path we will be passing to clang. The @@ -128,9 +177,9 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - if (!Args.hasArg(OPT_resource_dir)) + // if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); - if (!Args.hasArg(OPT_working_directory)) + // if (Invocation->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); // There could be a clang version mismatch between what the project uses and From c8a81aeae3ba9838ba5777bdaef9bb92ca4821ab Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 6 Jun 2018 00:36:39 -0700 Subject: [PATCH 116/378] Inject anonymous struct/union into parent scopes --- src/indexer.cc | 33 +++++++++++++++++++++------------ src/pipeline.cc | 4 ++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index d8fd7ad9c..7e305b781 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -597,13 +597,16 @@ void SetVarDetail(IndexVar& var, CXTypeKind k = clang_getCanonicalType( clang_getEnumDeclIntegerType(semanticContainer->cursor)) .kind; - std::string hover = qualified_name + " = "; - if (k == CXType_Char_U || k == CXType_UChar || k == CXType_UShort || - k == CXType_UInt || k == CXType_ULong || k == CXType_ULongLong) - hover += std::to_string( - clang_getEnumConstantDeclUnsignedValue(cursor.cx_cursor)); - else - hover += std::to_string(clang_getEnumConstantDeclValue(cursor.cx_cursor)); + std::string hover = qualified_name; + if (auto* TD = dyn_cast_or_null( + static_cast(cursor.cx_cursor.data[0]))) { + hover += " = "; + if (k == CXType_Char_U || k == CXType_UChar || k == CXType_UShort || + k == CXType_UInt || k == CXType_ULong || k == CXType_ULongLong) + hover += std::to_string(TD->getInitVal().getZExtValue()); + else + hover += std::to_string(TD->getInitVal().getSExtValue()); + } def.detailed_name = std::move(qualified_name); def.qual_name_offset = 0; def.hover = hover; @@ -1518,13 +1521,19 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { .def.vars.push_back(var.usr); break; } - case SymbolKind::Type: - if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) { - long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor); - db->ToType(decl->semanticContainer->cursor) - .def.vars.emplace_back(var.usr, offset); + case SymbolKind::Type: { + CXCursor parent = decl->semanticContainer->cursor; + long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor); + while (parent.kind != CXCursor_EnumDecl) { + IndexType& type = db->ToType(parent); + type.def.vars.emplace_back(var.usr, offset); + if (!clang_Cursor_isAnonymous(parent)) break; + parent = clang_getCursorSemanticParent(parent); + offset = -1; + if (GetSymbolKind(parent.kind) != SymbolKind::Type) break; } break; + } default: break; } diff --git a/src/pipeline.cc b/src/pipeline.cc index 52d154f75..aea96e265 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -190,8 +190,8 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, on_indexed->PushBack(std::move(update), request.is_interactive); } for (const auto& dep : dependencies) - if (vfs->Mark(dep.first().str(), 0, 2)) { - prev = RawCacheLoad(dep.first().str()); + if (vfs->Mark(dep.first().str(), 0, 2) && + (prev = RawCacheLoad(dep.first().str()))) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.is_interactive); } From e5d8153d4b0a4b7a4a03543b2dda632e81df7dfc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 7 Jun 2018 21:53:41 -0700 Subject: [PATCH 117/378] Internalize strings & remove diagnostics_publisher.cc --- CMakeLists.txt | 1 - src/clang_tu.cc | 4 +- src/clang_tu.h | 3 +- src/diagnostics_publisher.cc | 36 -------------- src/diagnostics_publisher.hh | 16 ------- src/indexer.cc | 69 +++++++++++++++------------ src/indexer.h | 52 +++++++------------- src/messages/ccls_member_hierarchy.cc | 8 ++-- src/messages/initialize.cc | 1 - src/messages/text_document_hover.cc | 6 +-- src/method.cc | 2 +- src/nt_string.h | 42 ---------------- src/pipeline.cc | 43 ++++++++++++++--- src/pipeline.hh | 15 +++++- src/query.cc | 12 ++--- src/serializer.cc | 43 ++++++++++++----- src/serializer.h | 10 ++-- src/serializers/binary.h | 16 +++---- src/serializers/json.h | 2 +- src/test.cc | 6 +-- 20 files changed, 170 insertions(+), 217 deletions(-) delete mode 100644 src/diagnostics_publisher.cc delete mode 100644 src/diagnostics_publisher.hh delete mode 100644 src/nt_string.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e829ca71..b35acd4a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -193,7 +193,6 @@ target_sources(ccls PRIVATE src/clang_tu.cc src/clang_utils.cc src/config.cc - src/diagnostics_publisher.cc src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc diff --git a/src/clang_tu.cc b/src/clang_tu.cc index dbb1d89db..8b5b1450e 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -259,7 +259,7 @@ std::string ClangCursor::get_type_description() const { return ::ToString(clang_getTypeSpelling(type)); } -NtString ClangCursor::get_comments() const { +std::string ClangCursor::get_comments() const { CXSourceRange range = clang_Cursor_getCommentRange(cx_cursor); if (clang_Range_isNull(range)) return {}; @@ -317,7 +317,7 @@ NtString ClangCursor::get_comments() const { ret.pop_back(); if (ret.empty()) return {}; - return static_cast(ret); + return ret; } std::string ClangCursor::ToString() const { diff --git a/src/clang_tu.h b/src/clang_tu.h index 2530b2de0..85bbf537f 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -1,5 +1,4 @@ #pragma once -#include "nt_string.h" #include "position.h" #include @@ -86,7 +85,7 @@ class ClangCursor { bool is_valid_kind() const; std::string get_type_description() const; - NtString get_comments() const; + std::string get_comments() const; std::string ToString() const; diff --git a/src/diagnostics_publisher.cc b/src/diagnostics_publisher.cc deleted file mode 100644 index 6402d98c8..000000000 --- a/src/diagnostics_publisher.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "diagnostics_publisher.hh" - -#include "pipeline.hh" -using namespace ccls; - -#include - -void DiagnosticsPublisher::Init() { - frequencyMs_ = g_config->diagnostics.frequencyMs; - match_ = std::make_unique(g_config->diagnostics.whitelist, - g_config->diagnostics.blacklist); -} - -void DiagnosticsPublisher::Publish(WorkingFiles* working_files, - std::string path, - std::vector diagnostics) { - // Cache diagnostics so we can show fixits. - working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { - if (working_file) - working_file->diagnostics_ = diagnostics; - }); - - int64_t now = - std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count(); - if (frequencyMs_ >= 0 && (nextPublish_ <= now || diagnostics.empty()) && - match_->IsMatch(path)) { - nextPublish_ = now + frequencyMs_; - - Out_TextDocumentPublishDiagnostics out; - out.params.uri = lsDocumentUri::FromPath(path); - out.params.diagnostics = diagnostics; - pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); - } -} diff --git a/src/diagnostics_publisher.hh b/src/diagnostics_publisher.hh deleted file mode 100644 index a6b5a6881..000000000 --- a/src/diagnostics_publisher.hh +++ /dev/null @@ -1,16 +0,0 @@ -#include "lsp_diagnostic.h" - -#include "match.h" -#include "working_files.h" - -class DiagnosticsPublisher { - std::unique_ptr match_; - int64_t nextPublish_ = 0; - int frequencyMs_; - - public: - void Init(); - void Publish(WorkingFiles* working_files, - std::string path, - std::vector diagnostics); -}; diff --git a/src/indexer.cc b/src/indexer.cc index 7e305b781..1e5720b95 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -3,6 +3,7 @@ #include "log.hh" #include "platform.h" #include "serializer.h" +using ccls::Intern; #include #include @@ -523,8 +524,10 @@ void SetTypeName(IndexType& type, // ns {}` which are not qualified. // type->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor); int short_name_offset, short_name_size; - std::tie(type.def.detailed_name, short_name_offset, short_name_size) = + std::string detailed; + std::tie(detailed, short_name_offset, short_name_size) = param->ns.QualifiedName(container ? container : &parent, name); + type.def.detailed_name = Intern(detailed); type.def.qual_name_offset = 0; type.def.short_name_offset = short_name_offset; type.def.short_name_size = short_name_size; @@ -558,7 +561,7 @@ IndexType* ResolveToDeclarationType(IndexFile* db, if (!usr) return nullptr; IndexType& typ = db->ToType(*usr); - if (typ.def.detailed_name.empty()) { + if (!typ.def.detailed_name[0]) { std::string name = declaration.get_spell_name(); SetTypeName(typ, declaration, nullptr, name.c_str(), param); } @@ -580,7 +583,7 @@ void SetVarDetail(IndexVar& var, if (type_name.find("(lambda at") != std::string::npos) type_name = "lambda"; if (g_config->index.comments) - def.comments = cursor.get_comments(); + def.comments = Intern(cursor.get_comments()); def.storage = GetStorageC(clang_Cursor_getStorageClass(cursor.cx_cursor)); // TODO how to make PrettyPrint'ed variable name qualified? @@ -607,16 +610,16 @@ void SetVarDetail(IndexVar& var, else hover += std::to_string(TD->getInitVal().getSExtValue()); } - def.detailed_name = std::move(qualified_name); + def.detailed_name = Intern(qualified_name); def.qual_name_offset = 0; - def.hover = hover; + def.hover = Intern(hover); } else { #if 0 def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false); #else int offset = type_name.size(); offset += ConcatTypeAndName(type_name, qualified_name); - def.detailed_name = type_name; + def.detailed_name = Intern(type_name); def.qual_name_offset = offset; def.short_name_offset += offset; // Append the textual initializer, bit field, constructor to |hover|. @@ -663,8 +666,9 @@ void SetVarDetail(IndexVar& var, std::optional spell_end = fc.ToOffset(spell_p), extent_end = fc.ToOffset(extent_p); if (extent_end && *spell_end < *extent_end) - def.hover = std::string(def.detailed_name.c_str()) + - fc.content.substr(*spell_end, *extent_end - *spell_end); + def.hover = + Intern(std::string(def.detailed_name) + + fc.content.substr(*spell_end, *extent_end - *spell_end)); } } skip:; @@ -714,7 +718,7 @@ void OnIndexReference_Function(IndexFile* db, // static const int IndexFile::kMajorVersion = 16; -const int IndexFile::kMinorVersion = 0; +const int IndexFile::kMinorVersion = 1; IndexFile::IndexFile(const std::string& path, const std::string& contents) : path(path), file_contents(contents) {} @@ -741,7 +745,7 @@ IndexVar& IndexFile::ToVar(Usr usr) { } std::string IndexFile::ToString() { - return Serialize(SerializeFormat::Json, *this); + return ccls::Serialize(SerializeFormat::Json, *this); } void Uniquify(std::vector& usrs) { @@ -1197,16 +1201,17 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, IndexVar& var_def = db->ToVar(decl_usr); if (cursor.get_kind() == CXCursor_MacroDefinition) { CXSourceRange cx_extent = clang_getCursorExtent(cursor.cx_cursor); - var_def.def.detailed_name = cursor.get_display_name(); + var_def.def.detailed_name = Intern(cursor.get_display_name()); var_def.def.qual_name_offset = 0; var_def.def.short_name_offset = 0; var_def.def.short_name_size = - int16_t(strlen(var_def.def.detailed_name.c_str())); + int16_t(strlen(var_def.def.detailed_name)); var_def.def.hover = - "#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent); + Intern("#define " + + GetDocumentContentInRange(param->tu->cx_tu, cx_extent)); var_def.def.kind = lsSymbolKind::Macro; if (g_config->index.comments) - var_def.def.comments = cursor.get_comments(); + var_def.def.comments = Intern(cursor.get_comments()); var_def.def.spell = SetUse(db, decl_loc_spelling, parent, Role::Definition); var_def.def.extent = SetUse( @@ -1244,7 +1249,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); if (ref_cursor.get_kind() == CXCursor_NonTypeTemplateParameter) { IndexVar& ref_var = db->ToVar(ref_cursor); - if (ref_var.def.detailed_name.empty()) { + if (!ref_var.def.detailed_name[0]) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); ref_var.def.spell = @@ -1298,7 +1303,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, // CXCursor_TemplateTemplateParameter can be visited by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting // {Class,Function}Template. Thus we need to initialize it here. - if (ref_type.def.detailed_name.empty()) { + if (!ref_type.def.detailed_name[0]) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); ref_type.def.spell = @@ -1308,11 +1313,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, #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(); + ref_type.def.detailed_name = Intern(ref_cursor.get_spell_name()); #endif ref_type.def.short_name_offset = 0; ref_type.def.short_name_size = - int16_t(strlen(ref_type.def.detailed_name.c_str())); + int16_t(strlen(ref_type.def.detailed_name)); ref_type.def.kind = lsSymbolKind::TypeParameter; } AddUseSpell(db, ref_type.uses, cursor); @@ -1328,7 +1333,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, // CXCursor_TemplateTypeParameter can be visited by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting // {Class,Function}Template. Thus we need to initialize it here. - if (ref_type.def.detailed_name.empty()) { + if (!ref_type.def.detailed_name[0]) { ClangCursor sem_parent = ref_cursor.get_semantic_parent(); ClangCursor lex_parent = ref_cursor.get_lexical_parent(); ref_type.def.spell = @@ -1339,11 +1344,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, // template void f(T t){} // weird, the name is empty ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); #else - ref_type.def.detailed_name = ref_cursor.get_spell_name(); + ref_type.def.detailed_name = Intern(ref_cursor.get_spell_name()); #endif ref_type.def.short_name_offset = 0; ref_type.def.short_name_size = - int16_t(strlen(ref_type.def.detailed_name.c_str())); + int16_t(strlen(ref_type.def.detailed_name)); ref_type.def.kind = lsSymbolKind::TypeParameter; } AddUseSpell(db, ref_type.uses, cursor); @@ -1443,7 +1448,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { Range spell = cursor.get_spell(); IndexType& ns = db->ToType(HashUsr(decl->entityInfo->USR)); ns.def.kind = GetSymbolKind(decl->entityInfo->kind); - if (ns.def.detailed_name.empty()) { + if (!ns.def.detailed_name[0]) { SetTypeName(ns, cursor, decl->semanticContainer, decl->entityInfo->name, param); ns.def.spell = SetUse(db, spell, sem_parent, Role::Definition); @@ -1559,7 +1564,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { IndexFunc& func = db->ToFunc(decl_cursor_resolved); if (g_config->index.comments) - func.def.comments = cursor.get_comments(); + func.def.comments = Intern(cursor.get_comments()); func.def.kind = GetSymbolKind(decl->entityInfo->kind); func.def.storage = GetStorageC(clang_Cursor_getStorageClass(decl->cursor)); @@ -1592,9 +1597,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // indexing the definition, then there will not be any (ie) outline // information. if (!is_template_specialization) { - std::tie(func.def.detailed_name, func.def.qual_name_offset, + std::string detailed; + std::tie(detailed, func.def.qual_name_offset, func.def.short_name_offset, func.def.short_name_size) = param->PrettyPrintCursor(decl->cursor, decl->entityInfo->name); + func.def.detailed_name = Intern(detailed); // CXCursor_OverloadedDeclRef in templates are not processed by // OnIndexReference, thus we use TemplateVisitor to collect function @@ -1668,7 +1675,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { decl->entityInfo->name, param); type.def.kind = GetSymbolKind(decl->entityInfo->kind); if (g_config->index.comments) - type.def.comments = cursor.get_comments(); + type.def.comments = Intern(cursor.get_comments()); // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. @@ -1679,10 +1686,10 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { spell_end = fc.ToOffset(spell.end), extent_end = fc.ToOffset(extent.end); if (extent_start && spell_start && spell_end && extent_end) { - type.def.hover = + type.def.hover = Intern( fc.content.substr(*extent_start, *spell_start - *extent_start) + - type.def.detailed_name.c_str() + - fc.content.substr(*spell_end, *extent_end - *spell_end); + type.def.detailed_name + + fc.content.substr(*spell_end, *extent_end - *spell_end)); } } @@ -1711,7 +1718,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { param); type.def.kind = GetSymbolKind(decl->entityInfo->kind); if (g_config->index.comments) - type.def.comments = cursor.get_comments(); + type.def.comments = Intern(cursor.get_comments()); // } if (decl->isDefinition) { @@ -1743,7 +1750,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // template class function; // not visited by // OnIndexDeclaration template<> class function {}; // current // cursor - if (origin.def.detailed_name.empty()) { + if (!origin.def.detailed_name[0]) { SetTypeName(origin, origin_cursor, nullptr, &type.def.Name(false)[0], param); origin.def.kind = type.def.kind; @@ -1895,7 +1902,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { // may not have a short_name yet. Note that we only process the lambda // parameter as a definition if it is in the same file as the reference, // as lambdas cannot be split across files. - if (var.def.detailed_name.empty()) { + if (!var.def.detailed_name[0]) { CXFile referenced_file; Range spell = referenced.get_spell(&referenced_file); if (file == referenced_file) { diff --git a/src/indexer.h b/src/indexer.h index 156f7c662..b7f06e15e 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -6,7 +6,6 @@ #include "language.h" #include "lsp.h" #include "maybe.h" -#include "nt_string.h" #include "position.h" #include "serializer.h" #include "symbol.h" @@ -69,21 +68,21 @@ template struct NameMixin { std::string_view Name(bool qualified) const { auto self = static_cast(this); - return qualified ? std::string_view( - self->detailed_name.c_str() + self->qual_name_offset, - self->short_name_offset - self->qual_name_offset + - self->short_name_size) - : std::string_view(self->detailed_name.c_str() + - self->short_name_offset, - self->short_name_size); + return qualified + ? std::string_view(self->detailed_name + self->qual_name_offset, + self->short_name_offset - + self->qual_name_offset + + self->short_name_size) + : std::string_view(self->detailed_name + self->short_name_offset, + self->short_name_size); } }; struct FuncDef : NameMixin { // General metadata. - std::string detailed_name; - NtString hover; - NtString comments; + const char* detailed_name = ""; + const char* hover = ""; + const char* comments = ""; Maybe spell; Maybe extent; @@ -105,13 +104,6 @@ struct FuncDef : NameMixin { clang::StorageClass storage = clang::SC_None; std::vector GetBases() const { return bases; } - bool operator==(const FuncDef& o) const { - return detailed_name == o.detailed_name && spell == o.spell && - extent == o.extent && declaring_type == o.declaring_type && - bases == o.bases && vars == o.vars && callees == o.callees && - kind == o.kind && storage == o.storage && hover == o.hover && - comments == o.comments; - } }; MAKE_REFLECT_STRUCT(FuncDef, detailed_name, @@ -139,10 +131,9 @@ struct IndexFunc : NameMixin { }; struct TypeDef : NameMixin { - // General metadata. - std::string detailed_name; - NtString hover; - NtString comments; + const char* detailed_name = ""; + const char* hover = ""; + const char* comments = ""; Maybe spell; Maybe extent; @@ -164,12 +155,6 @@ struct TypeDef : NameMixin { lsSymbolKind kind = lsSymbolKind::Unknown; std::vector GetBases() const { return bases; } - bool operator==(const TypeDef& o) const { - return detailed_name == o.detailed_name && spell == o.spell && - extent == o.extent && alias_of == o.alias_of && bases == o.bases && - types == o.types && funcs == o.funcs && vars == o.vars && - kind == o.kind && hover == o.hover && comments == o.comments; - } }; MAKE_REFLECT_STRUCT(TypeDef, detailed_name, @@ -199,9 +184,9 @@ struct IndexType { struct VarDef : NameMixin { // General metadata. - std::string detailed_name; - NtString hover; - NtString comments; + const char* detailed_name = ""; + const char* hover = ""; + const char* comments = ""; Maybe spell; Maybe extent; @@ -224,11 +209,6 @@ struct VarDef : NameMixin { } std::vector GetBases() const { return {}; } - bool operator==(const VarDef& 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; - } }; MAKE_REFLECT_STRUCT(VarDef, detailed_name, diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 9fa7cd6eb..0f2132d89 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -94,9 +94,11 @@ void DoField(MessageHandler* m, } if (qualified) entry1.fieldName += def1->detailed_name; - else - entry1.fieldName += def1->detailed_name.substr(0, def1->qual_name_offset) + - std::string(def1->Name(false)); + else { + entry1.fieldName += + std::string_view(def1->detailed_name).substr(0, def1->qual_name_offset); + entry1.fieldName += def1->Name(false); + } if (def1->spell) { if (std::optional loc = GetLsLocation(m->db, m->working_files, *def1->spell)) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 55d8a2e67..bed6295d1 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,4 +1,3 @@ -#include "diagnostics_publisher.hh" #include "filesystem.hh" #include "include_complete.h" #include "log.hh" diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 043953d34..36f5c710f 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -11,7 +11,7 @@ std::optional GetComments(DB* db, SymbolRef sym) { std::optional ret; WithEntity(db, sym, [&](const auto& entity) { if (const auto* def = entity.AnyDef()) - if (!def->comments.empty()) { + if (def->comments[0]) { lsMarkedString m; m.value = def->comments; ret = m; @@ -29,10 +29,10 @@ std::optional GetHoverOrName(DB* db, if (const auto* def = entity.AnyDef()) { lsMarkedString m; m.language = LanguageIdentifier(lang); - if (!def->hover.empty()) { + if (def->hover[0]) { m.value = def->hover; ret = m; - } else if (!def->detailed_name.empty()) { + } else if (def->detailed_name[0]) { m.value = def->detailed_name; ret = m; } diff --git a/src/method.cc b/src/method.cc index 38da766aa..722d6fb21 100644 --- a/src/method.cc +++ b/src/method.cc @@ -18,7 +18,7 @@ void Reflect(Reader& visitor, lsRequestId& value) { value.value = visitor.GetInt(); } else if (visitor.IsString()) { value.type = lsRequestId::kString; - value.value = atoll(visitor.GetString().c_str()); + value.value = atoll(visitor.GetString()); } else { value.type = lsRequestId::kNone; value.value = -1; diff --git a/src/nt_string.h b/src/nt_string.h deleted file mode 100644 index 0bc1e2c68..000000000 --- a/src/nt_string.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -// Nullable null-terminated string, which is null if default constructed, -// but non-null if assigned. -// This is used in Query{Func,Type,Var}::def to reduce memory footprint. -class NtString { - using size_type = std::string::size_type; - std::unique_ptr str; - - public: - NtString() = default; - NtString(NtString&& o) = default; - NtString(const NtString& o) { *this = o; } - NtString(std::string_view sv) { *this = sv; } - - const char* c_str() const { return str.get(); } - operator std::string_view() const { - if (c_str()) - return c_str(); - return {}; - } - bool empty() const { return !str || *c_str() == '\0'; } - - void operator=(std::string_view sv) { - str = std::unique_ptr(new char[sv.size() + 1]); - memcpy(str.get(), sv.data(), sv.size()); - str.get()[sv.size()] = '\0'; - } - void operator=(const NtString& o) { - *this = static_cast(o); - } - bool operator==(const NtString& o) const { - return str && o.str ? strcmp(c_str(), o.c_str()) == 0 - : c_str() == o.c_str(); - } -}; diff --git a/src/pipeline.cc b/src/pipeline.cc index aea96e265..13cef3954 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -2,7 +2,6 @@ #include "clang_complete.h" #include "config.h" -#include "diagnostics_publisher.hh" #include "include_complete.h" #include "log.hh" #include "lsp.h" @@ -17,8 +16,42 @@ #include using namespace llvm; +#include #include +void DiagnosticsPublisher::Init() { + frequencyMs_ = g_config->diagnostics.frequencyMs; + match_ = std::make_unique(g_config->diagnostics.whitelist, + g_config->diagnostics.blacklist); +} + +void DiagnosticsPublisher::Publish(WorkingFiles* working_files, + std::string path, + std::vector diagnostics) { + // Cache diagnostics so we can show fixits. + working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { + if (working_file) + working_file->diagnostics_ = diagnostics; + }); + + int64_t now = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + if (frequencyMs_ >= 0 && (nextPublish_ <= now || diagnostics.empty()) && + match_->IsMatch(path)) { + nextPublish_ = now + frequencyMs_; + + Out_TextDocumentPublishDiagnostics out; + out.params.uri = lsDocumentUri::FromPath(path); + out.params.diagnostics = diagnostics; + ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); + } +} + +namespace ccls::pipeline { +namespace { + struct Index_Request { std::string path; std::vector args; @@ -31,9 +64,6 @@ struct Stdout_Request { std::string content; }; -namespace ccls::pipeline { -namespace { - MultiQueueWaiter* main_waiter; MultiQueueWaiter* indexer_waiter; MultiQueueWaiter* stdout_waiter; @@ -115,8 +145,9 @@ std::unique_ptr RawCacheLoad( if (!file_content || !serialized_indexed_content) return nullptr; - return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, - *file_content, IndexFile::kMajorVersion); + return ccls::Deserialize(g_config->cacheFormat, path, + *serialized_indexed_content, *file_content, + IndexFile::kMajorVersion); } bool Indexer_Parse(DiagnosticsPublisher* diag_pub, diff --git a/src/pipeline.hh b/src/pipeline.hh index a3926594b..d3c7dcf4f 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,5 +1,6 @@ #pragma once +#include "lsp_diagnostic.h" #include "method.h" #include "query.h" @@ -7,12 +8,24 @@ #include #include -class DiagnosticsPublisher; +struct GroupMatch; struct VFS; struct Project; struct WorkingFiles; struct lsBaseOutMessage; +class DiagnosticsPublisher { + std::unique_ptr match_; + int64_t nextPublish_ = 0; + int frequencyMs_; + + public: + void Init(); + void Publish(WorkingFiles* working_files, + std::string path, + std::vector diagnostics); +}; + namespace ccls::pipeline { void Init(); diff --git a/src/query.cc b/src/query.cc index c4ef41294..dac2bc96a 100644 --- a/src/query.cc +++ b/src/query.cc @@ -189,7 +189,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, } for (auto& it : current->usr2func) { auto& func = it.second; - if (func.def.spell && func.def.detailed_name.size()) + if (func.def.spell && func.def.detailed_name[0]) r.funcs_def_update.emplace_back(it.first, func.def); r.funcs_declarations[func.usr].second = std::move(func.declarations); r.funcs_uses[func.usr].second = std::move(func.uses); @@ -208,7 +208,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, }; for (auto& it : current->usr2type) { auto& type = it.second; - if (type.def.spell && type.def.detailed_name.size()) + if (type.def.spell && type.def.detailed_name[0]) r.types_def_update.emplace_back(it.first, type.def); r.types_declarations[type.usr].second = std::move(type.declarations); r.types_uses[type.usr].second = std::move(type.uses); @@ -226,7 +226,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, } for (auto& it : current->usr2var) { auto& var = it.second; - if (var.def.spell && var.def.detailed_name.size()) + if (var.def.spell && var.def.detailed_name[0]) r.vars_def_update.emplace_back(it.first, var.def); r.vars_declarations[var.usr].second = std::move(var.declarations); r.vars_uses[var.usr].second = std::move(var.uses); @@ -353,7 +353,7 @@ int DB::Update(QueryFile::DefUpdate&& u) { void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; - assert(!def.detailed_name.empty()); + assert(def.detailed_name[0]); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); AssignFileId(file_id, def.callees); @@ -370,7 +370,7 @@ void DB::Update(int file_id, std::vector>&& us) { void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; - assert(!def.detailed_name.empty()); + assert(def.detailed_name[0]); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); auto R = type_usr.try_emplace({u.first}, type_usr.size()); @@ -387,7 +387,7 @@ void DB::Update(int file_id, std::vector>&& us) { void DB::Update(int file_id, std::vector>&& us) { for (auto& u : us) { auto& def = u.second; - assert(!def.detailed_name.empty()); + assert(def.detailed_name[0]); AssignFileId(file_id, def.spell); AssignFileId(file_id, def.extent); auto R = var_usr.try_emplace({u.first}, var_usr.size()); diff --git a/src/serializer.cc b/src/serializer.cc index 72090c6ec..e29c1674a 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,12 +1,15 @@ #include "serializer.h" #include "filesystem.hh" +#include "indexer.h" #include "log.hh" #include "serializers/binary.h" #include "serializers/json.h" -#include "indexer.h" +#include +#include +#include #include using namespace llvm; @@ -131,14 +134,12 @@ void Reflect(Writer& visitor, std::string_view& data) { visitor.String(&data[0], (rapidjson::SizeType)data.size()); } -void Reflect(Reader& visitor, NtString& value) { - if (!visitor.IsString()) - throw std::invalid_argument("std::string"); - value = visitor.GetString(); +void Reflect(Reader& vis, const char*& v) { + const char* str = vis.GetString(); + v = ccls::Intern(str); } -void Reflect(Writer& visitor, NtString& value) { - const char* s = value.c_str(); - visitor.String(s ? s : ""); +void Reflect(Writer& vis, const char*& v) { + vis.String(v); } void Reflect(Reader& visitor, JsonNull& value) { @@ -223,9 +224,9 @@ void ReflectHoverAndComments(Reader& visitor, Def& def) { template void ReflectHoverAndComments(Writer& visitor, Def& def) { // Don't emit empty hover and comments in JSON test mode. - if (!gTestOutputMode || !def.hover.empty()) + if (!gTestOutputMode || def.hover[0]) ReflectMember(visitor, "hover", def.hover); - if (!gTestOutputMode || !def.comments.empty()) + if (!gTestOutputMode || def.comments[0]) ReflectMember(visitor, "comments", def.comments); } @@ -234,7 +235,7 @@ void ReflectShortName(Reader& visitor, Def& def) { if (gTestOutputMode) { std::string short_name; ReflectMember(visitor, "short_name", short_name); - def.short_name_offset = def.detailed_name.find(short_name); + def.short_name_offset = std::string_view(def.detailed_name).find(short_name); assert(def.short_name_offset != std::string::npos); def.short_name_size = short_name.size(); } else { @@ -246,8 +247,8 @@ void ReflectShortName(Reader& visitor, Def& def) { template void ReflectShortName(Writer& visitor, Def& def) { if (gTestOutputMode) { - std::string short_name( - def.detailed_name.substr(def.short_name_offset, def.short_name_size)); + std::string_view short_name(def.detailed_name + def.short_name_offset, + def.short_name_size); ReflectMember(visitor, "short_name", short_name); } else { ReflectMember(visitor, "short_name_offset", def.short_name_offset); @@ -357,6 +358,21 @@ void Reflect(Writer& visitor, SerializeFormat& value) { } } +namespace ccls { +static BumpPtrAllocator Alloc; +static DenseSet Strings; +static std::mutex AllocMutex; + +const char* Intern(const std::string& str) { + if (str.empty()) return ""; + StringRef Str(str.data(), str.size() + 1); + std::lock_guard lock(AllocMutex); + auto R = Strings.insert(Str); + if (R.second) + *R.first = Str.copy(Alloc); + return R.first->data(); +} + std::string Serialize(SerializeFormat format, IndexFile& file) { switch (format) { case SerializeFormat::Binary: { @@ -451,3 +467,4 @@ std::unique_ptr Deserialize( file->path = path; return file; } +} diff --git a/src/serializer.h b/src/serializer.h index d2ee11915..1bbbc3579 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -1,7 +1,6 @@ #pragma once #include "maybe.h" -#include "nt_string.h" #include @@ -42,7 +41,7 @@ class Reader { virtual int64_t GetInt64() = 0; virtual uint64_t GetUInt64() = 0; virtual double GetDouble() = 0; - virtual std::string GetString() = 0; + virtual const char* GetString() = 0; virtual bool HasMember(const char* x) = 0; virtual std::unique_ptr operator[](const char* x) = 0; @@ -180,8 +179,8 @@ void Reflect(Writer& visitor, std::string& value); void Reflect(Reader& visitor, std::string_view& view); void Reflect(Writer& visitor, std::string_view& view); -void Reflect(Reader& visitor, NtString& value); -void Reflect(Writer& visitor, NtString& value); +void Reflect(Reader& vis, const char*& v); +void Reflect(Writer& vis, const char*& v); void Reflect(Reader& visitor, JsonNull& value); void Reflect(Writer& visitor, JsonNull& value); @@ -322,6 +321,8 @@ void ReflectMember(Writer& vis, const char* name, T& v) { // API +namespace ccls { +const char* Intern(const std::string& str); std::string Serialize(SerializeFormat format, IndexFile& file); std::unique_ptr Deserialize( SerializeFormat format, @@ -329,3 +330,4 @@ std::unique_ptr Deserialize( const std::string& serialized_index_content, const std::string& file_content, std::optional expected_version); +} diff --git a/src/serializers/binary.h b/src/serializers/binary.h index 821c4367b..7327ba158 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -52,13 +52,12 @@ class BinaryReader : public Reader { uint32_t GetUInt32() override { return VarUInt(); } uint64_t GetUInt64() override { return VarUInt(); } double GetDouble() override { return Get(); } - std::string GetString() override { - if (auto n = VarUInt()) { - std::string ret(p_, n); - p_ += n; - return ret; - } - return ""; + const char* GetString() override { + const char* ret = p_; + while (*p_) + p_++; + p_++; + return ret; } bool HasMember(const char* x) override { return true; } @@ -118,9 +117,8 @@ class BinaryWriter : public Writer { void Double(double x) override { Pack(x); } void String(const char* x) override { String(x, strlen(x)); } void String(const char* x, size_t len) override { - VarUInt(len); auto i = buf_.size(); - buf_.resize(i + len); + buf_.resize(i + len + 1); memcpy(buf_.data() + i, x, len); } void StartArray(size_t n) override { VarUInt(n); } diff --git a/src/serializers/json.h b/src/serializers/json.h index b5c84c04b..b650f83b4 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -29,7 +29,7 @@ class JsonReader : public Reader { uint32_t GetUInt32() override { return uint32_t(m_->GetUint64()); } uint64_t GetUInt64() override { return m_->GetUint64(); } double GetDouble() override { return m_->GetDouble(); } - std::string GetString() override { return m_->GetString(); } + const char* GetString() override { return m_->GetString(); } bool HasMember(const char* x) override { return m_->HasMember(x); } std::unique_ptr operator[](const char* x) override { diff --git a/src/test.cc b/src/test.cc index c9dff5cf9..4ba660716 100644 --- a/src/test.cc +++ b/src/test.cc @@ -191,10 +191,10 @@ void DiffDocuments(std::string path, void VerifySerializeToFrom(IndexFile* file) { std::string expected = file->ToString(); - std::string serialized = Serialize(SerializeFormat::Json, *file); + std::string serialized = ccls::Serialize(SerializeFormat::Json, *file); std::unique_ptr result = - Deserialize(SerializeFormat::Json, "--.cc", serialized, "", - std::nullopt /*expected_version*/); + ccls::Deserialize(SerializeFormat::Json, "--.cc", serialized, "", + std::nullopt /*expected_version*/); std::string actual = result->ToString(); if (expected != actual) { fprintf(stderr, "Serialization failure\n"); From 6a1902aeb6485a0c1901d2ae57e537ee75ad211e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 8 Jun 2018 18:20:51 -0700 Subject: [PATCH 118/378] Fix .. in compdb path; better type alias --- index_tests/types/anonymous_struct.cc | 9 +++++++ src/clang_tu.cc | 9 +++---- src/indexer.cc | 37 ++++++++++++--------------- src/pipeline.cc | 17 +++--------- src/project.cc | 2 +- 5 files changed, 33 insertions(+), 41 deletions(-) diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 5a70a8174..b52a6ff76 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -65,6 +65,15 @@ union vector3 { "types": [], "funcs": [], "vars": [{ + "L": 3348817847649945564, + "R": -1 + }, { + "L": 4821094820988543895, + "R": -1 + }, { + "L": 15292551660437765731, + "R": -1 + }, { "L": 1963212417280098348, "R": 0 }], diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 8b5b1450e..563adbec1 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -401,12 +401,9 @@ std::unique_ptr ClangTranslationUnit::Create( std::unique_ptr ClangTranslationUnit::Reparse( std::unique_ptr tu, std::vector& unsaved) { - int error_code; - { - error_code = clang_reparseTranslationUnit( - tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), - clang_defaultReparseOptions(tu->cx_tu)); - } + int error_code = clang_reparseTranslationUnit( + tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), + clang_defaultReparseOptions(tu->cx_tu)); if (error_code != CXError_Success && tu->cx_tu) EmitDiagnostics("", {}, tu->cx_tu); diff --git a/src/indexer.cc b/src/indexer.cc index 1e5720b95..229e671bd 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1655,16 +1655,23 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { case CXIdxEntity_Typedef: case CXIdxEntity_CXXTypeAlias: { - // Note we want to fetch the first TypeRef. Running - // ResolveCursorType(decl->cursor) would return - // the type of the typedef/using, not the type of the referenced type. - IndexType* alias_of = AddDeclTypeUsages( - db, cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); - IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); - - if (alias_of) - type.def.alias_of = alias_of->usr; + CXType Type = clang_getCursorType(decl->entityInfo->cursor); + CXType CanonType = clang_getCanonicalType(Type);; + if (clang_equalTypes(Type, CanonType) == 0) { + Usr type_usr = ClangType(CanonType).get_usr_hash(); + if (db->usr2type.count(type_usr)) { + type.def.alias_of = type_usr; + } else { + // Note we want to fetch the first TypeRef. Running + // ResolveCursorType(decl->cursor) would return + // the type of the typedef/using, not the type of the referenced type. + IndexType* alias_of = AddDeclTypeUsages( + db, cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); + if (alias_of) + type.def.alias_of = alias_of->usr; + } + } Range spell = cursor.get_spell(); Range extent = cursor.get_extent(); @@ -1709,17 +1716,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); - // TODO: Eventually run with this if. Right now I want to iron out bugs - // this may shadow. - // TODO: For type section, verify if this ever runs for non definitions? - // if (!decl->isRedeclaration) { - SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, param); type.def.kind = GetSymbolKind(decl->entityInfo->kind); if (g_config->index.comments) type.def.comments = Intern(cursor.get_comments()); - // } if (decl->isDefinition) { type.def.spell = SetUse(db, spell, sem_parent, Role::Definition); @@ -1781,12 +1782,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { } } - // type_def->alias_of - // type_def->funcs - // type_def->types - // type_def->uses - // type_def->vars - // Add type-level inheritance information. CXIdxCXXClassDeclInfo const* class_info = clang_index_getCXXClassDeclInfo(decl); diff --git a/src/pipeline.cc b/src/pipeline.cc index 13cef3954..d511b1c3a 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -94,17 +94,9 @@ bool FileNeedsParse(int64_t write_time, } // Command-line arguments changed. - auto is_file = [](const std::string& arg) { - return EndsWithAny(arg, {".h", ".c", ".cc", ".cpp", ".hpp", ".m", ".mm"}); - }; if (opt_previous_index) { auto& prev_args = opt_previous_index->args; - bool same = prev_args.size() == args.size(); - for (size_t i = 0; i < args.size() && same; ++i) { - same = prev_args[i] == args[i] || - (is_file(prev_args[i]) && is_file(args[i])); - } - if (!same) { + if (prev_args != args) { LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); return true; } @@ -483,11 +475,10 @@ void MainLoop() { Main_OnIndexed(&db, &semantic_cache, &working_files, &*update); } - // Cleanup and free any unused memory. - FreeUnusedMemory(); - - if (!did_work) + if (!did_work) { + FreeUnusedMemory(); main_waiter->Wait(on_indexed, on_request); + } } } diff --git a/src/project.cc b/src/project.cc index 4c7bf7371..db65eb684 100644 --- a/src/project.cc +++ b/src/project.cc @@ -48,7 +48,7 @@ struct CompileCommandsEntry { return path; SmallString<256> Ret; sys::path::append(Ret, directory, path); - return Ret.str(); + return NormalizePath(Ret.str()); } }; MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); From c5dc759831291ef80d9e522b291e74d8ea05b712 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 17 Jun 2018 13:29:24 -0700 Subject: [PATCH 119/378] Put `static const` into IndexVar::def (a definition is not required unless odr-used) --- src/indexer.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 229e671bd..cdd7330f0 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1495,13 +1495,17 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { var.def.kind = lsSymbolKind::Parameter; //} - if (decl->isDefinition) { + if (!decl->isDefinition) + var.declarations.push_back( + SetUse(db, spell, lex_parent, Role::Declaration)); + // For `static const`, a definition at namespace scope is not required + // unless odr-used. + if (decl->isDefinition || + (decl->entityInfo->kind == CXIdxEntity_CXXStaticVariable && + clang_isConstQualifiedType(clang_getCursorType(decl->cursor)))) { var.def.spell = SetUse(db, spell, sem_parent, Role::Definition); var.def.extent = SetUse(db, cursor.get_extent(), lex_parent, Role::None); - } else { - var.declarations.push_back( - SetUse(db, spell, lex_parent, Role::Declaration)); } cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db); From 559a68a26164bb10ab711dcafc9ac5a9bb445b45 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 23 Jun 2018 10:50:08 -0700 Subject: [PATCH 120/378] Display diagnostics from header files --- src/clang_complete.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 9e54bfa84..f2408ec0c 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -604,7 +604,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { if (diagnostic && diagnostic->range.start.line >= 0) ls_diagnostics.push_back(*diagnostic); } - completion_manager->on_diagnostic_(session->file.filename, ls_diagnostics); + completion_manager->on_diagnostic_(path, ls_diagnostics); } } From 207e79ea9889df0f489c140a8f4b71ab28dcd222 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 1 Jul 2018 10:19:35 -0700 Subject: [PATCH 121/378] Use ChangeStd{in,out}ToBinary --- src/main.cc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main.cc b/src/main.cc index ebb6b4888..8c3ae83c1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -9,6 +9,7 @@ using namespace ccls; #include #include +#include #include using namespace llvm; using namespace llvm::cl; @@ -58,15 +59,6 @@ int main(int argc, char** argv) { } pipeline::Init(); - -#ifdef _WIN32 - // We need to write to stdout in binary mode because in Windows, writing - // \n will implicitly write \r\n. Language server API will ignore a - // \r\r\n split request. - _setmode(_fileno(stdout), O_BINARY); - _setmode(_fileno(stdin), O_BINARY); -#endif - IndexInit(); bool language_server = true; @@ -129,6 +121,8 @@ int main(int argc, char** argv) { } } + sys::ChangeStdinToBinary(); + sys::ChangeStdoutToBinary(); // The thread that reads from stdin and dispatchs commands to the main thread. pipeline::LaunchStdin(); // The thread that writes responses from the main thread to stdout. From 8a9640a56b75028ef3db1d7a58321442bd318575 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 1 Jul 2018 00:35:41 -0700 Subject: [PATCH 122/378] Add all to textDocument/documentSymbol --- src/messages/text_document_document_symbol.cc | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 6aec71ff9..450155e9e 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -9,8 +9,9 @@ MethodType kMethodType = "textDocument/documentSymbol"; struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; + bool all = false; }; -MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); +MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument, all); struct In_TextDocumentDocumentSymbol : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -30,35 +31,44 @@ struct Handler_TextDocumentDocumentSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDocumentSymbol* request) override { + auto& params = request->params; Out_TextDocumentDocumentSymbol out; out.id = request->id; QueryFile* file; int file_id; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) { + params.textDocument.uri.GetPath(), &file, &file_id)) return; - } - - for (SymbolRef sym : file->def->outline) { - std::optional info = - GetSymbolInfo(db, working_files, sym, false); - if (!info) - continue; - if (sym.kind == SymbolKind::Var) { - QueryVar& var = db->GetVar(sym); - auto* def = var.AnyDef(); - if (!def || !def->spell || def->is_local()) - continue; - } - if (std::optional location = GetLsLocation( - db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { - info->location = *location; - out.result.push_back(*info); - } + if (params.all) { + for (SymbolRef sym : file->def->all_symbols) + if (std::optional info = + GetSymbolInfo(db, working_files, sym, false)) { + if (std::optional location = GetLsLocation( + db, working_files, + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { + info->location = *location; + out.result.push_back(*info); + } + } + } else { + for (SymbolRef sym : file->def->outline) + if (std::optional info = + GetSymbolInfo(db, working_files, sym, false)) { + if (sym.kind == SymbolKind::Var) { + QueryVar& var = db->GetVar(sym); + auto* def = var.AnyDef(); + if (!def || !def->spell || def->is_local()) + continue; + } + if (std::optional location = GetLsLocation( + db, working_files, + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { + info->location = *location; + out.result.push_back(*info); + } + } } pipeline::WriteStdout(kMethodType, out); From 0df5a2cd661eb97e859b55f2ddb5dc965ea99c36 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 3 Jul 2018 10:44:03 -0700 Subject: [PATCH 123/378] rename --- CMakeLists.txt | 44 +++++++++---------- ...all_hierarchy.cc => ccls_callHierarchy.cc} | 0 .../{ccls_file_info.cc => ccls_fileInfo.cc} | 0 ..._freshen_index.cc => ccls_freshenIndex.cc} | 0 ...rarchy.cc => ccls_inheritanceHierarchy.cc} | 0 ...r_hierarchy.cc => ccls_memberHierarchy.cc} | 0 ..._code_lens.cc => textDocument_codeLens.cc} | 0 ...mpletion.cc => textDocument_completion.cc} | 0 ...finition.cc => textDocument_definition.cc} | 0 ...id_change.cc => textDocument_didChange.cc} | 0 ..._did_close.cc => textDocument_didClose.cc} | 0 ...nt_did_open.cc => textDocument_didOpen.cc} | 0 ...nt_did_save.cc => textDocument_didSave.cc} | 0 ...t.cc => textDocument_documentHighlight.cc} | 0 ...mbol.cc => textDocument_documentSymbol.cc} | 38 ++++++++++------ ...ocument_hover.cc => textDocument_hover.cc} | 0 ...tion.cc => textDocument_implementation.cc} | 0 ...ferences.cc => textDocument_references.cc} | 0 ...ument_rename.cc => textDocument_rename.cc} | 0 ..._help.cc => textDocument_signatureHelp.cc} | 0 ...tion.cc => textDocument_typeDefinition.cc} | 0 ...cc => workspace_didChangeConfiguration.cc} | 0 ....cc => workspace_didChangeWatchedFiles.cc} | 0 ...command.cc => workspace_executeCommand.cc} | 0 24 files changed, 47 insertions(+), 35 deletions(-) rename src/messages/{ccls_call_hierarchy.cc => ccls_callHierarchy.cc} (100%) rename src/messages/{ccls_file_info.cc => ccls_fileInfo.cc} (100%) rename src/messages/{ccls_freshen_index.cc => ccls_freshenIndex.cc} (100%) rename src/messages/{ccls_inheritance_hierarchy.cc => ccls_inheritanceHierarchy.cc} (100%) rename src/messages/{ccls_member_hierarchy.cc => ccls_memberHierarchy.cc} (100%) rename src/messages/{text_document_code_lens.cc => textDocument_codeLens.cc} (100%) rename src/messages/{text_document_completion.cc => textDocument_completion.cc} (100%) rename src/messages/{text_document_definition.cc => textDocument_definition.cc} (100%) rename src/messages/{text_document_did_change.cc => textDocument_didChange.cc} (100%) rename src/messages/{text_document_did_close.cc => textDocument_didClose.cc} (100%) rename src/messages/{text_document_did_open.cc => textDocument_didOpen.cc} (100%) rename src/messages/{text_document_did_save.cc => textDocument_didSave.cc} (100%) rename src/messages/{text_document_document_highlight.cc => textDocument_documentHighlight.cc} (100%) rename src/messages/{text_document_document_symbol.cc => textDocument_documentSymbol.cc} (70%) rename src/messages/{text_document_hover.cc => textDocument_hover.cc} (100%) rename src/messages/{text_document_implementation.cc => textDocument_implementation.cc} (100%) rename src/messages/{text_document_references.cc => textDocument_references.cc} (100%) rename src/messages/{text_document_rename.cc => textDocument_rename.cc} (100%) rename src/messages/{text_document_signature_help.cc => textDocument_signatureHelp.cc} (100%) rename src/messages/{text_document_type_definition.cc => textDocument_typeDefinition.cc} (100%) rename src/messages/{workspace_did_change_configuration.cc => workspace_didChangeConfiguration.cc} (100%) rename src/messages/{workspace_did_change_watched_files.cc => workspace_didChangeWatchedFiles.cc} (100%) rename src/messages/{workspace_execute_command.cc => workspace_executeCommand.cc} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b35acd4a7..cfabeb329 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,32 +220,32 @@ target_sources(ccls PRIVATE target_sources(ccls PRIVATE src/messages/ccls_base.cc - src/messages/ccls_call_hierarchy.cc + src/messages/ccls_callHierarchy.cc src/messages/ccls_callers.cc - src/messages/ccls_file_info.cc - src/messages/ccls_freshen_index.cc - src/messages/ccls_inheritance_hierarchy.cc - src/messages/ccls_member_hierarchy.cc + src/messages/ccls_fileInfo.cc + src/messages/ccls_freshenIndex.cc + src/messages/ccls_inheritanceHierarchy.cc + src/messages/ccls_memberHierarchy.cc src/messages/ccls_vars.cc src/messages/exit.cc src/messages/initialize.cc src/messages/shutdown.cc - src/messages/text_document_code_lens.cc - src/messages/text_document_completion.cc - src/messages/text_document_definition.cc - src/messages/text_document_did_change.cc - src/messages/text_document_did_close.cc - src/messages/text_document_did_open.cc - src/messages/text_document_did_save.cc - src/messages/text_document_document_highlight.cc - src/messages/text_document_document_symbol.cc - src/messages/text_document_hover.cc - src/messages/text_document_implementation.cc - src/messages/text_document_references.cc - src/messages/text_document_rename.cc - src/messages/text_document_signature_help.cc - src/messages/text_document_type_definition.cc - src/messages/workspace_did_change_configuration.cc - src/messages/workspace_did_change_watched_files.cc + src/messages/textDocument_codeLens.cc + src/messages/textDocument_completion.cc + src/messages/textDocument_definition.cc + src/messages/textDocument_didChange.cc + src/messages/textDocument_didClose.cc + src/messages/textDocument_didOpen.cc + src/messages/textDocument_didSave.cc + src/messages/textDocument_documentHighlight.cc + src/messages/textDocument_documentSymbol.cc + src/messages/textDocument_hover.cc + src/messages/textDocument_implementation.cc + src/messages/textDocument_references.cc + src/messages/textDocument_rename.cc + src/messages/textDocument_signatureHelp.cc + src/messages/textDocument_typeDefinition.cc + src/messages/workspace_didChangeConfiguration.cc + src/messages/workspace_didChangeWatchedFiles.cc src/messages/workspace_symbol.cc ) diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_callHierarchy.cc similarity index 100% rename from src/messages/ccls_call_hierarchy.cc rename to src/messages/ccls_callHierarchy.cc diff --git a/src/messages/ccls_file_info.cc b/src/messages/ccls_fileInfo.cc similarity index 100% rename from src/messages/ccls_file_info.cc rename to src/messages/ccls_fileInfo.cc diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshenIndex.cc similarity index 100% rename from src/messages/ccls_freshen_index.cc rename to src/messages/ccls_freshenIndex.cc diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc similarity index 100% rename from src/messages/ccls_inheritance_hierarchy.cc rename to src/messages/ccls_inheritanceHierarchy.cc diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_memberHierarchy.cc similarity index 100% rename from src/messages/ccls_member_hierarchy.cc rename to src/messages/ccls_memberHierarchy.cc diff --git a/src/messages/text_document_code_lens.cc b/src/messages/textDocument_codeLens.cc similarity index 100% rename from src/messages/text_document_code_lens.cc rename to src/messages/textDocument_codeLens.cc diff --git a/src/messages/text_document_completion.cc b/src/messages/textDocument_completion.cc similarity index 100% rename from src/messages/text_document_completion.cc rename to src/messages/textDocument_completion.cc diff --git a/src/messages/text_document_definition.cc b/src/messages/textDocument_definition.cc similarity index 100% rename from src/messages/text_document_definition.cc rename to src/messages/textDocument_definition.cc diff --git a/src/messages/text_document_did_change.cc b/src/messages/textDocument_didChange.cc similarity index 100% rename from src/messages/text_document_did_change.cc rename to src/messages/textDocument_didChange.cc diff --git a/src/messages/text_document_did_close.cc b/src/messages/textDocument_didClose.cc similarity index 100% rename from src/messages/text_document_did_close.cc rename to src/messages/textDocument_didClose.cc diff --git a/src/messages/text_document_did_open.cc b/src/messages/textDocument_didOpen.cc similarity index 100% rename from src/messages/text_document_did_open.cc rename to src/messages/textDocument_didOpen.cc diff --git a/src/messages/text_document_did_save.cc b/src/messages/textDocument_didSave.cc similarity index 100% rename from src/messages/text_document_did_save.cc rename to src/messages/textDocument_didSave.cc diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/textDocument_documentHighlight.cc similarity index 100% rename from src/messages/text_document_document_highlight.cc rename to src/messages/textDocument_documentHighlight.cc diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/textDocument_documentSymbol.cc similarity index 70% rename from src/messages/text_document_document_symbol.cc rename to src/messages/textDocument_documentSymbol.cc index 450155e9e..a66ffec29 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -20,6 +20,21 @@ struct In_TextDocumentDocumentSymbol : public RequestInMessage { MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); +struct lsSimpleLocation { + lsRange range; +}; +MAKE_REFLECT_STRUCT(lsSimpleLocation, range); +struct lsSimpleSymbolInformation { + lsSimpleLocation location; +}; +MAKE_REFLECT_STRUCT(lsSimpleSymbolInformation, location); +struct Out_SimpleDocumentSymbol + : public lsOutMessage { + lsRequestId id; + std::vector result; +}; +MAKE_REFLECT_STRUCT(Out_SimpleDocumentSymbol, jsonrpc, id, result); + struct Out_TextDocumentDocumentSymbol : public lsOutMessage { lsRequestId id; @@ -32,8 +47,6 @@ struct Handler_TextDocumentDocumentSymbol MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDocumentSymbol* request) override { auto& params = request->params; - Out_TextDocumentDocumentSymbol out; - out.id = request->id; QueryFile* file; int file_id; @@ -42,17 +55,17 @@ struct Handler_TextDocumentDocumentSymbol return; if (params.all) { + Out_SimpleDocumentSymbol out; + out.id = request->id; for (SymbolRef sym : file->def->all_symbols) - if (std::optional info = - GetSymbolInfo(db, working_files, sym, false)) { - if (std::optional location = GetLsLocation( - db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { - info->location = *location; - out.result.push_back(*info); - } - } + if (std::optional location = GetLsLocation( + db, working_files, + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) + out.result.push_back({{location->range}}); + pipeline::WriteStdout(kMethodType, out); } else { + Out_TextDocumentDocumentSymbol out; + out.id = request->id; for (SymbolRef sym : file->def->outline) if (std::optional info = GetSymbolInfo(db, working_files, sym, false)) { @@ -69,9 +82,8 @@ struct Handler_TextDocumentDocumentSymbol out.result.push_back(*info); } } + pipeline::WriteStdout(kMethodType, out); } - - pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); diff --git a/src/messages/text_document_hover.cc b/src/messages/textDocument_hover.cc similarity index 100% rename from src/messages/text_document_hover.cc rename to src/messages/textDocument_hover.cc diff --git a/src/messages/text_document_implementation.cc b/src/messages/textDocument_implementation.cc similarity index 100% rename from src/messages/text_document_implementation.cc rename to src/messages/textDocument_implementation.cc diff --git a/src/messages/text_document_references.cc b/src/messages/textDocument_references.cc similarity index 100% rename from src/messages/text_document_references.cc rename to src/messages/textDocument_references.cc diff --git a/src/messages/text_document_rename.cc b/src/messages/textDocument_rename.cc similarity index 100% rename from src/messages/text_document_rename.cc rename to src/messages/textDocument_rename.cc diff --git a/src/messages/text_document_signature_help.cc b/src/messages/textDocument_signatureHelp.cc similarity index 100% rename from src/messages/text_document_signature_help.cc rename to src/messages/textDocument_signatureHelp.cc diff --git a/src/messages/text_document_type_definition.cc b/src/messages/textDocument_typeDefinition.cc similarity index 100% rename from src/messages/text_document_type_definition.cc rename to src/messages/textDocument_typeDefinition.cc diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_didChangeConfiguration.cc similarity index 100% rename from src/messages/workspace_did_change_configuration.cc rename to src/messages/workspace_didChangeConfiguration.cc diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_didChangeWatchedFiles.cc similarity index 100% rename from src/messages/workspace_did_change_watched_files.cc rename to src/messages/workspace_didChangeWatchedFiles.cc diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_executeCommand.cc similarity index 100% rename from src/messages/workspace_execute_command.cc rename to src/messages/workspace_executeCommand.cc From 6a8837d612187df907550554277dce98e7f3f6c3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 3 Jul 2018 15:47:43 -0700 Subject: [PATCH 124/378] diagnostics --- src/indexer.cc | 2 +- src/messages/textDocument_completion.cc | 2 +- src/messages/textDocument_documentSymbol.cc | 25 +++++++++------------ src/pipeline.cc | 19 ++++++++++++---- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index cdd7330f0..2efecd459 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -2054,7 +2054,7 @@ std::vector> ClangIndexer::Index( file = NormalizePath(file); - Timer timer("parse", "parse tu"); + static Timer timer("parse", "parse tu"); timer.startTimer(); std::vector unsaved_files; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a35732700..1479f8030 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -164,7 +164,7 @@ void FilterAndSortCompletionResponse( if (!g_config->completion.filterAndSort) return; - Timer timer("FilterAndSortCompletionResponse", ""); + static Timer timer("FilterAndSortCompletionResponse", ""); TimeRegion region(timer); auto& items = complete_response->result.items; diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index a66ffec29..288c14ad8 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -9,9 +9,10 @@ MethodType kMethodType = "textDocument/documentSymbol"; struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; - bool all = false; + int startLine = -1; + int endLine = -1; }; -MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument, all); +MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument, startLine, endLine); struct In_TextDocumentDocumentSymbol : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -20,18 +21,10 @@ struct In_TextDocumentDocumentSymbol : public RequestInMessage { MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); -struct lsSimpleLocation { - lsRange range; -}; -MAKE_REFLECT_STRUCT(lsSimpleLocation, range); -struct lsSimpleSymbolInformation { - lsSimpleLocation location; -}; -MAKE_REFLECT_STRUCT(lsSimpleSymbolInformation, location); struct Out_SimpleDocumentSymbol : public lsOutMessage { lsRequestId id; - std::vector result; + std::vector result; }; MAKE_REFLECT_STRUCT(Out_SimpleDocumentSymbol, jsonrpc, id, result); @@ -54,14 +47,18 @@ struct Handler_TextDocumentDocumentSymbol params.textDocument.uri.GetPath(), &file, &file_id)) return; - if (params.all) { + if (params.startLine >= 0) { Out_SimpleDocumentSymbol out; out.id = request->id; for (SymbolRef sym : file->def->all_symbols) if (std::optional location = GetLsLocation( db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) - out.result.push_back({{location->range}}); + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { + if (params.startLine <= sym.range.start.line && + sym.range.start.line <= params.endLine) + out.result.push_back(location->range); + } + std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); } else { Out_TextDocumentDocumentSymbol out; diff --git a/src/pipeline.cc b/src/pipeline.cc index d511b1c3a..cd8a8482c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -18,6 +18,9 @@ using namespace llvm; #include #include +#ifndef _WIN32 +#include +#endif void DiagnosticsPublisher::Init() { frequencyMs_ = g_config->diagnostics.frequencyMs; @@ -28,17 +31,21 @@ void DiagnosticsPublisher::Init() { void DiagnosticsPublisher::Publish(WorkingFiles* working_files, std::string path, std::vector diagnostics) { + bool good = true; // Cache diagnostics so we can show fixits. working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { - if (working_file) + if (working_file) { + good = working_file->diagnostics_.empty(); working_file->diagnostics_ = diagnostics; + } }); int64_t now = std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch()) .count(); - if (frequencyMs_ >= 0 && (nextPublish_ <= now || diagnostics.empty()) && + if (frequencyMs_ >= 0 && + (nextPublish_ <= now || (!good && diagnostics.empty())) && match_->IsMatch(path)) { nextPublish_ = now + frequencyMs_; @@ -258,7 +265,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, // Write current index to disk if requested. LOG_S(INFO) << "store index for " << path; { - Timer timer("write", "store index"); + static Timer timer("write", "store index"); timer.startTimer(); std::string cache_path = GetCachePath(path); WriteToFile(cache_path, curr->file_contents); @@ -328,7 +335,7 @@ void Main_OnIndexed(DB* db, return; } - Timer timer("apply", "apply index"); + static Timer timer("apply", "apply index"); timer.startTimer(); db->ApplyIndexUpdate(update); timer.stopTimer(); @@ -397,8 +404,12 @@ void LaunchStdout() { } for (auto& message : messages) { +#ifdef _WIN32 fwrite(message.content.c_str(), message.content.size(), 1, stdout); fflush(stdout); +#else + write(1, message.content.c_str(), message.content.size()); +#endif } } }).detach(); From f81454b9ec265334beecaf945ffb2405c32f4443 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 4 Jul 2018 19:16:56 -0700 Subject: [PATCH 125/378] textDocument/references: add excludeRole --- src/messages/textDocument_references.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index d8d60f11a..479a72ef7 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -12,10 +12,12 @@ struct In_TextDocumentReferences : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct lsReferenceContext { bool base = true; + // Exclude references with any |Role| bits set. + Role excludeRole = Role::None; // Include the declaration of the current symbol. bool includeDeclaration = false; - // Include references with these |Role| bits set. - Role role = Role::All; + // Include references with all |Role| bits set. + Role role = Role::None; }; struct Params { lsTextDocumentIdentifier textDocument; @@ -27,6 +29,7 @@ struct In_TextDocumentReferences : public RequestInMessage { }; MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, base, + excludeRole, includeDeclaration, role); MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, @@ -72,7 +75,8 @@ struct Handler_TextDocumentReferences sym.usr = stack.back(); stack.pop_back(); auto fn = [&](Use use, lsSymbolKind parent_kind) { - if (use.role & params.context.role) + if (Role(use.role & params.context.role) == params.context.role && + !(use.role & params.context.excludeRole)) if (std::optional ls_loc = GetLsLocationEx(db, working_files, use, container)) { if (container) From 775c72b0e6a092bf45919d6c99b6d335d53bb1fd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 6 Jul 2018 23:34:16 -0700 Subject: [PATCH 126/378] clang+llvm libs --- cmake/FindClang.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 4fd60949a..bb758d18e 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -70,7 +70,11 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE _Clang_find_library(Clang_LIBRARY clang) _Clang_find_add_library(clangFrontend) +_Clang_find_add_library(clangParse) _Clang_find_add_library(clangSerialization) +_Clang_find_add_library(clangSema) +_Clang_find_add_library(clangAnalysis) +_Clang_find_add_library(clangEdit) _Clang_find_add_library(clangAST) _Clang_find_add_library(clangLex) _Clang_find_add_library(clangDriver) @@ -78,6 +82,8 @@ _Clang_find_add_library(clangBasic) if(USE_SHARED_LLVM) _Clang_find_add_library(LLVM) else() + _Clang_find_add_library(LLVMMCParser) + _Clang_find_add_library(LLVMMC) _Clang_find_add_library(LLVMBitReader) _Clang_find_add_library(LLVMOption) _Clang_find_add_library(LLVMProfileData) From 7dd0241a4c1e5b0bab6bde7a628b913a64607470 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 5 Jul 2018 17:53:33 -0700 Subject: [PATCH 127/378] First draft: replace libclang indexer with clangIndex --- .clang-format | 2 +- cmake/FindClang.cmake | 1 + src/clang_tu.cc | 61 - src/clang_tu.h | 1 - src/clang_utils.cc | 15 + src/clang_utils.h | 2 + src/file_consumer.cc | 35 +- src/file_consumer.h | 13 +- src/indexer.cc | 2559 ++++++-------------------- src/indexer.h | 13 +- src/main.cc | 6 +- src/message_handler.cc | 6 +- src/message_handler.h | 4 +- src/messages/ccls_fileInfo.cc | 4 +- src/messages/textDocument_didOpen.cc | 2 +- src/pipeline.cc | 2 +- src/query.cc | 4 +- src/query.h | 2 +- src/serializer.cc | 6 +- src/test.cc | 3 +- 20 files changed, 634 insertions(+), 2107 deletions(-) diff --git a/.clang-format b/.clang-format index 3f19e6161..9b3aa8b72 100644 --- a/.clang-format +++ b/.clang-format @@ -1 +1 @@ -BasedOnStyle: Chromium +BasedOnStyle: LLVM diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index bb758d18e..12cbd503c 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -69,6 +69,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clang) +_Clang_find_add_library(clangIndex) _Clang_find_add_library(clangFrontend) _Clang_find_add_library(clangParse) _Clang_find_add_library(clangSerialization) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 563adbec1..95e44c908 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -259,67 +259,6 @@ std::string ClangCursor::get_type_description() const { return ::ToString(clang_getTypeSpelling(type)); } -std::string ClangCursor::get_comments() const { - CXSourceRange range = clang_Cursor_getCommentRange(cx_cursor); - if (clang_Range_isNull(range)) - return {}; - - unsigned start_column; - clang_getSpellingLocation(clang_getRangeStart(range), nullptr, nullptr, - &start_column, nullptr); - - // Get associated comment text. - CXString cx_raw = clang_Cursor_getRawCommentText(cx_cursor); - int pad = -1; - std::string ret; - for (const char* p = clang_getCString(cx_raw); *p;) { - // The first line starts with a comment marker, but the rest needs - // un-indenting. - unsigned skip = start_column - 1; - for (; skip > 0 && (*p == ' ' || *p == '\t'); p++) - skip--; - const char* q = p; - while (*q != '\n' && *q) - q++; - if (*q) - q++; - // A minimalist approach to skip Doxygen comment markers. - // See https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html - if (pad < 0) { - // First line, detect the length of comment marker and put into |pad| - const char* begin = p; - while (*p == '/' || *p == '*') - p++; - if (*p == '<' || *p == '!') - p++; - if (*p == ' ') - p++; - pad = int(p - begin); - } else { - // Other lines, skip |pad| bytes - int prefix = pad; - while (prefix > 0 && - (*p == ' ' || *p == '/' || *p == '*' || *p == '<' || *p == '!')) - prefix--, p++; - } - ret.insert(ret.end(), p, q); - p = q; - } - clang_disposeString(cx_raw); - while (ret.size() && isspace(ret.back())) - ret.pop_back(); - if (EndsWith(ret, "*/")) { - ret.resize(ret.size() - 2); - } else if (EndsWith(ret, "\n/")) { - ret.resize(ret.size() - 2); - } - while (ret.size() && isspace(ret.back())) - ret.pop_back(); - if (ret.empty()) - return {}; - return ret; -} - std::string ClangCursor::ToString() const { return ::ToString(get_kind()) + " " + get_spell_name(); } diff --git a/src/clang_tu.h b/src/clang_tu.h index 85bbf537f..03fbf9937 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -85,7 +85,6 @@ class ClangCursor { bool is_valid_kind() const; std::string get_type_description() const; - std::string get_comments() const; std::string ToString() const; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 6a56d2195..24bbfb892 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -3,6 +3,7 @@ #include "platform.h" #include "filesystem.hh" +using namespace clang; using namespace llvm; namespace { @@ -125,6 +126,20 @@ std::string FileName(CXFile file) { return ret; } +std::string FileName(const FileEntry& file) { + StringRef Name = file.tryGetRealPathName(); + if (Name.empty()) + Name = file.getName(); + std::string ret = NormalizePath(Name); + // Resolve /usr/include/c++/7.3.0 symlink. + if (!StartsWith(ret, g_config->projectRoot)) { + SmallString<256> dest; + sys::fs::real_path(ret, dest); + ret = dest.str(); + } + return ret; +} + std::string ToString(CXString cx_string) { std::string string; if (cx_string.data != nullptr) { diff --git a/src/clang_utils.h b/src/clang_utils.h index 8db9fedd4..7b7a1da47 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -3,6 +3,7 @@ #include "lsp_diagnostic.h" #include +#include #include #include @@ -12,6 +13,7 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, // Returns the absolute path to |file|. std::string FileName(CXFile file); +std::string FileName(const clang::FileEntry& file); std::string ToString(CXString cx_string); diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 218ec3bfb..b32a8ed59 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -23,11 +23,6 @@ std::optional GetFileContents( } // namespace -bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) { - return a.data[0] == b.data[0] && a.data[1] == b.data[1] && - a.data[2] == b.data[2]; -} - FileContents::FileContents(const std::string& path, const std::string& content) : path(path), content(content) { line_offsets_.push_back(0); @@ -98,14 +93,10 @@ FileConsumer::FileConsumer(VFS* vfs, const std::string& parse_file) : vfs_(vfs), parse_file_(parse_file), thread_id_(g_thread_id) {} IndexFile* FileConsumer::TryConsumeFile( - CXFile file, - bool* is_first_ownership, + const clang::FileEntry& File, std::unordered_map* file_contents_map) { - assert(is_first_ownership); - - CXFileUniqueID file_id; - if (clang_getFileUniqueID(file, &file_id) != 0) { - std::string file_name = FileName(file); + std::string file_name = FileName(File); + if (!File.isValid()) { if (!file_name.empty()) { LOG_S(ERROR) << "Could not get unique file id for " << file_name << " when parsing " << parse_file_; @@ -114,33 +105,27 @@ IndexFile* FileConsumer::TryConsumeFile( } // Try to find cached local result. - auto it = local_.find(file_id); - if (it != local_.end()) { - *is_first_ownership = false; + unsigned UID = File.getUID(); + auto it = local_.find(UID); + if (it != local_.end()) return it->second.get(); - } - - std::string file_name = FileName(file); // We did not take the file from global. Cache that we failed so we don't try // again and return nullptr. if (!vfs_->Mark(file_name, thread_id_, 2)) { - local_[file_id] = nullptr; + local_[UID] = nullptr; return nullptr; } // Read the file contents, if we fail then we cannot index the file. std::optional contents = GetFileContents(file_name, file_contents_map); - if (!contents) { - *is_first_ownership = false; + if (!contents) return nullptr; - } // Build IndexFile instance. - *is_first_ownership = true; - local_[file_id] = std::make_unique(file_name, *contents); - return local_[file_id].get(); + local_[UID] = std::make_unique(UID, file_name, *contents); + return local_[UID].get(); } std::vector> FileConsumer::TakeLocalState() { diff --git a/src/file_consumer.h b/src/file_consumer.h index b00a228ea..0697f3b9a 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -5,6 +5,7 @@ #include "utils.h" #include +#include #include #include @@ -13,10 +14,6 @@ struct IndexFile; -// Needed for unordered_map usage below. -MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]); -bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b); - struct FileContents { FileContents() = default; FileContents(const std::string& path, const std::string& content); @@ -56,24 +53,20 @@ struct VFS { struct FileConsumer { FileConsumer(VFS* vfs, const std::string& parse_file); - // Returns true if this instance owns given |file|. This will also attempt to - // take ownership over |file|. - // // Returns IndexFile for the file or nullptr. |is_first_ownership| is set // to true iff the function just took ownership over the file. Otherwise it // is set to false. // // note: file_contents is passed as a parameter instead of as a member // variable since it is large and we do not want to copy it. - IndexFile* TryConsumeFile(CXFile file, - bool* is_first_ownership, + IndexFile* TryConsumeFile(const clang::FileEntry& file, std::unordered_map* file_contents); // Returns and passes ownership of all local state. std::vector> TakeLocalState(); private: - std::unordered_map> local_; + std::unordered_map> local_; VFS* vfs_; std::string parse_file_; int thread_id_; diff --git a/src/indexer.cc b/src/indexer.cc index 2efecd459..715d1f836 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -7,7 +7,15 @@ using ccls::Intern; #include #include +#include +#include +#include +#include +#include +#include +#include #include +#include using namespace clang; using llvm::Timer; @@ -18,314 +26,281 @@ using llvm::Timer; #include #include -#if CINDEX_VERSION >= 48 -#define CINDEX_HAVE_ROLE 1 -#endif - namespace { -// For typedef/using spanning less than or equal to (this number) of lines, -// display their declarations on hover. -constexpr int kMaxDetailedLines = 3; - -struct CXTranslationUnitImpl { - /* clang::CIndexer */ void *CIdx; - clang::ASTUnit *TheASTUnit; - /* clang::cxstring::CXStringPool */ void *StringPool; - void *Diagnostics; - void *OverridenCursorsPool; - /* clang::index::CommentToXMLConverter */ void *CommentToXML; - unsigned ParsingOptions; - std::vector Arguments; -}; +struct IndexParam { + llvm::DenseSet SeenUID; + std::vector seen_files; + std::unordered_map file_contents; + std::unordered_map file2write_time; -// TODO How to check if a reference to type is a declaration? -// This currently also includes constructors/destructors. -// It seems declarations in functions are not indexed. -bool IsDeclContext(CXIdxEntityKind kind) { - switch (kind) { - case CXIdxEntity_CXXClass: - case CXIdxEntity_CXXNamespace: - case CXIdxEntity_ObjCCategory: - case CXIdxEntity_ObjCClass: - case CXIdxEntity_ObjCProtocol: - case CXIdxEntity_Struct: - return true; - default: - return false; - } -} + // Only use this when strictly needed (ie, primary translation unit is + // needed). Most logic should get the IndexFile instance via + // |file_consumer|. + // + // This can be null if we're not generating an index for the primary + // translation unit. + IndexFile* primary_file = nullptr; -Role GetRole(const CXIdxEntityRefInfo* ref_info, Role role) { -#if CINDEX_HAVE_ROLE - return static_cast(static_cast(ref_info->role)); -#else - return role; -#endif -} + ASTUnit& Unit; -SymbolKind GetSymbolKind(CXCursorKind kind) { - switch (kind) { - case CXCursor_TranslationUnit: - return SymbolKind::File; - - case CXCursor_FunctionDecl: - case CXCursor_CXXMethod: - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - case CXCursor_FunctionTemplate: - case CXCursor_OverloadedDeclRef: - case CXCursor_LambdaExpr: - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_ObjCClassMethodDecl: - return SymbolKind::Func; - - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - case CXCursor_ClassDecl: - case CXCursor_EnumDecl: - case CXCursor_ObjCInterfaceDecl: - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_Namespace: - return SymbolKind::Type; + FileConsumer* file_consumer = nullptr; + NamespaceHelper ns; - default: - return SymbolKind::Invalid; - } -} + IndexParam(ASTUnit& Unit, FileConsumer* file_consumer) + : Unit(Unit), file_consumer(file_consumer) {} +}; -// Inverse of libclang/CXIndexDataConsumer.cpp getEntityKindFromSymbolKind -lsSymbolKind GetSymbolKind(CXIdxEntityKind kind) { - switch (kind) { - case CXIdxEntity_Unexposed: - return lsSymbolKind::Unknown; - case CXIdxEntity_Typedef: - return lsSymbolKind::TypeAlias; - case CXIdxEntity_Function: - return lsSymbolKind::Function; - case CXIdxEntity_Variable: - // Can also be Parameter - return lsSymbolKind::Variable; - case CXIdxEntity_Field: - return lsSymbolKind::Field; - case CXIdxEntity_EnumConstant: - return lsSymbolKind::EnumMember; - - case CXIdxEntity_ObjCClass: - return lsSymbolKind::Class; - case CXIdxEntity_ObjCProtocol: - return lsSymbolKind::Interface; - case CXIdxEntity_ObjCCategory: - return lsSymbolKind::Interface; - - case CXIdxEntity_ObjCInstanceMethod: - return lsSymbolKind::Method; - case CXIdxEntity_ObjCClassMethod: - return lsSymbolKind::StaticMethod; - case CXIdxEntity_ObjCProperty: - return lsSymbolKind::Property; - case CXIdxEntity_ObjCIvar: - return lsSymbolKind::Field; - - case CXIdxEntity_Enum: - return lsSymbolKind::Enum; - case CXIdxEntity_Struct: - case CXIdxEntity_Union: - return lsSymbolKind::Struct; - - case CXIdxEntity_CXXClass: - return lsSymbolKind::Class; - case CXIdxEntity_CXXNamespace: - return lsSymbolKind::Namespace; - case CXIdxEntity_CXXNamespaceAlias: - return lsSymbolKind::Namespace; - case CXIdxEntity_CXXStaticVariable: - return lsSymbolKind::Field; - case CXIdxEntity_CXXStaticMethod: - return lsSymbolKind::StaticMethod; - case CXIdxEntity_CXXInstanceMethod: - return lsSymbolKind::Method; - case CXIdxEntity_CXXConstructor: - return lsSymbolKind::Constructor; - case CXIdxEntity_CXXDestructor: - return lsSymbolKind::Method; - case CXIdxEntity_CXXConversionFunction: - return lsSymbolKind::Constructor; - case CXIdxEntity_CXXTypeAlias: - return lsSymbolKind::TypeAlias; - case CXIdxEntity_CXXInterface: - return lsSymbolKind::Struct; +IndexFile *ConsumeFile(IndexParam ¶m, const FileEntry &File) { + IndexFile *db = + param.file_consumer->TryConsumeFile(File, ¶m.file_contents); + + // If this is the first time we have seen the file (ignoring if we are + // generating an index for it): + if (param.SeenUID.insert(File.getUID()).second) { + std::string file_name = FileName(File); + // Add to all files we have seen so we can generate proper dependency + // graph. + param.seen_files.push_back(file_name); + + // Set modification time. + std::optional write_time = LastWriteTime(file_name); + LOG_IF_S(ERROR, !write_time) + << "failed to fetch write time for " << file_name; + if (write_time) + param.file2write_time[file_name] = *write_time; } - return lsSymbolKind::Unknown; + return db; } -StorageClass GetStorageC(CX_StorageClass storage) { - switch (storage) { +Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R, unsigned *UID, bool token) { + SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); + std::pair BInfo = SM.getDecomposedLoc(BLoc); + std::pair EInfo = SM.getDecomposedLoc(ELoc); + if (token) + EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); + unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1, + c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1, + l1 = SM.getLineNumber(EInfo.first, EInfo.second) - 1, + c1 = SM.getColumnNumber(EInfo.first, EInfo.second) - 1; + if (l0 > INT16_MAX) l0 = 0; + if (c0 > INT16_MAX) c0 = 0; + if (l1 > INT16_MAX) l1 = 0; + if (c1 > INT16_MAX) c1 = 0; + if (UID) { + if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) + *UID = F->getUID(); + else + *UID = 0; + } + return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}}; +} + +Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R) { + return FromSourceRange(SM, LangOpts, R, nullptr, false); +} + +Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R, unsigned *UID = nullptr) { + return FromSourceRange(SM, LangOpts, R, UID, true); +} + +Position ResolveSourceLocation(const SourceManager &SM, SourceLocation Loc, + FileID *F = nullptr) { + std::pair D = SM.getDecomposedLoc(Loc); + if (F) + *F = D.first; + unsigned line = SM.getLineNumber(D.first, D.second) - 1; + unsigned col = SM.getColumnNumber(D.first, D.second) - 1; + return {int16_t(line > INT16_MAX ? 0 : line), + int16_t(col > INT16_MAX ? 0 : col)}; +} + +SymbolKind GetSymbolKind(const Decl& D) { + switch (D.getKind()) { + case Decl::TranslationUnit: + return SymbolKind::File; + case Decl::FunctionTemplate: + case Decl::Function: + case Decl::CXXMethod: + case Decl::CXXConstructor: + case Decl::CXXConversion: + case Decl::CXXDestructor: + return SymbolKind::Func; + case Decl::Namespace: + case Decl::NamespaceAlias: + case Decl::ClassTemplate: + case Decl::TypeAliasTemplate: + case Decl::Enum: + case Decl::Record: + case Decl::CXXRecord: + case Decl::TypeAlias: + case Decl::Typedef: + case Decl::UnresolvedUsingTypename: + return SymbolKind::Type; + case Decl::Field: + case Decl::Var: + case Decl::ParmVar: + case Decl::ImplicitParam: + case Decl::Decomposition: + case Decl::EnumConstant: + return SymbolKind::Var; + default: + return SymbolKind::Invalid; + } +} + +const Decl* GetTypeDecl(QualType T) { + Decl *D = nullptr; + const Type *TP; + for(;;) { + TP = T.getTypePtrOrNull(); + if (!TP) + return D; + switch (TP->getTypeClass()) { + case Type::Pointer: + T = cast(TP)->getPointeeType(); + continue; + case Type::BlockPointer: + T = cast(TP)->getPointeeType(); + continue; + case Type::LValueReference: + case Type::RValueReference: + T = cast(TP)->getPointeeType(); + continue; + case Type::ObjCObjectPointer: + T = cast(TP)->getPointeeType(); + continue; + case Type::MemberPointer: + T = cast(TP)->getPointeeType(); + continue; default: - case CX_SC_Invalid: - case CX_SC_OpenCLWorkGroupLocal: - case CX_SC_None: - return SC_None; - case CX_SC_Extern: - return SC_Extern; - case CX_SC_Static: - return SC_Static; - case CX_SC_PrivateExtern: - return SC_PrivateExtern; - case CX_SC_Auto: - return SC_Auto; - case CX_SC_Register: - return SC_Register; - } + break; + } + break; + } + +try_again: + switch (TP->getTypeClass()) { + case Type::Typedef: + D = cast(TP)->getDecl(); + break; + case Type::ObjCObject: + D = cast(TP)->getInterface(); + break; + case Type::ObjCInterface: + D = cast(TP)->getDecl(); + break; + case Type::Record: + case Type::Enum: + D = cast(TP)->getDecl(); + break; + case Type::TemplateSpecialization: + if (const RecordType *Record = TP->getAs()) + D = Record->getDecl(); + else + D = cast(TP) + ->getTemplateName() + .getAsTemplateDecl(); + break; + + case Type::Auto: + case Type::DeducedTemplateSpecialization: + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); + if (TP) + goto try_again; + break; + + case Type::InjectedClassName: + D = cast(TP)->getDecl(); + break; + + // FIXME: Template type parameters! + + case Type::Elaborated: + TP = cast(TP)->getNamedType().getTypePtrOrNull(); + goto try_again; + + default: + break; + } + return D; +} + +const Decl* GetSpecialized(const Decl* D) { + if (!D) + return D; + Decl *Template = nullptr; + if (const CXXRecordDecl *CXXRecord = dyn_cast(D)) { + if (const ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast(CXXRecord)) + Template = PartialSpec->getSpecializedTemplate(); + else if (const ClassTemplateSpecializationDecl *ClassSpec + = dyn_cast(CXXRecord)) { + llvm::PointerUnion Result + = ClassSpec->getSpecializedTemplateOrPartial(); + if (Result.is()) + Template = Result.get(); + else + Template = Result.get(); + + } else + Template = CXXRecord->getInstantiatedFromMemberClass(); + } else if (const FunctionDecl *Function = dyn_cast(D)) { + Template = Function->getPrimaryTemplate(); + if (!Template) + Template = Function->getInstantiatedFromMemberFunction(); + } else if (const VarDecl *Var = dyn_cast(D)) { + if (Var->isStaticDataMember()) + Template = Var->getInstantiatedFromStaticDataMember(); + } else if (const RedeclarableTemplateDecl *Tmpl + = dyn_cast(D)) + Template = Tmpl->getInstantiatedFromMemberTemplate(); + else + return nullptr; + return Template; } -// Caches all instances of constructors, regardless if they are indexed or not. -// The constructor may have a make_unique call associated with it that we need -// to export. If we do not capture the parameter type description for the -// constructor we will not be able to attribute the constructor call correctly. -struct ConstructorCache { - struct Constructor { - Usr usr; - std::vector param_type_desc; - }; - std::unordered_map> constructors_; - - // This should be called whenever there is a constructor declaration. - void NotifyConstructor(ClangCursor ctor_cursor) { - auto build_type_desc = [](ClangCursor cursor) { - std::vector type_desc; - for (ClangCursor arg : cursor.get_arguments()) { - if (arg.get_kind() == CXCursor_ParmDecl) - type_desc.push_back(arg.get_type_description()); - } - return type_desc; - }; +class IndexDataConsumer : public index::IndexDataConsumer { + ASTContext *Ctx; + IndexParam& param; + llvm::DenseMap Decl2usr; - Constructor ctor{ctor_cursor.get_usr_hash(), build_type_desc(ctor_cursor)}; - - // Insert into |constructors_|. - auto type_usr_hash = ctor_cursor.get_semantic_parent().get_usr_hash(); - auto existing_ctors = constructors_.find(type_usr_hash); - if (existing_ctors != constructors_.end()) { - existing_ctors->second.push_back(ctor); - } else { - constructors_[type_usr_hash] = {ctor}; + Usr GetUsr(const Decl* D) { + D = D->getCanonicalDecl(); + auto R = Decl2usr.try_emplace(D); + if (R.second) { + SmallString<256> USR; + index::generateUSRForDecl(D, USR); + R.first->second = HashUsr({USR.data(), USR.size()}); } + return R.first->second; } - // Tries to lookup a constructor in |type_usr| that takes arguments most - // closely aligned to |param_type_desc|. - std::optional TryFindConstructorUsr( - Usr type_usr, - const std::vector& param_type_desc) { - auto count_matching_prefix_length = [](const char* a, const char* b) { - int matched = 0; - while (*a && *b) { - if (*a != *b) - break; - ++a; - ++b; - ++matched; - } - // Additional score if the strings were the same length, which makes - // "a"/"a" match higher than "a"/"a&" - if (*a == *b) - matched += 1; - return matched; - }; - - // Try to find constructors for the type. If there are no constructors - // available, return an empty result. - auto ctors_it = constructors_.find(type_usr); - if (ctors_it == constructors_.end()) - return std::nullopt; - const std::vector& ctors = ctors_it->second; - if (ctors.empty()) - return std::nullopt; - - Usr best_usr = ctors[0].usr; - int best_score = INT_MIN; - - // Scan constructors for the best possible match. - for (const Constructor& ctor : ctors) { - // If |param_type_desc| is empty and the constructor is as well, we don't - // need to bother searching, as this is the match. - if (param_type_desc.empty() && ctor.param_type_desc.empty()) { - best_usr = ctor.usr; - break; - } - - // Weight matching parameter length heavily, as it is more accurate than - // the fuzzy type matching approach. - int score = 0; - if (param_type_desc.size() == ctor.param_type_desc.size()) - score += param_type_desc.size() * 1000; - - // Do prefix-based match on parameter type description. This works well in - // practice because clang appends qualifiers to the end of the type, ie, - // |foo *&&| - for (size_t i = 0; - i < std::min(param_type_desc.size(), ctor.param_type_desc.size()); - ++i) { - score += count_matching_prefix_length(param_type_desc[i].c_str(), - ctor.param_type_desc[i].c_str()); - } - - if (score > best_score) { - best_usr = ctor.usr; - best_score = score; - } + template + void SetName(const Decl *D, std::string_view short_name, + std::string_view qualified, Def &def, + PrintingPolicy *Policy = nullptr) { + SmallString<256> Str; + llvm::raw_svector_ostream OS(Str); + if (Policy) { + D->print(OS, *Policy); + } else { + PrintingPolicy PP(Ctx->getLangOpts()); + PP.AnonymousTagLocations = false; + PP.TerseOutput = true; + // PP.PolishForDeclaration = true; + PP.ConstantsAsWritten = true; + PP.SuppressTagKeyword = false; + PP.FullyQualifiedName = false; + D->print(OS, PP); } - return best_usr; - } -}; - -struct IndexParam { - std::unordered_set seen_cx_files; - std::vector seen_files; - std::unordered_map file_contents; - std::unordered_map file2write_time; - - // Only use this when strictly needed (ie, primary translation unit is - // needed). Most logic should get the IndexFile instance via - // |file_consumer|. - // - // This can be null if we're not generating an index for the primary - // translation unit. - IndexFile* primary_file = nullptr; - - ClangTranslationUnit* tu = nullptr; - - FileConsumer* file_consumer = nullptr; - NamespaceHelper ns; - ConstructorCache ctors; - - IndexParam(ClangTranslationUnit* tu, FileConsumer* file_consumer) - : tu(tu), file_consumer(file_consumer) {} - - std::tuple PrettyPrintCursor( - CXCursor Cursor, - std::string_view short_name) { - auto TU = - static_cast(const_cast(Cursor.data[2])); - ASTContext& AST = TU->TheASTUnit->getASTContext(); - PrintingPolicy Policy = AST.getPrintingPolicy(); - Policy.TerseOutput = 1; - Policy.FullyQualifiedName = true; - - const Decl* D = static_cast(Cursor.data[0]); - if (!D) - return {"", 0, 0, 0}; - - llvm::SmallString<128> Str; - llvm::raw_svector_ostream OS(Str); - D->print(OS, Policy); std::string name = OS.str(); - for (std::string::size_type i = 0;;) { if ((i = name.find("(anonymous ", i)) == std::string::npos) break; @@ -336,8 +311,17 @@ struct IndexParam { name.replace(i, 10, "anon"); } auto i = name.find(short_name); - assert(i != std::string::npos); - int16_t short_name_offset = i, short_name_size = short_name.size(); + if (i == std::string::npos) { + // e.g. operator type-parameter-1 + i = 0; + def.short_name_offset = 0; + } else if (short_name.size()) { + name.replace(i, short_name.size(), qualified); + def.short_name_offset = i + qualified.size() - short_name.size(); + } else { + def.short_name_offset = i; + } + def.short_name_size = short_name.size(); for (int paren = 0; i; i--) { // Skip parentheses in "(anon struct)::name" if (name[i - 1] == ')') @@ -348,380 +332,262 @@ struct IndexParam { name[i - 1] == '_' || name[i - 1] == ':')) break; } - return {name, i, short_name_offset, short_name_size}; + def.qual_name_offset = i; + def.detailed_name = Intern(name); } -}; -IndexFile* ConsumeFile(IndexParam* param, CXFile file) { - if (!file) - return nullptr; - bool is_first_ownership = false; - IndexFile* db = param->file_consumer->TryConsumeFile( - file, &is_first_ownership, ¶m->file_contents); - - // If this is the first time we have seen the file (ignoring if we are - // generating an index for it): - 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 - if (!file_name.empty()) { - // Add to all files we have seen so we can generate proper dependency - // graph. - param->seen_files.push_back(file_name); - - // Set modification time. - std::optional write_time = LastWriteTime(file_name); - LOG_IF_S(ERROR, !write_time) << "failed to fetch write time for " - << file_name; - if (write_time) - param->file2write_time[file_name] = *write_time; - } - } - - if (is_first_ownership) { - // Report skipped source range list. - CXSourceRangeList* skipped = clang_getSkippedRanges(param->tu->cx_tu, file); - for (unsigned i = 0; i < skipped->count; ++i) { - db->skipped_by_preprocessor.push_back( - ResolveCXSourceRange(skipped->ranges[i])); - } - clang_disposeSourceRangeList(skipped); - } - - return db; -} - -// Returns true if the given entity kind can be called implicitly, ie, without -// actually being written in the source code. -bool CanBeCalledImplicitly(CXIdxEntityKind kind) { - switch (kind) { - case CXIdxEntity_CXXConstructor: - case CXIdxEntity_CXXConversionFunction: - case CXIdxEntity_CXXDestructor: - return true; - default: - return false; - } -} - -// Returns true if the cursor spelling contains the given string. This is -// useful to check for implicit function calls. -bool CursorSpellingContainsString(CXCursor cursor, - CXTranslationUnit cx_tu, - std::string_view needle) { - CXSourceRange range = clang_Cursor_getSpellingNameRange(cursor, 0, 0); - CXToken* tokens; - unsigned num_tokens; - clang_tokenize(cx_tu, range, &tokens, &num_tokens); - - bool result = false; - - for (unsigned i = 0; i < num_tokens; ++i) { - CXString name = clang_getTokenSpelling(cx_tu, tokens[i]); - if (needle == clang_getCString(name)) { - result = true; - break; - } - clang_disposeString(name); - } - - clang_disposeTokens(cx_tu, tokens, num_tokens); - return result; -} - -// Returns the document content for the given range. May not work perfectly -// when there are tabs instead of spaces. -std::string GetDocumentContentInRange(CXTranslationUnit cx_tu, - CXSourceRange range) { - std::string result; - - CXToken* tokens; - unsigned num_tokens; - clang_tokenize(cx_tu, range, &tokens, &num_tokens); - - std::optional previous_token_range; - - for (unsigned i = 0; i < num_tokens; ++i) { - // Add whitespace between the previous token and this one. - Range token_range = - ResolveCXSourceRange(clang_getTokenExtent(cx_tu, tokens[i])); - if (previous_token_range) { - // Insert newlines. - int16_t line_delta = - token_range.start.line - previous_token_range->end.line; - assert(line_delta >= 0); - if (line_delta > 0) { - result.append((size_t)line_delta, '\n'); - // Reset column so we insert starting padding. - previous_token_range->end.column = 0; - } - // Insert spaces. - int16_t column_delta = - token_range.start.column - previous_token_range->end.column; - assert(column_delta >= 0); - result.append((size_t)column_delta, ' '); - } - previous_token_range = token_range; - - // Add token content. - CXString spelling = clang_getTokenSpelling(cx_tu, tokens[i]); - result += clang_getCString(spelling); - clang_disposeString(spelling); - } - - clang_disposeTokens(cx_tu, tokens, num_tokens); - - return result; -} - -// |parent| should be resolved before using |SetUsePreflight| so that |def| will -// not be invalidated by |To{Func,Type,Var}Id|. -Use SetUse(IndexFile* db, Range range, ClangCursor parent, Role role) { - switch (GetSymbolKind(parent.get_kind())) { + Use GetUse(IndexFile* db, Range range, const DeclContext *DC, Role role) { + if (!DC) + return Use{{range, 0, SymbolKind::File, role}}; + const Decl *D = cast(DC); + switch (GetSymbolKind(*D)) { case SymbolKind::Func: - return Use{{range, db->ToFunc(parent).usr, SymbolKind::Func, role}}; + return Use{{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}}; case SymbolKind::Type: - return Use{{range, db->ToType(parent).usr, SymbolKind::Type, role}}; + return Use{{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}}; case SymbolKind::Var: - return Use{{range, db->ToVar(parent).usr, SymbolKind::Var, role}}; + return Use{{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}}; default: return Use{{range, 0, SymbolKind::File, role}}; + } } -} - -const char* GetAnonName(CXCursorKind kind) { - switch (kind) { - case CXCursor_ClassDecl: - return "(anon class)"; - case CXCursor_EnumDecl: - return "(anon enum)"; - case CXCursor_Namespace: - return "(anon ns)"; - case CXCursor_StructDecl: - return "(anon struct)"; - case CXCursor_UnionDecl: - return "(anon union)"; - default: - return "(anon)"; - } -} -void SetTypeName(IndexType& type, - const ClangCursor& cursor, - const CXIdxContainerInfo* container, - const char* name, - IndexParam* param) { - CXIdxContainerInfo parent; - // |name| can be null in an anonymous struct (see - // tests/types/anonymous_struct.cc). - if (!name) - name = GetAnonName(cursor.get_kind()); - 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); - int short_name_offset, short_name_size; - std::string detailed; - std::tie(detailed, short_name_offset, short_name_size) = - param->ns.QualifiedName(container ? container : &parent, name); - type.def.detailed_name = Intern(detailed); - type.def.qual_name_offset = 0; - type.def.short_name_offset = short_name_offset; - type.def.short_name_size = short_name_size; -} - -// Finds the cursor associated with the declaration type of |cursor|. This -// strips -// qualifies from |cursor| (ie, Foo* => Foo) and removes template arguments -// (ie, Foo => Foo<*,*>). -IndexType* ResolveToDeclarationType(IndexFile* db, - ClangCursor cursor, - IndexParam* param) { - ClangType type = cursor.get_type(); - - // auto x = new Foo() will not be deduced to |Foo| if we do not use the - // canonical type. However, a canonical type will look past typedefs so we - // will not accurately report variables on typedefs if we always do this. - if (type.cx_type.kind == CXType_Auto) - type = type.get_canonical(); - - type = type.strip_qualifiers(); - - if (type.is_builtin()) { - // For builtin types, use type kinds as USR hash. - return &db->ToType(static_cast(type.cx_type.kind)); +public: + IndexDataConsumer(IndexParam& param) : param(param) {} + void initialize(ASTContext &Ctx) override { + this->Ctx = &Ctx; } - - ClangCursor declaration = - type.get_declaration().template_specialization_to_template_definition(); - std::optional usr = declaration.get_opt_usr_hash(); - if (!usr) - return nullptr; - IndexType& typ = db->ToType(*usr); - if (!typ.def.detailed_name[0]) { - std::string name = declaration.get_spell_name(); - SetTypeName(typ, declaration, nullptr, name.c_str(), param); - } - return &typ; -} - -void SetVarDetail(IndexVar& var, - std::string_view short_name, - const ClangCursor& cursor, - const CXIdxContainerInfo* semanticContainer, - bool is_first_seen, - IndexFile* db, - IndexParam* param) { - IndexVar::Def& def = var.def; - const CXType cx_type = clang_getCursorType(cursor.cx_cursor); - std::string type_name = ToString(clang_getTypeSpelling(cx_type)); - // clang may report "(lambda at foo.cc)" which end up being a very long - // string. Shorten it to just "lambda". - if (type_name.find("(lambda at") != std::string::npos) - type_name = "lambda"; - if (g_config->index.comments) - def.comments = Intern(cursor.get_comments()); - def.storage = GetStorageC(clang_Cursor_getStorageClass(cursor.cx_cursor)); - - // TODO how to make PrettyPrint'ed variable name qualified? -#if 0 && CINDEX_HAVE_PRETTY - cursor.get_kind() != CXCursor_EnumConstantDecl - ? param->PrettyPrintCursor(cursor.cx_cursor) - : + bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, + ArrayRef Relations, +#if LLVM_VERSION_MAJOR >= 7 + SourceLocation Loc, +#else + FileID LocFID, unsigned LocOffset, #endif - std::string qualified_name; - std::tie(qualified_name, def.short_name_offset, def.short_name_size) = - param->ns.QualifiedName(semanticContainer, short_name); - - if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) { - CXTypeKind k = clang_getCanonicalType( - clang_getEnumDeclIntegerType(semanticContainer->cursor)) - .kind; - std::string hover = qualified_name; - if (auto* TD = dyn_cast_or_null( - static_cast(cursor.cx_cursor.data[0]))) { - hover += " = "; - if (k == CXType_Char_U || k == CXType_UChar || k == CXType_UShort || - k == CXType_UInt || k == CXType_ULong || k == CXType_ULongLong) - hover += std::to_string(TD->getInitVal().getZExtValue()); - else - hover += std::to_string(TD->getInitVal().getSExtValue()); + ASTNodeInfo ASTNode) override { + SourceManager &SM = Ctx->getSourceManager(); + const LangOptions &Lang = Ctx->getLangOpts(); +#if LLVM_VERSION_MAJOR < 7 + SourceLocation Loc; + { + const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(LocFID); + unsigned off = Entry.getOffset() + LocOffset; + if (!Entry.isFile()) + off |= 1u << 31; + Loc = SourceLocation::getFromRawEncoding(off); } - def.detailed_name = Intern(qualified_name); - def.qual_name_offset = 0; - def.hover = Intern(hover); - } else { -#if 0 - def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false); +#endif + SourceLocation Spell = SM.getSpellingLoc(Loc); + Range spell = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); + if (!FE) { +#if LLVM_VERSION_MAJOR < 7 + auto P = SM.getExpansionRange(Loc); + spell = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); + FE = SM.getFileEntryForID(SM.getFileID(P.first)); #else - int offset = type_name.size(); - offset += ConcatTypeAndName(type_name, qualified_name); - def.detailed_name = Intern(type_name); - def.qual_name_offset = offset; - def.short_name_offset += offset; - // Append the textual initializer, bit field, constructor to |hover|. - // Omit |hover| for these types: - // int (*a)(); int (&a)(); int (&&a)(); int a[1]; auto x = ... - // We can take these into consideration after we have better support for - // inside-out syntax. - QualType T = QualType::getFromOpaquePtr(cx_type.data[0]); - while (1) { - const Type* TP = T.getTypePtrOrNull(); - if (!TP) - goto skip; - switch (TP->getTypeClass()) { - default: - break; - // case Type::Auto: - // case Type::ConstantArray: - // case Type::IncompleteArray: - // case Type::VariableArray: - // case Type::DependentSizedArray: - // case Type::Vector: - // case Type::Complex: - // goto skip; - case Type::Pointer: - T = cast(TP)->getPointeeType(); - continue; - case Type::LValueReference: - case Type::RValueReference: - T = cast(TP)->getPointeeType(); - continue; - case Type::MemberPointer: - T = cast(TP)->getPointeeType(); - continue; + auto R = SM.getExpansionRange(Loc); + spell = FromTokenRange(SM, Ctx->getLangOpts(), R.getAsRange()); + FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); +#endif + if (!FE) + return true; + } + IndexFile *db = ConsumeFile(param, *FE); + if (!db) + return true; + + const DeclContext *SemDC = D->getDeclContext(); + const DeclContext *LexDC = D->getLexicalDeclContext(); + (void)SemDC; + (void)LexDC; + Range extent = FromTokenRange(SM, Lang, D->getSourceRange()); + Role role = static_cast(Roles); + + bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); + bool is_def = Roles & uint32_t(index::SymbolRole::Definition); + std::string short_name, qualified; + + if (auto* ND = dyn_cast(D)) { + short_name = ND->getNameAsString(); + qualified = ND->getQualifiedNameAsString(); + } + + IndexFunc *func = nullptr; + IndexType *type = nullptr; + IndexVar *var = nullptr; + SymbolKind kind = GetSymbolKind(*D); + Usr usr = GetUsr(D); + switch (kind) { + case SymbolKind::Invalid: + LOG_S(INFO) << "Unhandled " << int(D->getKind()); + return true; + case SymbolKind::File: + return true; + case SymbolKind::Func: + func = &db->ToFunc(usr); + if (!func->def.detailed_name[0]) { + SetName(D, short_name, qualified, func->def); + if (g_config->index.comments) + func->def.comments = Intern(""); } + if (is_def || (is_decl && !func->def.spell)) { + if (func->def.spell) + func->declarations.push_back(*func->def.spell); + func->def.spell = GetUse(db, spell, LexDC, role); + func->def.extent = GetUse(db, extent, LexDC, Role::None); + if (auto *FD = dyn_cast(D)) { + DeclarationNameInfo Info = FD->getNameInfo(); + func->def.spell = GetUse( + db, FromTokenRange(SM, Ctx->getLangOpts(), Info.getSourceRange()), + LexDC, role); + } + } else + func->uses.push_back(GetUse(db, spell, LexDC, role)); break; - } - if (T->getAs()) - goto skip; - { - const FileContents& fc = param->file_contents[db->path]; - Position spell_p = cursor.get_spell().end, - extent_p = cursor.get_extent().end; - if (extent_p.line - spell_p.line < kMaxDetailedLines) { - std::optional spell_end = fc.ToOffset(spell_p), - extent_end = fc.ToOffset(extent_p); - if (extent_end && *spell_end < *extent_end) - def.hover = - Intern(std::string(def.detailed_name) + - fc.content.substr(*spell_end, *extent_end - *spell_end)); + case SymbolKind::Type: + type = &db->ToType(usr); + if (!type->def.detailed_name[0]) { + SetName(D, short_name, qualified, type->def); + if (g_config->index.comments) + type->def.comments = Intern(""); } + if (is_def || (is_decl && !type->def.spell)) { + if (type->def.spell) + type->declarations.push_back(*type->def.spell); + type->def.spell = GetUse(db, spell, LexDC, role); + type->def.extent = GetUse(db, extent, LexDC, Role::None); + } else + type->uses.push_back(GetUse(db, spell, LexDC, role)); + break; + case SymbolKind::Var: + var = &db->ToVar(usr); + if (!var->def.detailed_name[0]) { + SetName(D, short_name, qualified, var->def); + if (g_config->index.comments) + var->def.comments = Intern(""); + } + if (is_def || (is_decl && !var->def.spell)) { + if (var->def.spell) + var->declarations.push_back(*var->def.spell); + var->def.spell = GetUse(db, spell, LexDC, role); + var->def.extent = GetUse(db, extent, LexDC, Role::None); + if (auto *VD = dyn_cast(D)) { + var->def.storage = VD->getStorageClass(); + QualType T = VD->getType(); + for (const Decl* D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { + Usr usr1 = GetUsr(D1); + if (db->usr2type.count(usr1)) + var->def.type = usr1; + } + } + } else + var->uses.push_back(GetUse(db, spell, LexDC, role)); + break; } - skip:; - } -#endif - - if (is_first_seen) { - if (IndexType* var_type = - ResolveToDeclarationType(db, cursor, param)) { - // Don't treat enum definition variables as instantiations. - bool is_enum_member = semanticContainer && - semanticContainer->cursor.kind == CXCursor_EnumDecl; - if (!is_enum_member) - var_type->instances.push_back(var.usr); - - def.type = var_type->usr; - } - } -} -void OnIndexReference_Function(IndexFile* db, - Range loc, - ClangCursor parent_cursor, - IndexFunc& called, - Role role) { - switch (GetSymbolKind(parent_cursor.get_kind())) { - case SymbolKind::Func: { - IndexFunc& parent = db->ToFunc(parent_cursor.cx_cursor); - parent.def.callees.push_back( - SymbolRef{{loc, called.usr, SymbolKind::Func, role}}); - called.uses.push_back(Use{{loc, parent.usr, SymbolKind::Func, role}}); + switch (D->getKind()) { + case Decl::Namespace: + type->def.kind = lsSymbolKind::Namespace; + break; + case Decl::NamespaceAlias: { + type->def.kind = lsSymbolKind::TypeAlias; + auto* NAD = cast(D); + if (const NamespaceDecl* ND = NAD->getNamespace()) { + Usr usr1 = GetUsr(ND); + if (db->usr2type.count(usr1)) + type->def.alias_of = usr1; + } break; } - case SymbolKind::Type: { - IndexType& parent = db->ToType(parent_cursor.cx_cursor); - called.uses.push_back(Use{{loc, parent.usr, SymbolKind::Type, role}}); + case Decl::Enum: + type->def.kind = lsSymbolKind::Enum; + break; + case Decl::Record: + case Decl::CXXRecord: + type->def.kind = lsSymbolKind::Struct; + if (is_def) { + auto *RD = cast(D); + bool can_get_offset = + RD->isCompleteDefinition() && !RD->isDependentType(); + for (FieldDecl *FD : RD->fields()) + type->def.vars.emplace_back( + GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); + } + break; + case Decl::ClassTemplate: + type->def.kind = lsSymbolKind::Class; + break; + case Decl::FunctionTemplate: + type->def.kind = lsSymbolKind::Function; + break; + case Decl::TypeAliasTemplate: + type->def.kind = lsSymbolKind::TypeAlias; + break; + case Decl::TypeAlias: + case Decl::Typedef: + case Decl::UnresolvedUsingTypename: + type->def.kind = lsSymbolKind::TypeAlias; + if (auto *TD = dyn_cast(D)) { + QualType T = TD->getUnderlyingType(); + if (const Decl* D1 = GetTypeDecl(T)) { + Usr usr1 = GetUsr(D1); + if (db->usr2type.count(usr1)) + type->def.alias_of = usr1; + } + } + break; + case Decl::Function: + func->def.kind = lsSymbolKind::Function; + break; + case Decl::CXXMethod: + func->def.kind = lsSymbolKind::Method; + break; + case Decl::CXXConstructor: + case Decl::CXXConversion: + func->def.kind = lsSymbolKind::Constructor; + break; + case Decl::CXXDestructor: + func->def.kind = lsSymbolKind::Method; + break; + case Decl::Var: + case Decl::ParmVar: + var->def.kind = lsSymbolKind::Variable; + if (is_def) { + if (auto* FD = dyn_cast(SemDC)) + db->ToFunc(GetUsr(FD)).def.vars.push_back(usr); + else if (auto* ND = dyn_cast(SemDC)) + db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); + } + [[fallthrough]]; + case Decl::Field: + case Decl::ImplicitParam: + case Decl::Decomposition: + break; + case Decl::EnumConstant: { + auto *ECD = cast(D); + const auto& Val = ECD->getInitVal(); + std::string init = + " = " + (Val.isSigned() ? std::to_string(Val.getSExtValue()) + : std::to_string(Val.getZExtValue())); + var->def.detailed_name = Intern(var->def.detailed_name + init); break; } - default: { - called.uses.push_back(Use{{loc, 0, SymbolKind::File, role}}); + default: + LOG_S(INFO) << "Unhandled " << int(D->getKind()); break; } + return true; } +}; } -} // namespace - -// static const int IndexFile::kMajorVersion = 16; const int IndexFile::kMinorVersion = 1; -IndexFile::IndexFile(const std::string& path, const std::string& contents) - : path(path), file_contents(contents) {} +IndexFile::IndexFile(unsigned UID, const std::string &path, + const std::string &contents) + : UID(UID), path(path), file_contents(contents) {} IndexFunc& IndexFile::ToFunc(Usr usr) { auto ret = usr2func.try_emplace(usr); @@ -772,1277 +638,21 @@ void AddUse(IndexFile* db, Range range, ClangCursor parent, Role role = Role::Reference) { - switch (GetSymbolKind(parent.get_kind())) { - case SymbolKind::Func: - uses.push_back(Use{ - {range, db->ToFunc(parent.cx_cursor).usr, SymbolKind::Func, role}}); - break; - case SymbolKind::Type: - uses.push_back(Use{ - {range, db->ToType(parent.cx_cursor).usr, SymbolKind::Type, role}}); - break; - default: - uses.push_back(Use{{range, 0, SymbolKind::File, role}}); - break; - } -} - -CXCursor fromContainer(const CXIdxContainerInfo* parent) { - return parent ? parent->cursor : clang_getNullCursor(); -} - -void AddUseSpell(IndexFile* db, std::vector& uses, ClangCursor cursor) { - AddUse(db, uses, cursor.get_spell(), cursor.get_lexical_parent().cx_cursor); -} - -void OnIndexDiagnostic(CXClientData client_data, - CXDiagnosticSet diagnostics, - void* reserved) { - IndexParam* param = static_cast(client_data); - - for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) { - CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i); - - CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic); - // Skip diagnostics in system headers. - // if (clang_Location_isInSystemHeader(diag_loc)) - // continue; - - // Get db so we can attribute diagnostic to the right indexed file. - CXFile file; - unsigned int line, column; - clang_getSpellingLocation(diag_loc, &file, &line, &column, nullptr); - // Skip empty diagnostic. - if (!line && !column) - continue; - IndexFile* db = ConsumeFile(param, file); - if (!db) - continue; - - // Build diagnostic. - std::optional ls_diagnostic = - BuildAndDisposeDiagnostic(diagnostic, db->path); - if (ls_diagnostic) - db->diagnostics_.push_back(*ls_diagnostic); - } -} - -CXIdxClientFile OnIndexIncludedFile(CXClientData client_data, - const CXIdxIncludedFileInfo* file) { - IndexParam* param = static_cast(client_data); - - // file->hashLoc only has the position of the hash. We don't have the full - // range for the include. - CXSourceLocation hash_loc = clang_indexLoc_getCXSourceLocation(file->hashLoc); - CXFile cx_file; - unsigned int line; - clang_getSpellingLocation(hash_loc, &cx_file, &line, nullptr, nullptr); - line--; - - IndexFile* db = ConsumeFile(param, cx_file); - if (!db) - return nullptr; - - IndexInclude include; - include.line = line; - include.resolved_path = FileName(file->file); - if (include.resolved_path.size()) - db->includes.push_back(include); - - return nullptr; + // switch (GetSymbolKind(parent.get_kind())) { + // case SymbolKind::Func: + // uses.push_back(Use{ + // {range, db->ToFunc(parent.cx_cursor).usr, SymbolKind::Func, role}}); + // break; + // case SymbolKind::Type: + // uses.push_back(Use{ + // {range, db->ToType(parent.cx_cursor).usr, SymbolKind::Type, role}}); + // break; + // default: + // uses.push_back(Use{{range, 0, SymbolKind::File, role}}); + // break; + // } } -struct FindChildOfKindParam { - CXCursorKind target_kind; - std::optional result; - - FindChildOfKindParam(CXCursorKind target_kind) : target_kind(target_kind) {} -}; - -ClangCursor::VisitResult FindTypeVisitor(ClangCursor cursor, - ClangCursor parent, - std::optional* result) { - switch (cursor.get_kind()) { - case CXCursor_TypeRef: - case CXCursor_TemplateRef: - *result = cursor; - return ClangCursor::VisitResult::Break; - default: - break; - } - - return ClangCursor::VisitResult::Recurse; -} - -std::optional FindType(ClangCursor cursor) { - std::optional result; - cursor.VisitChildren(&FindTypeVisitor, &result); - return result; -} - -bool IsTypeDefinition(const CXIdxContainerInfo* container) { - if (!container) - return false; - return GetSymbolKind(container->cursor.kind) == SymbolKind::Type; -} - -struct VisitDeclForTypeUsageParam { - IndexFile* db; - IndexType* toplevel_type; - int has_processed_any = false; - std::optional previous_cursor; - IndexType* initial_type = nullptr; - - VisitDeclForTypeUsageParam(IndexFile* db, IndexType* toplevel_type) - : db(db), toplevel_type(toplevel_type) {} -}; - -void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, - VisitDeclForTypeUsageParam* param) { - param->has_processed_any = true; - IndexFile* db = param->db; - - // For |A a| where there is a specialization for |A|, - // the |referenced_usr| below resolves to the primary template and - // attributes the use to the primary template instead of the specialization. - // |toplevel_type| is retrieved |clang_getCursorType| which can be a - // specialization. If its name is the same as the primary template's, we - // assume the use should be attributed to the specialization. This heuristic - // fails when a member class bears the same name with its container. - // - // template - // struct C { struct C {}; }; - // C::C a; - // - // We will attribute |::C| to the parent class. - if (param->toplevel_type) { - IndexType& ref_type = *param->toplevel_type; - std::string name = cursor.get_referenced().get_spell_name(); - if (name == ref_type.def.Name(false)) { - AddUseSpell(db, ref_type.uses, cursor); - param->toplevel_type = nullptr; - return; - } - } - - std::optional referenced_usr = - cursor.get_referenced() - .template_specialization_to_template_definition() - .get_opt_usr_hash(); - // In STL this may be empty. - if (!referenced_usr) - return; - - IndexType& ref_type = db->ToType(*referenced_usr); - - if (!param->initial_type) - param->initial_type = &ref_type; - - // TODO: Should we even be visiting this if the file is not from the main - // def? Try adding assert on |loc| later. - AddUseSpell(db, ref_type.uses, cursor); -} - -ClangCursor::VisitResult VisitDeclForTypeUsageVisitor( - ClangCursor cursor, - ClangCursor parent, - VisitDeclForTypeUsageParam* param) { - switch (cursor.get_kind()) { - case CXCursor_TemplateRef: - case CXCursor_TypeRef: - if (param->previous_cursor) { - VisitDeclForTypeUsageVisitorHandler(param->previous_cursor.value(), - param); - } - - param->previous_cursor = cursor; - return ClangCursor::VisitResult::Continue; - - // We do not want to recurse for everything, since if we do that we will end - // up visiting method definition bodies/etc. Instead, we only recurse for - // things that can logically appear as part of an inline variable - // initializer, - // ie, - // - // class Foo { - // int x = (Foo)3; - // } - case CXCursor_CallExpr: - case CXCursor_CStyleCastExpr: - case CXCursor_CXXStaticCastExpr: - case CXCursor_CXXReinterpretCastExpr: - return ClangCursor::VisitResult::Recurse; - - default: - return ClangCursor::VisitResult::Continue; - } - - return ClangCursor::VisitResult::Continue; -} - -// Add usages to any seen TypeRef or TemplateRef under the given |decl_cursor|. -// This returns the first seen TypeRef or TemplateRef value, which can be -// useful if trying to figure out ie, what a using statement refers to. If -// trying to generally resolve a cursor to a type, use -// ResolveToDeclarationType, which works in more scenarios. -// If |decl_cursor| is a variable of a template type, clang_getCursorType -// may return a specialized template which is preciser than the primary -// template. -// We use |toplevel_type| to attribute the use to the specialized template -// instead of the primary template. -IndexType* AddDeclTypeUsages(IndexFile* db, - ClangCursor decl_cursor, - IndexType* toplevel_type, - const CXIdxContainerInfo* semantic_container, - const CXIdxContainerInfo* lexical_container) { - // - // The general AST format for definitions follows this pattern: - // - // template - // struct Container; - // - // struct S1; - // struct S2; - // - // Container, S2> foo; - // - // => - // - // VarDecl - // TemplateRef Container - // TemplateRef Container - // TypeRef struct S1 - // TypeRef struct S2 - // TypeRef struct S2 - // - // - // Here is another example: - // - // enum A {}; - // enum B {}; - // - // template - // struct Foo { - // struct Inner {}; - // }; - // - // Foo::Inner a; - // Foo b; - // - // => - // - // EnumDecl A - // EnumDecl B - // ClassTemplate Foo - // TemplateTypeParameter T - // StructDecl Inner - // VarDecl a - // TemplateRef Foo - // TypeRef enum A - // TypeRef struct Foo::Inner - // CallExpr Inner - // VarDecl b - // TemplateRef Foo - // TypeRef enum B - // CallExpr Foo - // - // - // Determining the actual type of the variable/declaration from just the - // children is tricky. Doing so would require looking up the template - // definition associated with a TemplateRef, figuring out how many children - // it has, and then skipping that many TypeRef values. This also has to work - // with the example below (skipping the last TypeRef). As a result, we - // determine variable types using |ResolveToDeclarationType|. - // - // - // We skip the last type reference for methods/variables which are defined - // out-of-line w.r.t. the parent type. - // - // S1* Foo::foo() {} - // - // The above example looks like this in the AST: - // - // CXXMethod foo - // TypeRef struct S1 - // TypeRef class Foo - // CompoundStmt - // ... - // - // The second TypeRef is an uninteresting usage. - bool process_last_type_ref = true; - if (IsTypeDefinition(semantic_container) && - !IsTypeDefinition(lexical_container)) { - // - // In some code, such as the following example, we receive a cursor which is - // not - // a definition and is not associated with a definition due to an error - // condition. - // In this case, it is the Foo::Foo constructor. - // - // struct Foo {}; - // - // template - // Foo::Foo() {} - // - if (!decl_cursor.is_definition()) { - ClangCursor def = decl_cursor.get_definition(); - if (def.get_kind() != CXCursor_FirstInvalid) - decl_cursor = def; - } - process_last_type_ref = false; - } - - VisitDeclForTypeUsageParam param(db, toplevel_type); - decl_cursor.VisitChildren(&VisitDeclForTypeUsageVisitor, ¶m); - - // VisitDeclForTypeUsageVisitor guarantees that if there are multiple TypeRef - // children, the first one will always be visited. - if (param.previous_cursor && process_last_type_ref) { - VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), ¶m); - } else { - // If we are not processing the last type ref, it *must* be a TypeRef or - // TemplateRef. - // - // We will not visit every child if the is_interseting is false, so - // previous_cursor - // may not point to the last TemplateRef. - assert(param.previous_cursor.has_value() == false || - (param.previous_cursor.value().get_kind() == CXCursor_TypeRef || - param.previous_cursor.value().get_kind() == CXCursor_TemplateRef)); - } - - if (param.initial_type) - return param.initial_type; - CXType cx_under = clang_getTypedefDeclUnderlyingType(decl_cursor.cx_cursor); - if (cx_under.kind == CXType_Invalid) - return nullptr; - return &db->ToType(ClangType(cx_under).strip_qualifiers().get_usr_hash()); -} - -// Various versions of LLVM (ie, 4.0) will not visit inline variable references -// for template arguments. -ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor, - ClangCursor parent, - IndexFile* db) { - /* - We need to index the |DeclRefExpr| below (ie, |var| inside of - Foo::var). - - template - struct Foo { - static constexpr int var = 3; - }; - - int a = Foo::var; - - => - - VarDecl a - UnexposedExpr var - DeclRefExpr var - TemplateRef Foo - - */ - - switch (cursor.get_kind()) { - case CXCursor_DeclRefExpr: { - if (cursor.get_referenced().get_kind() != CXCursor_VarDecl) - break; - - // TODO: when we resolve the template type to the definition, we get a - // different Usr. - - // ClangCursor ref = - // cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr_hash(); - // std::string ref_usr = - // cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr_hash(); - auto ref_usr = cursor.get_referenced() - .template_specialization_to_template_definition() - .get_opt_usr_hash(); - if (!ref_usr) - break; - IndexVar& ref_var = db->ToVar(*ref_usr); - AddUseSpell(db, ref_var.uses, cursor); - break; - } - - default: - break; - } - - return ClangCursor::VisitResult::Recurse; -} - -ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, - ClangCursor parent, - IndexParam* param) { - switch (cursor.get_kind()) { - case CXCursor_MacroDefinition: - case CXCursor_MacroExpansion: { - // Resolve location, find IndexFile instance. - CXSourceRange cx_source_range = - clang_Cursor_getSpellingNameRange(cursor.cx_cursor, 0, 0); - CXFile file; - Range decl_loc_spelling = ResolveCXSourceRange(cx_source_range, &file); - IndexFile* db = ConsumeFile(param, file); - if (!db) - break; - - // TODO: Considering checking clang_Cursor_isMacroFunctionLike, but the - // only real difference will be that we show 'callers' instead of 'refs' - // (especially since macros cannot have overrides) - - Usr decl_usr; - if (cursor.get_kind() == CXCursor_MacroDefinition) - decl_usr = cursor.get_usr_hash(); - else - decl_usr = cursor.get_referenced().get_usr_hash(); - - IndexVar& var_def = db->ToVar(decl_usr); - if (cursor.get_kind() == CXCursor_MacroDefinition) { - CXSourceRange cx_extent = clang_getCursorExtent(cursor.cx_cursor); - var_def.def.detailed_name = Intern(cursor.get_display_name()); - var_def.def.qual_name_offset = 0; - var_def.def.short_name_offset = 0; - var_def.def.short_name_size = - int16_t(strlen(var_def.def.detailed_name)); - var_def.def.hover = - Intern("#define " + - GetDocumentContentInRange(param->tu->cx_tu, cx_extent)); - var_def.def.kind = lsSymbolKind::Macro; - if (g_config->index.comments) - var_def.def.comments = Intern(cursor.get_comments()); - var_def.def.spell = - SetUse(db, decl_loc_spelling, parent, Role::Definition); - var_def.def.extent = SetUse( - db, ResolveCXSourceRange(cx_extent, nullptr), parent, Role::None); - } else - AddUse(db, var_def.uses, decl_loc_spelling, parent); - - break; - } - default: - break; - } - - return ClangCursor::VisitResult::Continue; -} - -namespace { - -// TODO Move to another file and use clang C++ API -struct TemplateVisitorData { - IndexFile* db; - IndexParam* param; - ClangCursor container; -}; - -ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, - ClangCursor parent, - TemplateVisitorData* data) { - IndexFile* db = data->db; - IndexParam* param = data->param; - switch (cursor.get_kind()) { - default: - break; - case CXCursor_DeclRefExpr: { - ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); - if (ref_cursor.get_kind() == CXCursor_NonTypeTemplateParameter) { - IndexVar& ref_var = db->ToVar(ref_cursor); - if (!ref_var.def.detailed_name[0]) { - ClangCursor sem_parent = ref_cursor.get_semantic_parent(); - ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - 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.def.kind = lsSymbolKind::TypeParameter; - SetVarDetail(ref_var, ref_cursor.get_spell_name(), ref_cursor, - nullptr, true, db, param); - - ClangType ref_type_c = clang_getCursorType(ref_cursor.cx_cursor); - // TODO optimize - if (ref_type_c.get_usr().size()) { - IndexType& ref_type = db->ToType(ref_type_c.get_usr_hash()); - // The cursor extent includes `type name`, not just `name`. There - // seems no way to extract the spelling range of `type` and we do - // not want to do subtraction here. - // See https://github.com/cquery-project/cquery/issues/252 - AddUse(db, ref_type.uses, ref_cursor.get_extent(), - ref_cursor.get_lexical_parent()); - } - } - AddUseSpell(db, ref_var.uses, cursor); - } - break; - } - case CXCursor_OverloadedDeclRef: { - unsigned num_overloaded = clang_getNumOverloadedDecls(cursor.cx_cursor); - for (unsigned i = 0; i != num_overloaded; i++) { - ClangCursor overloaded = clang_getOverloadedDecl(cursor.cx_cursor, i); - switch (overloaded.get_kind()) { - default: - break; - case CXCursor_FunctionDecl: - case CXCursor_FunctionTemplate: { - IndexFunc& called = db->ToFunc(overloaded.get_usr_hash()); - OnIndexReference_Function(db, cursor.get_spell(), data->container, - called, Role::Call); - break; - } - } - } - break; - } - case CXCursor_TemplateRef: { - ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); - if (ref_cursor.get_kind() == CXCursor_TemplateTemplateParameter) { - IndexType& ref_type = db->ToType(ref_cursor); - // TODO It seems difficult to get references to template template - // parameters. - // CXCursor_TemplateTemplateParameter can be visited by visiting - // CXCursor_TranslationUnit, but not (confirm this) by visiting - // {Class,Function}Template. Thus we need to initialize it here. - if (!ref_type.def.detailed_name[0]) { - ClangCursor sem_parent = ref_cursor.get_semantic_parent(); - ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - 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 - ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); -#else - ref_type.def.detailed_name = Intern(ref_cursor.get_spell_name()); -#endif - ref_type.def.short_name_offset = 0; - ref_type.def.short_name_size = - int16_t(strlen(ref_type.def.detailed_name)); - ref_type.def.kind = lsSymbolKind::TypeParameter; - } - AddUseSpell(db, ref_type.uses, cursor); - } - break; - } - case CXCursor_TypeRef: { - ClangCursor ref_cursor = clang_getCursorReferenced(cursor.cx_cursor); - if (ref_cursor.get_kind() == CXCursor_TemplateTypeParameter) { - IndexType& ref_type = db->ToType(ref_cursor); - // TODO It seems difficult to get a FunctionTemplate's template - // parameters. - // CXCursor_TemplateTypeParameter can be visited by visiting - // CXCursor_TranslationUnit, but not (confirm this) by visiting - // {Class,Function}Template. Thus we need to initialize it here. - if (!ref_type.def.detailed_name[0]) { - ClangCursor sem_parent = ref_cursor.get_semantic_parent(); - ClangCursor lex_parent = ref_cursor.get_lexical_parent(); - 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 - // template void f(T t){} // weird, the name is empty - ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); -#else - ref_type.def.detailed_name = Intern(ref_cursor.get_spell_name()); -#endif - ref_type.def.short_name_offset = 0; - ref_type.def.short_name_size = - int16_t(strlen(ref_type.def.detailed_name)); - ref_type.def.kind = lsSymbolKind::TypeParameter; - } - AddUseSpell(db, ref_type.uses, cursor); - } - break; - } - } - return ClangCursor::VisitResult::Recurse; -} - -} // namespace - -std::tuple NamespaceHelper::QualifiedName( - const CXIdxContainerInfo* container, - std::string_view unqualified_name) { - if (!container) - return {std::string(unqualified_name), 0, 0}; - // Anonymous namespaces are not processed by indexDeclaration. We trace - // nested namespaces bottom-up through clang_getCursorSemanticParent until - // one that we know its qualified name. Then do another trace top-down and - // put their names into a map of USR -> qualified_name. - ClangCursor cursor(container->cursor); - std::vector namespaces; - std::string qualifier; - while (cursor.get_kind() != CXCursor_TranslationUnit && - GetSymbolKind(cursor.get_kind()) == SymbolKind::Type) { - auto it = usr2qualified_name.find(cursor.get_usr_hash()); - if (it != usr2qualified_name.end()) { - qualifier = it->second; - break; - } - namespaces.push_back(cursor); - cursor = clang_getCursorSemanticParent(cursor.cx_cursor); - } - for (size_t i = namespaces.size(); i > 0;) { - i--; - std::string name = namespaces[i].get_spell_name(); - // Empty name indicates unnamed namespace, anonymous struct, anonymous - // union, ... - if (name.size()) - qualifier += name; - else - qualifier += GetAnonName(namespaces[i].get_kind()); - qualifier += "::"; - usr2qualified_name[namespaces[i].get_usr_hash()] = qualifier; - } - int16_t pos = qualifier.size(); - qualifier.append(unqualified_name); - return {qualifier, pos, int16_t(unqualified_name.size())}; -} - -void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { - IndexParam* param = static_cast(client_data); - - // Track all constructor declarations, as we may need to use it to manually - // associate std::make_unique and the like as constructor invocations. - if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor) { - param->ctors.NotifyConstructor(decl->cursor); - } - - CXFile file; - clang_getSpellingLocation(clang_indexLoc_getCXSourceLocation(decl->loc), - &file, nullptr, nullptr, nullptr); - IndexFile* db = ConsumeFile(param, file); - if (!db) - return; - - // The language of this declaration - LanguageId decl_lang = [&decl]() { - switch (clang_getCursorLanguage(decl->cursor)) { - case CXLanguage_C: - return LanguageId::C; - case CXLanguage_CPlusPlus: - return LanguageId::Cpp; - case CXLanguage_ObjC: - return LanguageId::ObjC; - default: - return LanguageId::Unknown; - }; - }(); - - // Only update the file language if the new language is "greater" than the old - if (decl_lang > db->language) { - db->language = decl_lang; - } - - ClangCursor sem_parent(fromContainer(decl->semanticContainer)); - ClangCursor lex_parent(fromContainer(decl->lexicalContainer)); - ClangCursor cursor = decl->cursor; - - switch (decl->entityInfo->kind) { - case CXIdxEntity_Unexposed: - LOG_S(INFO) << "CXIdxEntity_Unexposed " << cursor.get_spell_name(); - break; - - case CXIdxEntity_CXXNamespace: { - Range spell = cursor.get_spell(); - IndexType& ns = db->ToType(HashUsr(decl->entityInfo->USR)); - ns.def.kind = GetSymbolKind(decl->entityInfo->kind); - if (!ns.def.detailed_name[0]) { - 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); - if (decl->semanticContainer) { - IndexType& parent = db->ToType(decl->semanticContainer->cursor); - parent.derived.push_back(ns.usr); - ns.def.bases.push_back(parent.usr); - } - } - AddUse(db, ns.uses, spell, lex_parent); - break; - } - - case CXIdxEntity_CXXNamespaceAlias: - assert(false && "CXXNamespaceAlias"); - break; - - case CXIdxEntity_ObjCProperty: - case CXIdxEntity_ObjCIvar: - case CXIdxEntity_EnumConstant: - case CXIdxEntity_Field: - case CXIdxEntity_Variable: - case CXIdxEntity_CXXStaticVariable: { - Range spell = cursor.get_spell(); - - // Do not index implicit template instantiations. - if (cursor != cursor.template_specialization_to_template_definition()) - break; - - IndexVar& var = db->ToVar(HashUsr(decl->entityInfo->USR)); - - // TODO: Eventually run with this if. Right now I want to iron out bugs - // this may shadow. - // TODO: Verify this gets called multiple times - // if (!decl->isRedeclaration) { - SetVarDetail(var, std::string(decl->entityInfo->name), decl->cursor, - decl->semanticContainer, !decl->isRedeclaration, db, param); - - var.def.kind = GetSymbolKind(decl->entityInfo->kind); - if (var.def.kind == lsSymbolKind::Variable && - decl->cursor.kind == CXCursor_ParmDecl) - var.def.kind = lsSymbolKind::Parameter; - //} - - if (!decl->isDefinition) - var.declarations.push_back( - SetUse(db, spell, lex_parent, Role::Declaration)); - // For `static const`, a definition at namespace scope is not required - // unless odr-used. - if (decl->isDefinition || - (decl->entityInfo->kind == CXIdxEntity_CXXStaticVariable && - clang_isConstQualifiedType(clang_getCursorType(decl->cursor)))) { - var.def.spell = SetUse(db, spell, sem_parent, Role::Definition); - var.def.extent = - SetUse(db, cursor.get_extent(), lex_parent, Role::None); - } - - cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db); - - // Declaring variable type information. Note that we do not insert an - // interesting reference for parameter declarations - that is handled when - // 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 ? &db->ToType(var.def.type) : nullptr, - decl->semanticContainer, decl->lexicalContainer); - - // We don't need to assign declaring type multiple times if this variable - // has already been seen. - - if (decl->isDefinition && decl->semanticContainer) { - switch (GetSymbolKind(decl->semanticContainer->cursor.kind)) { - case SymbolKind::Func: { - db->ToFunc(decl->semanticContainer->cursor) - .def.vars.push_back(var.usr); - break; - } - case SymbolKind::Type: { - CXCursor parent = decl->semanticContainer->cursor; - long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor); - while (parent.kind != CXCursor_EnumDecl) { - IndexType& type = db->ToType(parent); - type.def.vars.emplace_back(var.usr, offset); - if (!clang_Cursor_isAnonymous(parent)) break; - parent = clang_getCursorSemanticParent(parent); - offset = -1; - if (GetSymbolKind(parent.kind) != SymbolKind::Type) break; - } - break; - } - default: - break; - } - } - - break; - } - - case CXIdxEntity_ObjCInstanceMethod: - case CXIdxEntity_ObjCClassMethod: - case CXIdxEntity_Function: - case CXIdxEntity_CXXConstructor: - case CXIdxEntity_CXXDestructor: - case CXIdxEntity_CXXInstanceMethod: - case CXIdxEntity_CXXStaticMethod: - case CXIdxEntity_CXXConversionFunction: { - Range spell = cursor.get_spell(); - Range extent = cursor.get_extent(); - - ClangCursor decl_cursor_resolved = - cursor.template_specialization_to_template_definition(); - bool is_template_specialization = cursor != decl_cursor_resolved; - - IndexFunc& func = db->ToFunc(decl_cursor_resolved); - if (g_config->index.comments) - func.def.comments = Intern(cursor.get_comments()); - func.def.kind = GetSymbolKind(decl->entityInfo->kind); - func.def.storage = - GetStorageC(clang_Cursor_getStorageClass(decl->cursor)); - - // We don't actually need to know the return type, but we need to mark it - // as an interesting usage. - AddDeclTypeUsages(db, cursor, nullptr, decl->semanticContainer, - decl->lexicalContainer); - - // Add definition or declaration. This is a bit tricky because we treat - // template specializations as declarations, even though they are - // technically definitions. - bool is_def = decl->isDefinition; - if (!is_def) { - auto* D = static_cast(decl->cursor.data[0]); - auto* Method = dyn_cast_or_null(D->getAsFunction()); - is_def = Method && (Method->isDefaulted() || Method->isPure()); - } - if (is_def && !is_template_specialization) { - func.def.spell = SetUse(db, spell, sem_parent, Role::Definition); - func.def.extent = SetUse(db, extent, lex_parent, Role::None); - } else { - func.declarations.push_back( - SetUse(db, spell, lex_parent, Role::Declaration)); - } - - // Emit definition data for the function. We do this even if it isn't a - // definition because there can be, for example, interfaces, or a class - // declaration that doesn't have a definition yet. If we never end up - // indexing the definition, then there will not be any (ie) outline - // information. - if (!is_template_specialization) { - std::string detailed; - std::tie(detailed, func.def.qual_name_offset, - func.def.short_name_offset, func.def.short_name_size) = - param->PrettyPrintCursor(decl->cursor, decl->entityInfo->name); - func.def.detailed_name = Intern(detailed); - - // CXCursor_OverloadedDeclRef in templates are not processed by - // OnIndexReference, thus we use TemplateVisitor to collect function - // references. - if (decl->entityInfo->templateKind == CXIdxEntity_Template) { - TemplateVisitorData data; - data.db = db; - data.param = param; - data.container = cursor; - cursor.VisitChildren(&TemplateVisitor, &data); - } - - // Add function usage information. We only want to do it once per - // definition/declaration. Do it on definition since there should only - // ever be one of those in the entire program. - if (IsTypeDefinition(decl->semanticContainer)) { - IndexType& declaring_type = - db->ToType(decl->semanticContainer->cursor); - func.def.declaring_type = declaring_type.usr; - - // Mark a type reference at the ctor/dtor location. - if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor) - AddUse(db, declaring_type.uses, spell, - fromContainer(decl->lexicalContainer)); - - // Add function to declaring type. - declaring_type.def.funcs.push_back(func.usr); - } - - // Process inheritance. - if (clang_CXXMethod_isVirtual(decl->cursor)) { - CXCursor* overridden; - unsigned int num_overridden; - clang_getOverriddenCursors(decl->cursor, &overridden, - &num_overridden); - - for (unsigned i = 0; i < num_overridden; ++i) { - ClangCursor parent = - ClangCursor(overridden[i]) - .template_specialization_to_template_definition(); - IndexFunc& parent_def = db->ToFunc(parent); - func.def.bases.push_back(parent_def.usr); - parent_def.derived.push_back(func.usr); - } - - clang_disposeOverriddenCursors(overridden); - } - } - break; - } - - case CXIdxEntity_Typedef: - case CXIdxEntity_CXXTypeAlias: { - IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); - CXType Type = clang_getCursorType(decl->entityInfo->cursor); - CXType CanonType = clang_getCanonicalType(Type);; - if (clang_equalTypes(Type, CanonType) == 0) { - Usr type_usr = ClangType(CanonType).get_usr_hash(); - if (db->usr2type.count(type_usr)) { - type.def.alias_of = type_usr; - } else { - // Note we want to fetch the first TypeRef. Running - // ResolveCursorType(decl->cursor) would return - // the type of the typedef/using, not the type of the referenced type. - IndexType* alias_of = AddDeclTypeUsages( - db, cursor, nullptr, decl->semanticContainer, decl->lexicalContainer); - if (alias_of) - type.def.alias_of = alias_of->usr; - } - } - - Range spell = cursor.get_spell(); - Range extent = cursor.get_extent(); - type.def.spell = SetUse(db, spell, sem_parent, Role::Definition); - type.def.extent = SetUse(db, extent, lex_parent, Role::None); - - SetTypeName(type, cursor, decl->semanticContainer, - decl->entityInfo->name, param); - type.def.kind = GetSymbolKind(decl->entityInfo->kind); - if (g_config->index.comments) - type.def.comments = Intern(cursor.get_comments()); - - // For Typedef/CXXTypeAlias spanning a few lines, display the declaration - // line, with spelling name replaced with qualified name. - if (extent.end.line - extent.start.line < kMaxDetailedLines) { - FileContents& fc = param->file_contents[db->path]; - std::optional extent_start = fc.ToOffset(extent.start), - spell_start = fc.ToOffset(spell.start), - spell_end = fc.ToOffset(spell.end), - extent_end = fc.ToOffset(extent.end); - if (extent_start && spell_start && spell_end && extent_end) { - type.def.hover = Intern( - fc.content.substr(*extent_start, *spell_start - *extent_start) + - type.def.detailed_name + - fc.content.substr(*spell_end, *extent_end - *spell_end)); - } - } - - AddUse(db, type.uses, spell, fromContainer(decl->lexicalContainer)); - break; - } - - case CXIdxEntity_ObjCProtocol: - case CXIdxEntity_ObjCCategory: - case CXIdxEntity_ObjCClass: - case CXIdxEntity_Enum: - case CXIdxEntity_Union: - case CXIdxEntity_Struct: - case CXIdxEntity_CXXInterface: - case CXIdxEntity_CXXClass: { - Range spell = cursor.get_spell(); - - IndexType& type = db->ToType(HashUsr(decl->entityInfo->USR)); - - SetTypeName(type, cursor, decl->semanticContainer, decl->entityInfo->name, - param); - type.def.kind = GetSymbolKind(decl->entityInfo->kind); - if (g_config->index.comments) - type.def.comments = Intern(cursor.get_comments()); - - if (decl->isDefinition) { - type.def.spell = SetUse(db, spell, sem_parent, Role::Definition); - type.def.extent = - SetUse(db, cursor.get_extent(), lex_parent, Role::None); - - if (cursor.get_kind() == CXCursor_EnumDecl) { - ClangType enum_type = clang_getEnumDeclIntegerType(decl->cursor); - if (!enum_type.is_builtin()) { - IndexType& int_type = db->ToType(enum_type.get_usr_hash()); - AddUse(db, int_type.uses, spell, - fromContainer(decl->lexicalContainer)); - } - } - } else - AddUse(db, type.declarations, spell, - fromContainer(decl->lexicalContainer), Role::Declaration); - - switch (decl->entityInfo->templateKind) { - default: - break; - case CXIdxEntity_TemplateSpecialization: - case CXIdxEntity_TemplatePartialSpecialization: { - // TODO Use a different dimension - ClangCursor origin_cursor = - cursor.template_specialization_to_template_definition(); - IndexType& origin = db->ToType(origin_cursor); - // template class function; // not visited by - // OnIndexDeclaration template<> class function {}; // current - // cursor - if (!origin.def.detailed_name[0]) { - SetTypeName(origin, origin_cursor, nullptr, - &type.def.Name(false)[0], param); - origin.def.kind = type.def.kind; - } - // TODO The name may be assigned in |ResolveToDeclarationType| but - // |spell| is std::nullopt. - CXFile origin_file; - Range origin_spell = origin_cursor.get_spell(&origin_file); - if (!origin.def.spell && file == origin_file) { - ClangCursor origin_sem = origin_cursor.get_semantic_parent(); - ClangCursor origin_lex = origin_cursor.get_lexical_parent(); - origin.def.spell = - SetUse(db, origin_spell, origin_sem, Role::Definition); - origin.def.extent = - SetUse(db, origin_cursor.get_extent(), origin_lex, Role::None); - } - origin.derived.push_back(type.usr); - type.def.bases.push_back(origin.usr); - [[fallthrough]]; - } - case CXIdxEntity_Template: { - TemplateVisitorData data; - data.db = db; - data.container = cursor; - data.param = param; - cursor.VisitChildren(&TemplateVisitor, &data); - break; - } - } - - // Add type-level inheritance information. - CXIdxCXXClassDeclInfo const* class_info = - clang_index_getCXXClassDeclInfo(decl); - if (class_info) { - for (unsigned int i = 0; i < class_info->numBases; ++i) { - const CXIdxBaseClassInfo* base_class = class_info->bases[i]; - - AddDeclTypeUsages(db, base_class->cursor, nullptr, - decl->semanticContainer, decl->lexicalContainer); - IndexType* parent_type = - ResolveToDeclarationType(db, base_class->cursor, param); - if (parent_type) { - parent_type->derived.push_back(type.usr); - type.def.bases.push_back(parent_type->usr); - } - } - } - break; - } - } -} - -// Type-dependent member access expressions do not have accurate spelling -// ranges. -// -// Not type dependent -// C f; f.x // .x produces a MemberRefExpr which has a spelling range -// of `x`. -// -// Type dependent -// C e; e.x // .x produces a MemberRefExpr which has a spelling range -// of `e` (weird) and an empty spelling name. -// -// To attribute the use of `x` in `e.x`, we use cursor extent `e.x` -// minus cursor spelling `e` minus the period. -void CheckTypeDependentMemberRefExpr(Range* spell, - const ClangCursor& cursor, - IndexParam* param, - const IndexFile* db) { - if (cursor.get_kind() == CXCursor_MemberRefExpr && - cursor.get_spell_name().empty()) { - *spell = cursor.get_extent().RemovePrefix(spell->end); - const FileContents& fc = param->file_contents[db->path]; - std::optional maybe_period = fc.ToOffset(spell->start); - if (maybe_period) { - int i = *maybe_period; - if (fc.content[i] == '.') - spell->start.column++; - // -> is likely unexposed. - } - } -} - -void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { - // TODO: Use clang_getFileUniqueID - CXFile file; - clang_getSpellingLocation(clang_indexLoc_getCXSourceLocation(ref->loc), &file, - nullptr, nullptr, nullptr); - IndexParam* param = static_cast(client_data); - IndexFile* db = ConsumeFile(param, file); - if (!db) - return; - - ClangCursor cursor(ref->cursor); - ClangCursor lex_parent(fromContainer(ref->container)); - ClangCursor referenced; - if (ref->referencedEntity) - referenced = ref->referencedEntity->cursor; - - switch (ref->referencedEntity->kind) { - case CXIdxEntity_Unexposed: - LOG_S(INFO) << "CXIdxEntity_Unexposed " << cursor.get_spell_name(); - break; - - case CXIdxEntity_CXXNamespace: { - IndexType& ns = db->ToType(referenced.get_usr_hash()); - AddUse(db, ns.uses, cursor.get_spell(), fromContainer(ref->container)); - break; - } - - case CXIdxEntity_CXXNamespaceAlias: { - IndexType& ns = db->ToType(referenced.get_usr_hash()); - AddUse(db, ns.uses, cursor.get_spell(), fromContainer(ref->container)); - if (!ns.def.spell) { - ClangCursor sem_parent = referenced.get_semantic_parent(); - ClangCursor lex_parent = referenced.get_lexical_parent(); - CXFile referenced_file; - Range spell = referenced.get_spell(&referenced_file); - if (file == referenced_file) { - ns.def.spell = SetUse(db, 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); - } - } - break; - } - - case CXIdxEntity_ObjCProperty: - case CXIdxEntity_ObjCIvar: - case CXIdxEntity_EnumConstant: - case CXIdxEntity_CXXStaticVariable: - case CXIdxEntity_Variable: - case CXIdxEntity_Field: { - Range loc = cursor.get_spell(); - CheckTypeDependentMemberRefExpr(&loc, cursor, param, db); - - referenced = referenced.template_specialization_to_template_definition(); - - IndexVar& var = db->ToVar(referenced); - // Lambda paramaters are not processed by OnIndexDeclaration and - // may not have a short_name yet. Note that we only process the lambda - // parameter as a definition if it is in the same file as the reference, - // as lambdas cannot be split across files. - if (!var.def.detailed_name[0]) { - CXFile referenced_file; - 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); - - // TODO Some of the logic here duplicates CXIdxEntity_Variable branch - // of OnIndexDeclaration. But there `decl` is of type CXIdxDeclInfo - // and has more information, thus not easy to reuse the code. - SetVarDetail(var, referenced.get_spell_name(), referenced, nullptr, - true, db, param); - var.def.kind = lsSymbolKind::Parameter; - } - } - AddUse(db, var.uses, loc, fromContainer(ref->container), - GetRole(ref, Role::Reference)); - break; - } - - case CXIdxEntity_CXXConversionFunction: - case CXIdxEntity_CXXStaticMethod: - case CXIdxEntity_CXXInstanceMethod: - case CXIdxEntity_ObjCInstanceMethod: - case CXIdxEntity_ObjCClassMethod: - case CXIdxEntity_Function: - case CXIdxEntity_CXXConstructor: - case CXIdxEntity_CXXDestructor: { - // TODO: Redirect container to constructor for the following example, ie, - // we should be inserting an outgoing function call from the Foo - // ctor. - // - // int Gen() { return 5; } - // class Foo { - // int x = Gen(); - // } - - // TODO: search full history? - Range loc = cursor.get_spell(); - - IndexFunc& called = db->ToFunc(HashUsr(ref->referencedEntity->USR)); - - std::string_view short_name = called.def.Name(false); - // libclang doesn't provide a nice api to check if the given function - // call is implicit. ref->kind should probably work (it's either direct - // or implicit), but libclang only supports implicit for objective-c. - bool is_implicit = - CanBeCalledImplicitly(ref->referencedEntity->kind) && - // Treats empty short_name as an implicit call like implicit move - // constructor in `vector a = f();` - (short_name.empty() || - // For explicit destructor call, ref->cursor may be "~" while - // called->def.short_name is "~A" - // "~A" is not a substring of ref->cursor, but we should take this - // case as not `is_implicit`. - (short_name[0] != '~' && - !CursorSpellingContainsString(ref->cursor, param->tu->cx_tu, - short_name))); - - // Extents have larger ranges and thus less specific, and will be - // overriden by other functions if exist. - // - // Type-dependent member access expressions do not have useful spelling - // ranges. See the comment above for the CXIdxEntity_Field case. - if (is_implicit) - loc = cursor.get_extent(); - else - CheckTypeDependentMemberRefExpr(&loc, cursor, param, db); - - OnIndexReference_Function( - db, loc, ref->container->cursor, called, - GetRole(ref, Role::Call) | - (is_implicit ? Role::Implicit : Role::None)); - - // Checks if |str| starts with |start|. Ignores case. - auto str_begin = [](const char* start, const char* str) { - while (*start && *str) { - char a = tolower(*start); - char b = tolower(*str); - if (a != b) - return false; - ++start; - ++str; - } - return !*start; - }; - - bool is_template = ref->referencedEntity->templateKind != - CXIdxEntityCXXTemplateKind::CXIdxEntity_NonTemplate; - if (g_config->index.attributeMakeCallsToCtor && is_template && - str_begin("make", ref->referencedEntity->name)) { - // Try to find the return type of called function. That type will have - // the constructor function we add a usage to. - std::optional opt_found_type = FindType(ref->cursor); - if (opt_found_type) { - Usr ctor_type_usr = opt_found_type->get_referenced().get_usr_hash(); - ClangCursor call_cursor = ref->cursor; - - // Build a type description from the parameters of the call, so we - // can try to find a constructor with the same type description. - std::vector call_type_desc; - for (ClangType type : call_cursor.get_type().get_arguments()) { - std::string type_desc = type.get_spell_name(); - if (!type_desc.empty()) - call_type_desc.push_back(type_desc); - } - - // Try to find the constructor and add a reference. - std::optional ctor_usr = - param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc); - if (ctor_usr) { - IndexFunc& ctor = db->ToFunc(*ctor_usr); - ctor.uses.push_back( - Use{{loc, 0, SymbolKind::File, Role::Call | Role::Implicit}}); - } - } - } - - break; - } - - case CXIdxEntity_ObjCCategory: - case CXIdxEntity_ObjCProtocol: - case CXIdxEntity_ObjCClass: - case CXIdxEntity_Typedef: - case CXIdxEntity_CXXInterface: // MSVC __interface - case CXIdxEntity_CXXTypeAlias: - case CXIdxEntity_Enum: - case CXIdxEntity_Union: - case CXIdxEntity_Struct: - case CXIdxEntity_CXXClass: { - referenced = referenced.template_specialization_to_template_definition(); - IndexType& ref_type = db->ToType(referenced); - if (!ref->parentEntity || IsDeclContext(ref->parentEntity->kind)) - AddUseSpell(db, ref_type.declarations, ref->cursor); - else - AddUseSpell(db, ref_type.uses, ref->cursor); - break; - } - } -} std::vector> ClangIndexer::Index( VFS* vfs, @@ -2054,88 +664,90 @@ std::vector> ClangIndexer::Index( file = NormalizePath(file); - static Timer timer("parse", "parse tu"); - timer.startTimer(); + std::vector Args; + for (auto& arg: args) + Args.push_back(arg.c_str()); + Args.push_back("-Xclang"); + Args.push_back("-detailed-preprocessing-record"); + Args.push_back("-fno-spell-checking"); + auto PCHCO = std::make_shared(); + IntrusiveRefCntPtr + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + std::shared_ptr CI = + createInvocationFromCommandLine(Args, Diags); + if (!CI) + return {}; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; - std::vector unsaved_files; - for (const FileContents& contents : file_contents) { - CXUnsavedFile unsaved; - unsaved.Filename = contents.path.c_str(); - unsaved.Contents = contents.content.c_str(); - unsaved.Length = (unsigned long)contents.content.size(); - unsaved_files.push_back(unsaved); + std::vector> BufOwner; + for (auto &c : file_contents) { + std::unique_ptr MB = + llvm::MemoryBuffer::getMemBufferCopy(c.content, c.path); + CI->getPreprocessorOpts().addRemappedFile(c.path, MB.get()); + BufOwner.push_back(std::move(MB)); } - std::unique_ptr tu = ClangTranslationUnit::Create( - &index, file, args, unsaved_files, - CXTranslationUnit_KeepGoing | - CXTranslationUnit_DetailedPreprocessingRecord); - if (!tu) + auto Unit = ASTUnit::create(CI, Diags, true, true); + if (!Unit) return {}; - timer.stopTimer(); - - return ParseWithTu(vfs, tu.get(), &index, file, args, unsaved_files); -} - -std::vector> ParseWithTu( - VFS* vfs, - ClangTranslationUnit* tu, - ClangIndex* index, - const std::string& file, - const std::vector& args, - const std::vector& file_contents) { - IndexerCallbacks callback = {0}; - // Available callbacks: - // - abortQuery - // - enteredMainFile - // - ppIncludedFile - // - importedASTFile - // - startedTranslationUnit - callback.diagnostic = &OnIndexDiagnostic; - callback.ppIncludedFile = &OnIndexIncludedFile; - callback.indexDeclaration = &OnIndexDeclaration; - callback.indexEntityReference = &OnIndexReference; - FileConsumer file_consumer(vfs, file); - IndexParam param(tu, &file_consumer); - for (const CXUnsavedFile& contents : file_contents) { - param.file_contents[contents.Filename] = FileContents( - contents.Filename, std::string(contents.Contents, contents.Length)); - } - - CXFile cx_file = clang_getFile(tu->cx_tu, file.c_str()); - param.primary_file = ConsumeFile(¶m, cx_file); - - CXIndexAction index_action = clang_IndexAction_create(index->cx_index); - - // |index_result| is a CXErrorCode instance. - int index_result = clang_indexTranslationUnit( - index_action, ¶m, &callback, sizeof(IndexerCallbacks), - CXIndexOpt_IndexFunctionLocalSymbols | - CXIndexOpt_SkipParsedBodiesInSession | - CXIndexOpt_IndexImplicitTemplateInstantiations, - tu->cx_tu); - if (index_result != CXError_Success) { - LOG_S(ERROR) << "Indexing " << file - << " failed with errno=" << index_result; + IndexParam param(*Unit, &file_consumer); + auto DataConsumer = std::make_shared(param); + + index::IndexingOptions IndexOpts; + memset(&IndexOpts, 1, sizeof IndexOpts); + IndexOpts.SystemSymbolFilter = + index::IndexingOptions::SystemSymbolFilterKind::All; + IndexOpts.IndexFunctionLocals = true; + + std::unique_ptr IndexAction = + createIndexingAction(DataConsumer, IndexOpts, nullptr); + llvm::CrashRecoveryContextCleanupRegistrar IndexActionCleanup( + IndexAction.get()); + + DiagnosticErrorTrap DiagTrap(*Diags); + bool Success = ASTUnit::LoadFromCompilerInvocationAction( + std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), + /*Persistent=*/true, "/home/maskray/Dev/llvm/release/lib/clang/7.0.0", + /*OnlyLocalDecls=*/true, + /*CaptureDiagnostics=*/true, 0, false, false, true); + if (!Unit) { + LOG_S(ERROR) << "failed to index " << file; return {}; } - clang_IndexAction_dispose(index_action); - - ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) - .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); + if (!Success) + return {}; + // ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) + // .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); std::unordered_map inc_to_line; // TODO if (param.primary_file) for (auto& inc : param.primary_file->includes) inc_to_line[inc.resolved_path] = inc.line; + llvm::DenseMap> UID2skipped; + { + const SourceManager& SM = Unit->getSourceManager(); + PreprocessingRecord *PPRec = Unit->getPreprocessor().getPreprocessingRecord(); + if (PPRec) { + const std::vector& Skipped = PPRec->getSkippedRanges(); + for (auto& R : Skipped) { + unsigned UID; + Range range = FromTokenRange(SM, Unit->getLangOpts(), R, &UID); + UID2skipped[UID].push_back(range); + } + } + } + auto result = param.file_consumer->TakeLocalState(); for (std::unique_ptr& entry : result) { entry->import_file = file; entry->args = args; + auto it = UID2skipped.find(entry->UID); + if (it != UID2skipped.end()) + entry->skipped_ranges = std::move(it->second); for (auto& it : entry->usr2func) { // e.g. declaration + out-of-line definition Uniquify(it.second.derived); @@ -2179,21 +791,10 @@ std::vector> ParseWithTu( return result; } -bool ConcatTypeAndName(std::string& type, const std::string& name) { - bool ret = false; - if (type.size() && - (type.back() != ' ' && type.back() != '*' && type.back() != '&')) { - type.push_back(' '); - ret = true; - } - type.append(name); - return ret; -} - void IndexInit() { - clang_enableStackTraces(); - if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY")) - clang_toggleCrashRecovery(1); + // InitLLVM + CXIndex CXIdx = clang_createIndex(0, 0); + clang_disposeIndex(CXIdx); } // |SymbolRef| is serialized this way. diff --git a/src/indexer.h b/src/indexer.h index b7f06e15e..ec180cd1a 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -248,6 +248,7 @@ struct IndexFile { // files accepted by newer ccls. static const int kMinorVersion; + unsigned UID; std::string path; std::vector args; int64_t last_write_time = 0; @@ -260,7 +261,7 @@ struct IndexFile { std::string import_file; // Source ranges that were not processed. - std::vector skipped_by_preprocessor; + std::vector skipped_ranges; std::vector includes; llvm::StringMap dependencies; @@ -273,7 +274,7 @@ struct IndexFile { // File contents at the time of index. Not serialized. std::string file_contents; - IndexFile(const std::string& path, const std::string& contents); + IndexFile(unsigned UID, const std::string& path, const std::string& contents); IndexFunc& ToFunc(Usr usr); IndexType& ToType(Usr usr); @@ -293,14 +294,6 @@ struct NamespaceHelper { std::string_view unqualified_name); }; -std::vector> ParseWithTu( - VFS* vfs, - ClangTranslationUnit* tu, - ClangIndex* index, - const std::string& file, - const std::vector& args, - const std::vector& file_contents); - bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); diff --git a/src/main.cc b/src/main.cc index 8c3ae83c1..6f85f6304 100644 --- a/src/main.cc +++ b/src/main.cc @@ -28,7 +28,7 @@ std::string g_init_options; namespace { opt opt_help("h", desc("Alias for -help")); opt opt_verbose("v", desc("verbosity"), init(0)); -opt opt_test_index("test-index", desc("run index tests")); +opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests")); opt opt_test_unit("test-unit", desc("run unit tests")); opt opt_init("init", desc("extra initialization options")); @@ -91,9 +91,9 @@ int main(int argc, char** argv) { return res; } - if (opt_test_index) { + if (opt_test_index != "!") { language_server = false; - if (!RunIndexTests("", sys::Process::StandardInIsUserInput())) + if (!RunIndexTests(opt_test_index, sys::Process::StandardInIsUserInput())) return 1; } diff --git a/src/message_handler.cc b/src/message_handler.cc index 60aea6342..86e7d23c1 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -175,11 +175,11 @@ bool FindFileOrFail(DB* db, return false; } -void EmitInactiveLines(WorkingFile* working_file, - const std::vector& inactive_regions) { +void EmitSkippedRanges(WorkingFile *working_file, + const std::vector &skipped_ranges) { Out_CclsSetInactiveRegion out; out.params.uri = lsDocumentUri::FromPath(working_file->filename); - for (Range skipped : inactive_regions) { + for (Range skipped : skipped_ranges) { std::optional ls_skipped = GetLsRange(working_file, skipped); if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); diff --git a/src/message_handler.h b/src/message_handler.h index 58bb1329b..6b6daa6c9 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -141,8 +141,8 @@ bool FindFileOrFail(DB* db, QueryFile** out_query_file, int* out_file_id = nullptr); -void EmitInactiveLines(WorkingFile* working_file, - const std::vector& inactive_regions); +void EmitSkippedRanges(WorkingFile *working_file, + const std::vector &skipped_ranges); void EmitSemanticHighlighting(DB* db, SemanticHighlightSymbolCache* semantic_cache, diff --git a/src/messages/ccls_fileInfo.cc b/src/messages/ccls_fileInfo.cc index 689ef1f94..3c1a0fc59 100644 --- a/src/messages/ccls_fileInfo.cc +++ b/src/messages/ccls_fileInfo.cc @@ -9,7 +9,7 @@ MAKE_REFLECT_STRUCT(QueryFile::Def, language, outline, all_symbols, - inactive_regions, + skipped_ranges, dependencies); namespace { @@ -49,7 +49,7 @@ struct Handler_CclsFileInfo : BaseMessageHandler { out.result.args = file->def->args; out.result.language = file->def->language; out.result.includes = file->def->includes; - out.result.inactive_regions = file->def->inactive_regions; + out.result.skipped_ranges = file->def->skipped_ranges; pipeline::WriteStdout(kMethodType, out); } }; diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index fcd937976..ed96e6de7 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -45,7 +45,7 @@ struct Handler_TextDocumentDidOpen QueryFile* file = nullptr; FindFileOrFail(db, project, std::nullopt, path, &file); if (file && file->def) { - EmitInactiveLines(working_file, file->def->inactive_regions); + EmitSkippedRanges(working_file, file->def->skipped_ranges); EmitSemanticHighlighting(db, semantic_cache, working_file, file); } diff --git a/src/pipeline.cc b/src/pipeline.cc index cd8a8482c..3d960b9e9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -347,7 +347,7 @@ void Main_OnIndexed(DB* db, if (WorkingFile* working_file = working_files->GetFileByFilename(def_u.first.path)) { working_file->SetIndexContent(def_u.second); - EmitInactiveLines(working_file, def_u.first.inactive_regions); + EmitSkippedRanges(working_file, def_u.first.skipped_ranges); EmitSemanticHighlighting(db, semantic_cache, working_file, &db->files[update->file_id]); } diff --git a/src/query.cc b/src/query.cc index dac2bc96a..3d40f6c4d 100644 --- a/src/query.cc +++ b/src/query.cc @@ -73,7 +73,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { def.path = std::move(indexed.path); def.args = std::move(indexed.args); def.includes = std::move(indexed.includes); - def.inactive_regions = std::move(indexed.skipped_by_preprocessor); + def.skipped_ranges = std::move(indexed.skipped_ranges); def.dependencies.reserve(indexed.dependencies.size()); for (auto& dep : indexed.dependencies) def.dependencies.push_back(dep.first()); @@ -172,7 +172,7 @@ bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, IndexFile* current) { IndexUpdate r; - static IndexFile empty(current->path, ""); + static IndexFile empty(0u, current->path, ""); if (!previous) previous = ∅ diff --git a/src/query.h b/src/query.h index 22b3982d3..b164b9caf 100644 --- a/src/query.h +++ b/src/query.h @@ -18,7 +18,7 @@ struct QueryFile { // Every symbol found in the file (ie, for goto definition) std::vector all_symbols; // Parts of the file which are disabled. - std::vector inactive_regions; + std::vector skipped_ranges; // Used by |$ccls/freshenIndex|. std::vector dependencies; }; diff --git a/src/serializer.cc b/src/serializer.cc index e29c1674a..458d268a1 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -335,7 +335,7 @@ void Reflect(TVisitor& visitor, IndexFile& value) { REFLECT_MEMBER(dependencies); } REFLECT_MEMBER(includes); - REFLECT_MEMBER(skipped_by_preprocessor); + REFLECT_MEMBER(skipped_ranges); REFLECT_MEMBER(usr2func); REFLECT_MEMBER(usr2type); REFLECT_MEMBER(usr2var); @@ -426,7 +426,7 @@ std::unique_ptr Deserialize( if (major != IndexFile::kMajorVersion || minor != IndexFile::kMinorVersion) throw std::invalid_argument("Invalid version"); - file = std::make_unique(path, file_content); + file = std::make_unique(0u, path, file_content); Reflect(reader, *file); } catch (std::invalid_argument& e) { LOG_S(INFO) << "failed to deserialize '" << path @@ -450,7 +450,7 @@ std::unique_ptr Deserialize( if (reader.HasParseError()) return nullptr; - file = std::make_unique(path, file_content); + file = std::make_unique(0u, path, file_content); JsonReader json_reader{&reader}; try { Reflect(json_reader, *file); diff --git a/src/test.cc b/src/test.cc index 4ba660716..c5c940a37 100644 --- a/src/test.cc +++ b/src/test.cc @@ -307,8 +307,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // Get output from index operation. IndexFile* db = FindDbForPathEnding(expected_path, dbs); - assert(db); - if (!db->diagnostics_.empty()) { + if (db && !db->diagnostics_.empty()) { printf("For %s\n", path.c_str()); for (const lsDiagnostic& diagnostic : db->diagnostics_) { printf(" "); From 2196e172221919b4d906b590775bcf5069334741 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Jul 2018 15:25:25 -0700 Subject: [PATCH 128/378] Clean up clang_tu --- src/clang_tu.cc | 198 ------------------------------------------------ src/clang_tu.h | 98 ------------------------ src/indexer.cc | 82 ++++++++++++++------ src/indexer.h | 9 +-- 4 files changed, 60 insertions(+), 327 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 95e44c908..e98d0453d 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -65,204 +65,6 @@ void EmitDiagnostics(std::string path, } } // namespace -Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { - CXSourceLocation start = clang_getRangeStart(range); - CXSourceLocation end = clang_getRangeEnd(range); - - unsigned int start_line, start_column; - clang_getSpellingLocation(start, cx_file, &start_line, &start_column, - nullptr); - unsigned int end_line, end_column; - clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr); - - return Range{{int16_t(start_line - 1), (int16_t)(start_column - 1)}, - {int16_t(end_line - 1), int16_t(end_column - 1)}}; -} - -ClangCursor ClangType::get_declaration() const { - return clang_getTypeDeclaration(cx_type); -} - -std::string ClangType::get_usr() const { - return ClangCursor{clang_getTypeDeclaration(cx_type)}.get_usr(); -} - -Usr ClangType::get_usr_hash() const { - if (is_builtin()) - return static_cast(cx_type.kind); - return ClangCursor{clang_getTypeDeclaration(cx_type)}.get_usr_hash(); -} - -ClangType ClangType::get_canonical() const { - return clang_getCanonicalType(cx_type); -} - -ClangType ClangType::strip_qualifiers() const { - CXType cx = cx_type; - while (1) { - switch (cx.kind) { - default: - break; - case CXType_ConstantArray: - case CXType_DependentSizedArray: - case CXType_IncompleteArray: - case CXType_VariableArray: - cx = clang_getElementType(cx); - continue; - case CXType_BlockPointer: - case CXType_LValueReference: - case CXType_MemberPointer: - case CXType_ObjCObjectPointer: - case CXType_Pointer: - case CXType_RValueReference: - cx = clang_getPointeeType(cx); - continue; - } - break; - } - - return cx; -} - -std::string ClangType::get_spell_name() const { - return ToString(clang_getTypeSpelling(cx_type)); -} - -ClangType ClangType::get_return_type() const { - return clang_getResultType(cx_type); -} - -std::vector ClangType::get_arguments() const { - int size = clang_getNumArgTypes(cx_type); - if (size < 0) - return {}; - std::vector types(size); - for (int i = 0; i < size; ++i) - types.emplace_back(clang_getArgType(cx_type, i)); - return types; -} - -std::vector ClangType::get_template_arguments() const { - int size = clang_Type_getNumTemplateArguments(cx_type); - assert(size >= 0); - if (size < 0) - return std::vector(); - - std::vector types(size); - for (int i = 0; i < size; ++i) - types.emplace_back(clang_Type_getTemplateArgumentAsType(cx_type, i)); - return types; -} - -ClangType ClangCursor::get_type() const { - return {clang_getCursorType(cx_cursor)}; -} - -std::string ClangCursor::get_spell_name() const { - return ::ToString(clang_getCursorSpelling(cx_cursor)); -} - -Range ClangCursor::get_spell(CXFile* cx_file) const { - // TODO for Objective-C methods and Objective-C message expressions, there are - // multiple pieces for each selector identifier. - CXSourceRange range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0); - return ResolveCXSourceRange(range, cx_file); -} - -Range ClangCursor::get_extent() const { - CXSourceRange range = clang_getCursorExtent(cx_cursor); - return ResolveCXSourceRange(range, nullptr); -} - -std::string ClangCursor::get_display_name() const { - return ::ToString(clang_getCursorDisplayName(cx_cursor)); -} - -std::string ClangCursor::get_usr() const { - return ::ToString(clang_getCursorUSR(cx_cursor)); -} - -Usr ClangCursor::get_usr_hash() const { - CXString usr = clang_getCursorUSR(cx_cursor); - Usr ret = HashUsr(clang_getCString(usr)); - clang_disposeString(usr); - return ret; -} - -std::optional ClangCursor::get_opt_usr_hash() const { - CXString usr = clang_getCursorUSR(cx_cursor); - const char* str = clang_getCString(usr); - if (!str || str[0] == '\0') { - clang_disposeString(usr); - return {}; - } - Usr ret = HashUsr(str); - clang_disposeString(usr); - return ret; -} - -bool ClangCursor::is_definition() const { - return clang_isCursorDefinition(cx_cursor); -} - -ClangCursor ClangCursor::template_specialization_to_template_definition() - const { - CXCursor definition = clang_getSpecializedCursorTemplate(cx_cursor); - if (definition.kind == CXCursor_FirstInvalid) - return cx_cursor; - return definition; -} - -ClangCursor ClangCursor::get_referenced() const { - return {clang_getCursorReferenced(cx_cursor)}; -} - -ClangCursor ClangCursor::get_canonical() const { - return {clang_getCanonicalCursor(cx_cursor)}; -} - -ClangCursor ClangCursor::get_definition() const { - return {clang_getCursorDefinition(cx_cursor)}; -} - -ClangCursor ClangCursor::get_lexical_parent() const { - return {clang_getCursorLexicalParent(cx_cursor)}; -} - -ClangCursor ClangCursor::get_semantic_parent() const { - return {clang_getCursorSemanticParent(cx_cursor)}; -} - -std::vector ClangCursor::get_arguments() const { - int size = clang_Cursor_getNumArguments(cx_cursor); - if (size < 0) - return std::vector(); - - std::vector cursors(size); - for (int i = 0; i < size; ++i) - cursors.emplace_back(clang_Cursor_getArgument(cx_cursor, i)); - return cursors; -} - -bool ClangCursor::is_valid_kind() const { - CXCursor referenced = clang_getCursorReferenced(cx_cursor); - if (clang_Cursor_isNull(referenced)) - return false; - - CXCursorKind kind = get_kind(); - return kind > CXCursor_UnexposedDecl && - (kind < CXCursor_FirstInvalid || kind > CXCursor_LastInvalid); -} - -std::string ClangCursor::get_type_description() const { - auto type = clang_getCursorType(cx_cursor); - return ::ToString(clang_getTypeSpelling(type)); -} - -std::string ClangCursor::ToString() const { - return ::ToString(get_kind()) + " " + get_spell_name(); -} - ClangIndex::ClangIndex() : ClangIndex(1, 0) {} ClangIndex::ClangIndex(int exclude_declarations_from_pch, diff --git a/src/clang_tu.h b/src/clang_tu.h index 03fbf9937..b363c68be 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -7,104 +7,6 @@ #include #include -using Usr = uint64_t; - -Range ResolveCXSourceRange(const CXSourceRange& range, - CXFile* cx_file = nullptr); - -class ClangCursor; - -class ClangType { - public: - ClangType() = default; - ClangType(const CXType& cx) : cx_type(cx) {} - - // Returns true if this is a fundamental type like int. - bool is_builtin() const { - // NOTE: This will return false for pointed types. Should we call - // strip_qualifiers for the user? - return cx_type.kind >= CXType_FirstBuiltin && - cx_type.kind <= CXType_LastBuiltin; - } - - ClangCursor get_declaration() const; - std::string get_usr() const; - Usr get_usr_hash() const; - std::string get_spell_name() const; - ClangType get_canonical() const; - - // Try to resolve this type and remove qualifies, ie, Foo* will become Foo - ClangType strip_qualifiers() const; - - ClangType get_return_type() const; - std::vector get_arguments() const; - std::vector get_template_arguments() const; - - CXType cx_type; -}; - -class ClangCursor { - public: - ClangCursor() = default; - ClangCursor(CXCursor cx) : cx_cursor(cx) {} - bool operator==(const ClangCursor& o) const { - return clang_equalCursors(cx_cursor, o.cx_cursor); - } - bool operator!=(const ClangCursor& o) const { - return !(*this == o); - } - - CXCursorKind get_kind() const { - return cx_cursor.kind; - } - ClangType get_type() const; - std::string get_spell_name() const; - Range get_spell(CXFile* cx_file = nullptr) const; - Range get_extent() const; - std::string get_display_name() const; - std::string get_usr() const; - Usr get_usr_hash() const; - std::optional get_opt_usr_hash() const; - - bool is_definition() const; - - // If the given cursor points to a template specialization, this - // will return the cursor pointing to the template definition. - // If the given cursor is not a template specialization, this will - // just return the same cursor. - // - // This means it is always safe to call this method. - ClangCursor template_specialization_to_template_definition() const; - - ClangCursor get_referenced() const; - ClangCursor get_canonical() const; - ClangCursor get_definition() const; - ClangCursor get_lexical_parent() const; - ClangCursor get_semantic_parent() const; - std::vector get_arguments() const; - bool is_valid_kind() const; - - std::string get_type_description() const; - - std::string ToString() const; - - enum class VisitResult { Break, Continue, Recurse }; - - template - using Visitor = VisitResult (*)(ClangCursor cursor, - ClangCursor parent, - TClientData* client_data); - - template - void VisitChildren(Visitor visitor, - TClientData* client_data) const { - clang_visitChildren(cx_cursor, reinterpret_cast(visitor), - client_data); - } - - CXCursor cx_cursor; -}; - // Simple RAII wrapper about CXIndex. // Note: building a ClangIndex instance acquires a global lock, since libclang // API does not appear to be thread-safe here. diff --git a/src/indexer.cc b/src/indexer.cc index 715d1f836..2c9a29ac3 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -270,6 +270,61 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexParam& param; llvm::DenseMap Decl2usr; + std::string GetComment(const Decl* D) { + SourceManager &SM = Ctx->getSourceManager(); + const RawComment *RC = Ctx->getRawCommentForAnyRedecl(D); + if (!RC) return ""; + StringRef Raw = RC->getRawText(Ctx->getSourceManager()); + SourceRange R = RC->getSourceRange(); + std::pair BInfo = SM.getDecomposedLoc(R.getBegin()); + unsigned start_column = SM.getLineNumber(BInfo.first, BInfo.second); + std::string ret; + int pad = -1; + for (const char *p = Raw.data(), *E = Raw.end(); p < E;) { + // The first line starts with a comment marker, but the rest needs + // un-indenting. + unsigned skip = start_column - 1; + for (; skip > 0 && p < E && (*p == ' ' || *p == '\t'); p++) + skip--; + const char *q = p; + while (q < E && *q != '\n') + q++; + if (q < E) + q++; + // A minimalist approach to skip Doxygen comment markers. + // See https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html + if (pad < 0) { + // First line, detect the length of comment marker and put into |pad| + const char *begin = p; + while (p < E && (*p == '/' || *p == '*')) + p++; + if (p < E && (*p == '<' || *p == '!')) + p++; + if (p < E && *p == ' ') + p++; + pad = int(p - begin); + } else { + // Other lines, skip |pad| bytes + int prefix = pad; + while (prefix > 0 && p < E && + (*p == ' ' || *p == '/' || *p == '*' || *p == '<' || *p == '!')) + prefix--, p++; + } + ret.insert(ret.end(), p, q); + p = q; + } + while (ret.size() && isspace(ret.back())) + ret.pop_back(); + if (EndsWith(ret, "*/")) { + ret.resize(ret.size() - 2); + } else if (EndsWith(ret, "\n/")) { + ret.resize(ret.size() - 2); + } + while (ret.size() && isspace(ret.back())) + ret.pop_back(); + return ret; + } + Usr GetUsr(const Decl* D) { D = D->getCanonicalDecl(); auto R = Decl2usr.try_emplace(D); @@ -429,7 +484,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!func->def.detailed_name[0]) { SetName(D, short_name, qualified, func->def); if (g_config->index.comments) - func->def.comments = Intern(""); + func->def.comments = Intern(GetComment(D)); } if (is_def || (is_decl && !func->def.spell)) { if (func->def.spell) @@ -450,7 +505,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!type->def.detailed_name[0]) { SetName(D, short_name, qualified, type->def); if (g_config->index.comments) - type->def.comments = Intern(""); + type->def.comments = Intern(GetComment(D)); } if (is_def || (is_decl && !type->def.spell)) { if (type->def.spell) @@ -465,7 +520,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!var->def.detailed_name[0]) { SetName(D, short_name, qualified, var->def); if (g_config->index.comments) - var->def.comments = Intern(""); + var->def.comments = Intern(GetComment(D)); } if (is_def || (is_decl && !var->def.spell)) { if (var->def.spell) @@ -633,27 +688,6 @@ void Uniquify(std::vector& uses) { uses.resize(n); } -void AddUse(IndexFile* db, - std::vector& uses, - Range range, - ClangCursor parent, - Role role = Role::Reference) { - // switch (GetSymbolKind(parent.get_kind())) { - // case SymbolKind::Func: - // uses.push_back(Use{ - // {range, db->ToFunc(parent.cx_cursor).usr, SymbolKind::Func, role}}); - // break; - // case SymbolKind::Type: - // uses.push_back(Use{ - // {range, db->ToType(parent.cx_cursor).usr, SymbolKind::Type, role}}); - // break; - // default: - // uses.push_back(Use{{range, 0, SymbolKind::File, role}}); - // break; - // } -} - - std::vector> ClangIndexer::Index( VFS* vfs, std::string file, diff --git a/src/indexer.h b/src/indexer.h index ec180cd1a..441dc44ce 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -1,6 +1,5 @@ #pragma once -#include "clang_tu.h" #include "clang_utils.h" #include "file_consumer.h" #include "language.h" @@ -21,6 +20,8 @@ #include #include +using Usr = uint64_t; + struct SymbolIdx { Usr usr; SymbolKind kind; @@ -279,9 +280,6 @@ struct IndexFile { IndexFunc& ToFunc(Usr usr); IndexType& ToType(Usr usr); IndexVar& ToVar(Usr usr); - IndexFunc& ToFunc(const ClangCursor& c) { return ToFunc(c.get_usr_hash()); } - IndexType& ToType(const ClangCursor& c) { return ToType(c.get_usr_hash()); } - IndexVar& ToVar(const ClangCursor& c) { return ToVar(c.get_usr_hash()); } std::string ToString(); }; @@ -304,7 +302,4 @@ struct ClangIndexer { std::string file, const std::vector& args, const std::vector& file_contents); - - // Note: constructing this acquires a global lock - ClangIndex index; }; From df02c29a7db8287782c9044dc9b8beaa3cb4bd93 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 7 Jul 2018 16:56:47 -0700 Subject: [PATCH 129/378] clangIndex --- index_tests/_empty_test.cc | 2 +- index_tests/class_forward_declaration.cc | 8 +- index_tests/constructors/constructor.cc | 20 +- index_tests/constructors/destructor.cc | 24 +- .../constructors/implicit_constructor.cc | 24 +- index_tests/constructors/invalid_reference.cc | 16 +- index_tests/constructors/make_functions.cc | 193 +----- .../declaration_vs_definition/class.cc | 8 +- .../declaration_vs_definition/class_member.cc | 28 +- .../class_member_static.cc | 47 +- index_tests/declaration_vs_definition/func.cc | 4 +- .../func_associated_function_params.cc | 18 +- .../declaration_vs_definition/method.cc | 24 +- index_tests/enums/enum_class_decl.cc | 46 +- index_tests/enums/enum_decl.cc | 38 +- index_tests/enums/enum_inherit.cc | 78 ++- index_tests/enums/enum_usage.cc | 36 +- index_tests/foobar.cc | 26 +- index_tests/function_declaration.cc | 2 +- .../function_declaration_definition.cc | 4 +- index_tests/function_definition.cc | 2 +- index_tests/inheritance/class_inherit.cc | 14 +- .../class_inherit_templated_parent.cc | 88 +-- .../inheritance/class_multiple_inherit.cc | 30 +- index_tests/inheritance/function_override.cc | 24 +- .../inheritance/interface_pure_virtual.cc | 12 +- .../inheritance/multiple_base_functions.cc | 46 +- index_tests/lambdas/lambda.cc | 41 +- index_tests/macros/complex.cc | 28 +- index_tests/macros/foo.cc | 52 +- index_tests/method_declaration.cc | 10 +- index_tests/method_definition.cc | 14 +- index_tests/method_inline_declaration.cc | 10 +- index_tests/multi_file/funky_enum.cc | 60 +- index_tests/multi_file/impl.cc | 98 +-- index_tests/multi_file/simple_impl.cc | 21 +- index_tests/multi_file/static.cc | 41 +- index_tests/namespaces/anonymous_function.cc | 4 +- .../namespaces/function_declaration.cc | 31 +- index_tests/namespaces/function_definition.cc | 31 +- index_tests/namespaces/method_declaration.cc | 41 +- index_tests/namespaces/method_definition.cc | 47 +- .../namespaces/method_inline_declaration.cc | 41 +- index_tests/namespaces/namespace_alias.cc | 108 ++-- index_tests/namespaces/namespace_reference.cc | 68 +-- index_tests/operators/operator.cc | 20 +- .../outline/static_function_in_type.cc | 117 ++-- index_tests/preprocessor/include_guard.cc | 6 +- index_tests/preprocessor/skipped.cc | 2 +- .../func_specialized_template_param.cc | 18 +- .../implicit_variable_instantiation.cc | 135 ++--- .../templates/member_ref_in_template.cc | 45 +- ...ass_template_func_usage_folded_into_one.cc | 79 ++- ...ace_template_type_usage_folded_into_one.cc | 63 +- index_tests/templates/specialization.cc | 242 +++----- .../templates/specialized_func_definition.cc | 49 +- ...mplate_class_func_usage_folded_into_one.cc | 24 +- ...ass_template_func_usage_folded_into_one.cc | 24 +- ...mplate_class_type_usage_folded_into_one.cc | 26 +- ...emplate_class_var_usage_folded_into_one.cc | 44 +- .../template_func_usage_folded_into_one.cc | 12 +- .../template_type_usage_folded_into_one.cc | 8 +- .../template_var_usage_folded_into_one.cc | 27 +- index_tests/types/anonymous_struct.cc | 81 ++- index_tests/types/typedefs.cc | 26 +- index_tests/unions/union_decl.cc | 40 +- index_tests/unions/union_usage.cc | 46 +- .../usage/func_called_from_constructor.cc | 22 +- .../usage/func_called_from_macro_argument.cc | 14 +- .../usage/func_called_from_template.cc | 10 +- .../usage/func_called_implicit_ctor.cc | 20 +- index_tests/usage/func_usage_addr_func.cc | 15 +- index_tests/usage/func_usage_addr_method.cc | 22 +- index_tests/usage/func_usage_call_func.cc | 6 +- index_tests/usage/func_usage_call_method.cc | 18 +- .../usage/func_usage_class_inline_var_def.cc | 30 +- .../usage/func_usage_forward_decl_func.cc | 6 +- .../usage/func_usage_forward_decl_method.cc | 18 +- index_tests/usage/func_usage_template_func.cc | 25 +- .../usage/type_usage_as_template_parameter.cc | 20 +- ...ype_usage_as_template_parameter_complex.cc | 32 +- ...type_usage_as_template_parameter_simple.cc | 14 +- .../usage/type_usage_declare_extern.cc | 10 +- index_tests/usage/type_usage_declare_field.cc | 38 +- index_tests/usage/type_usage_declare_local.cc | 14 +- index_tests/usage/type_usage_declare_param.cc | 16 +- .../type_usage_declare_param_prototype.cc | 12 +- .../usage/type_usage_declare_param_unnamed.cc | 6 +- .../usage/type_usage_declare_qualifiers.cc | 12 +- .../usage/type_usage_declare_static.cc | 10 +- .../usage/type_usage_on_return_type.cc | 34 +- .../usage/type_usage_typedef_and_using.cc | 51 +- .../type_usage_typedef_and_using_template.cc | 26 +- index_tests/usage/type_usage_various.cc | 20 +- index_tests/usage/usage_inside_of_call.cc | 63 +- .../usage/usage_inside_of_call_simple.cc | 8 +- index_tests/usage/var_usage_call_function.cc | 16 +- index_tests/usage/var_usage_class_member.cc | 42 +- .../usage/var_usage_class_member_static.cc | 38 +- index_tests/usage/var_usage_cstyle_cast.cc | 49 +- index_tests/usage/var_usage_extern.cc | 12 +- index_tests/usage/var_usage_func_parameter.cc | 10 +- index_tests/usage/var_usage_local.cc | 10 +- index_tests/usage/var_usage_shadowed_local.cc | 14 +- .../usage/var_usage_shadowed_parameter.cc | 16 +- index_tests/usage/var_usage_static.cc | 12 +- index_tests/vars/class_member.cc | 24 +- index_tests/vars/class_static_member.cc | 43 +- .../vars/class_static_member_decl_only.cc | 34 +- index_tests/vars/deduce_auto_type.cc | 22 +- index_tests/vars/function_local.cc | 8 +- index_tests/vars/function_param.cc | 12 +- index_tests/vars/function_param_unnamed.cc | 2 +- index_tests/vars/function_shadow_local.cc | 14 +- index_tests/vars/function_shadow_param.cc | 12 +- index_tests/vars/global_variable.cc | 12 +- index_tests/vars/global_variable_decl_only.cc | 10 +- .../vars/type_instance_on_using_type.cc | 15 +- src/file_consumer.cc | 21 +- src/file_consumer.h | 4 +- src/indexer.cc | 568 ++++++++++++------ src/indexer.h | 5 +- src/query.cc | 3 +- src/serializer.cc | 6 +- src/utils.cc | 4 + src/utils.h | 5 + 126 files changed, 2177 insertions(+), 2200 deletions(-) diff --git a/index_tests/_empty_test.cc b/index_tests/_empty_test.cc index 87accc882..d1ae7a6c4 100644 --- a/index_tests/_empty_test.cc +++ b/index_tests/_empty_test.cc @@ -2,7 +2,7 @@ OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [], "usr2var": [] diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index 297282989..a90ce1259 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -7,17 +7,17 @@ class Foo; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "3:1-3:13|0|1|0", + "extent": "1:1-1:10|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index 33c2ff6c0..46f44dbec 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -12,7 +12,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3385168158331140247, "detailed_name": "Foo::Foo()", @@ -21,13 +21,13 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|2", + "spell": "3:3-3:6|15041163540773201510|2|514", "extent": "3:3-3:11|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|4259594751088586730|3|288", "8:17-8:20|4259594751088586730|3|32"], + "uses": ["7:7-7:8|15041163540773201510|2|8228", "8:17-8:20|15041163540773201510|2|8228"], "callees": [] }, { "usr": 4259594751088586730, @@ -42,17 +42,17 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [10983126130596230582, 17165811951126099095], + "vars": [], "uses": [], - "callees": ["7:7-7:8|3385168158331140247|3|288", "7:7-7:8|3385168158331140247|3|288", "8:17-8:20|3385168158331140247|3|32", "8:17-8:20|3385168158331140247|3|32"] + "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, - "declarations": ["3:3-3:6|0|1|4"], + "declarations": [], "spell": "1:7-1:10|0|1|2", "extent": "1:1-4:2|0|1|0", "alias_of": 0, @@ -62,7 +62,7 @@ void foo() { "funcs": [3385168158331140247], "vars": [], "instances": [10983126130596230582, 17165811951126099095], - "uses": ["3:3-3:6|15041163540773201510|2|4", "7:3-7:6|0|1|4", "8:3-8:6|0|1|4", "8:17-8:20|0|1|4"] + "uses": ["3:3-3:6|0|1|4", "7:3-7:6|0|1|4", "8:3-8:6|0|1|4", "8:17-8:20|0|1|4"] }], "usr2var": [{ "usr": 10983126130596230582, diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index ff79a520c..c722bab0e 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -17,7 +17,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3385168158331140247, "detailed_name": "Foo::Foo()", @@ -26,13 +26,13 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|2", + "spell": "3:3-3:6|15041163540773201510|2|514", "extent": "3:3-3:11|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|4259594751088586730|3|288"], + "uses": ["8:7-8:8|15041163540773201510|2|8228"], "callees": [] }, { "usr": 4259594751088586730, @@ -47,9 +47,9 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [1893354193220338759], + "vars": [], "uses": [], - "callees": ["8:7-8:8|3385168158331140247|3|288", "8:7-8:8|3385168158331140247|3|288"] + "callees": [] }, { "usr": 7440261702884428359, "detailed_name": "Foo::~Foo() noexcept", @@ -58,9 +58,9 @@ void foo() { "kind": 6, "storage": 0, "declarations": [], - "spell": "4:3-4:7|15041163540773201510|2|2", + "spell": "4:3-4:4|15041163540773201510|2|514", "extent": "4:3-4:12|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -69,11 +69,11 @@ void foo() { }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, - "declarations": ["3:3-3:6|0|1|4", "4:4-4:7|0|1|4"], + "declarations": [], "spell": "1:7-1:10|0|1|2", "extent": "1:1-5:2|0|1|0", "alias_of": 0, @@ -83,7 +83,7 @@ void foo() { "funcs": [3385168158331140247, 7440261702884428359], "vars": [], "instances": [1893354193220338759], - "uses": ["3:3-3:6|15041163540773201510|2|4", "8:3-8:6|0|1|4"] + "uses": ["3:3-3:6|0|1|4", "4:4-4:7|0|1|4", "8:3-8:6|0|1|4"] }], "usr2var": [{ "usr": 1893354193220338759, diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index 6600ac372..abcbd9a5d 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -11,7 +11,7 @@ void Make() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3957104924306079513, "detailed_name": "void Make()", @@ -25,9 +25,9 @@ void Make() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [449111627548814328, 17097499197730163115], + "vars": [], "uses": [], - "callees": ["6:8-6:12|10530961286677896857|3|288", "6:8-6:12|10530961286677896857|3|288", "7:15-7:19|10530961286677896857|3|32", "7:15-7:19|10530961286677896857|3|32"] + "callees": [] }, { "usr": 10530961286677896857, "detailed_name": "Type::Type()", @@ -36,22 +36,22 @@ void Make() { "kind": 9, "storage": 0, "declarations": [], - "spell": "2:3-2:7|13487927231218873822|2|2", + "spell": "2:3-2:7|13487927231218873822|2|514", "extent": "2:3-2:12|13487927231218873822|2|0", - "declaring_type": 13487927231218873822, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|3957104924306079513|3|288", "7:15-7:19|3957104924306079513|3|32"], + "uses": ["6:8-6:12|13487927231218873822|2|8228", "7:15-7:19|13487927231218873822|2|8228"], "callees": [] }], "usr2type": [{ "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, + "detailed_name": "struct Type {}", + "qual_name_offset": 7, "short_name": "Type", "kind": 23, - "declarations": ["2:3-2:7|0|1|4"], + "declarations": [], "spell": "1:8-1:12|0|1|2", "extent": "1:1-3:2|0|1|0", "alias_of": 0, @@ -61,7 +61,7 @@ void Make() { "funcs": [10530961286677896857], "vars": [], "instances": [449111627548814328, 17097499197730163115], - "uses": ["2:3-2:7|13487927231218873822|2|4", "6:3-6:7|0|1|4", "7:15-7:19|0|1|4"] + "uses": ["2:3-2:7|0|1|4", "6:3-6:7|0|1|4", "7:15-7:19|0|1|4"] }], "usr2var": [{ "usr": 449111627548814328, @@ -77,10 +77,10 @@ void Make() { "storage": 0 }, { "usr": 17097499197730163115, - "detailed_name": "Type foo1", + "detailed_name": "auto foo1", "qual_name_offset": 5, "short_name": "foo1", - "hover": "Type foo1 = Type()", + "hover": "auto foo1 = Type()", "declarations": [], "spell": "7:8-7:12|3957104924306079513|3|2", "extent": "7:3-7:21|3957104924306079513|3|0", diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 29118e1e5..c68bc86ef 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -11,18 +11,18 @@ Foo::Foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 17319723337446061757, - "detailed_name": "Foo::Foo()", + "detailed_name": "Foo::Foo::Foo()", "qual_name_offset": 0, "short_name": "Foo", "kind": 9, "storage": 0, "declarations": [], - "spell": "4:6-4:9|15041163540773201510|2|2", + "spell": "4:6-4:9|0|1|514", "extent": "4:1-4:11|0|1|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -31,11 +31,11 @@ Foo::Foo() {} }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["4:6-4:9|0|1|4"], + "declarations": [], "spell": "1:8-1:11|0|1|2", "extent": "1:1-1:14|0|1|0", "alias_of": 0, @@ -45,7 +45,7 @@ Foo::Foo() {} "funcs": [17319723337446061757], "vars": [], "instances": [], - "uses": ["4:6-4:9|0|1|4", "4:1-4:4|0|1|4"] + "uses": ["4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index 7407640a7..5a74373a9 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -27,7 +27,7 @@ void caller22() { OUTPUT: make_functions.h { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3765833212244435302, "detailed_name": "Foobar::Foobar(int &&, Bar *, bool *)", @@ -36,9 +36,9 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "7:3-7:9|14935975554338052500|2|2", + "spell": "7:3-7:9|14935975554338052500|2|514", "extent": "7:3-7:32|14935975554338052500|2|0", - "declaring_type": 14935975554338052500, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -52,9 +52,9 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "6:3-6:9|14935975554338052500|2|2", + "spell": "6:3-6:9|14935975554338052500|2|514", "extent": "6:3-6:17|14935975554338052500|2|0", - "declaring_type": 14935975554338052500, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -68,9 +68,9 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "5:3-5:9|14935975554338052500|2|2", + "spell": "5:3-5:9|14935975554338052500|2|514", "extent": "5:3-5:14|14935975554338052500|2|0", - "declaring_type": 14935975554338052500, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -84,9 +84,9 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "8:3-8:9|14935975554338052500|2|2", + "spell": "8:3-8:9|14935975554338052500|2|514", "extent": "8:3-8:30|14935975554338052500|2|0", - "declaring_type": 14935975554338052500, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -95,8 +95,8 @@ OUTPUT: make_functions.h }], "usr2type": [{ "usr": 12993848456528750350, - "detailed_name": "Bar", - "qual_name_offset": 0, + "detailed_name": "struct Bar {}", + "qual_name_offset": 7, "short_name": "Bar", "kind": 23, "declarations": [], @@ -112,11 +112,11 @@ OUTPUT: make_functions.h "uses": ["7:17-7:20|0|1|4", "8:15-8:18|0|1|4"] }, { "usr": 14935975554338052500, - "detailed_name": "Foobar", - "qual_name_offset": 0, + "detailed_name": "class Foobar {}", + "qual_name_offset": 6, "short_name": "Foobar", "kind": 5, - "declarations": ["5:3-5:9|0|1|4", "6:3-6:9|0|1|4", "7:3-7:9|0|1|4", "8:3-8:9|0|1|4"], + "declarations": [], "spell": "3:7-3:13|0|1|2", "extent": "3:1-9:2|0|1|0", "alias_of": 0, @@ -126,17 +126,14 @@ OUTPUT: make_functions.h "funcs": [13131778807733950299, 13028995015627606181, 3765833212244435302, 17321436359755983845], "vars": [], "instances": [], - "uses": ["5:3-5:9|14935975554338052500|2|4", "6:3-6:9|14935975554338052500|2|4", "7:3-7:9|14935975554338052500|2|4", "8:3-8:9|14935975554338052500|2|4"] + "uses": ["5:3-5:9|0|1|4", "6:3-6:9|0|1|4", "7:3-7:9|0|1|4", "8:3-8:9|0|1|4"] }], "usr2var": [] } OUTPUT: make_functions.cc { - "includes": [{ - "line": 0, - "resolved_path": "&make_functions.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [{ "usr": 2532818908869373467, "detailed_name": "T *maKE_NoRefs(Args ...args)", @@ -150,8 +147,8 @@ OUTPUT: make_functions.cc "declaring_type": 0, "bases": [], "derived": [], - "vars": [3908732770590594660], - "uses": ["17:3-17:14|2816883305867289955|3|32"], + "vars": [], + "uses": ["17:3-17:14|0|1|8228"], "callees": [] }, { "usr": 2816883305867289955, @@ -168,48 +165,6 @@ OUTPUT: make_functions.cc "derived": [], "vars": [], "uses": [], - "callees": ["14:3-14:13|15793662558620604611|3|32", "15:3-15:13|15793662558620604611|3|32", "16:3-16:13|15793662558620604611|3|32", "17:3-17:14|2532818908869373467|3|32"] - }, { - "usr": 3765833212244435302, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": ["16:3-16:13|0|1|288"], - "callees": [] - }, { - "usr": 13028995015627606181, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": ["15:3-15:13|0|1|288"], - "callees": [] - }, { - "usr": 13131778807733950299, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [], - "uses": ["14:3-14:13|0|1|288"], "callees": [] }, { "usr": 15793662558620604611, @@ -224,98 +179,16 @@ OUTPUT: make_functions.cc "declaring_type": 0, "bases": [], "derived": [], - "vars": [8463700030555379526], - "uses": ["14:3-14:13|2816883305867289955|3|32", "15:3-15:13|2816883305867289955|3|32", "16:3-16:13|2816883305867289955|3|32"], - "callees": [] - }, { - "usr": 17321436359755983845, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], "vars": [], - "uses": ["17:3-17:14|0|1|288"], + "uses": ["14:3-14:13|0|1|8228", "15:3-15:13|0|1|8228", "16:3-16:13|0|1|8228"], "callees": [] }], "usr2type": [{ - "usr": 3337128087216004141, - "detailed_name": "Args", - "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, - "declarations": [], - "spell": "8:35-8:39|2532818908869373467|3|2", - "extent": "8:23-8:39|2532818908869373467|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["9:16-9:20|0|1|4"] - }, { - "usr": 9281343527065946499, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "3:20-3:21|15793662558620604611|3|2", - "extent": "3:11-3:21|15793662558620604611|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["4:1-4:2|0|1|4"] - }, { - "usr": 10771590811355716928, - "detailed_name": "Args", - "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, - "declarations": [], - "spell": "3:35-3:39|15793662558620604611|3|2", - "extent": "3:23-3:39|15793662558620604611|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["4:15-4:19|0|1|4"] - }, { - "usr": 11897454629873246477, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "8:20-8:21|2532818908869373467|3|2", - "extent": "8:11-8:21|2532818908869373467|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["9:1-9:2|0|1|4"] - }, { "usr": 12993848456528750350, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "struct Bar {}", + "qual_name_offset": 7, + "short_name": "Bar", + "kind": 23, "declarations": [], "alias_of": 0, "bases": [], @@ -327,10 +200,10 @@ OUTPUT: make_functions.cc "uses": ["16:29-16:32|0|1|4", "17:30-17:33|0|1|4"] }, { "usr": 14935975554338052500, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "class Foobar {}", + "qual_name_offset": 6, + "short_name": "Foobar", + "kind": 5, "declarations": [], "alias_of": 0, "bases": [], @@ -343,11 +216,11 @@ OUTPUT: make_functions.cc }], "usr2var": [{ "usr": 3908732770590594660, - "detailed_name": "Args... args", + "detailed_name": "Args ...args", "qual_name_offset": 8, "short_name": "args", "declarations": [], - "spell": "9:24-9:28|2532818908869373467|3|2", + "spell": "9:24-9:28|2532818908869373467|3|514", "extent": "9:16-9:28|2532818908869373467|3|0", "type": 0, "uses": [], @@ -355,11 +228,11 @@ OUTPUT: make_functions.cc "storage": 0 }, { "usr": 8463700030555379526, - "detailed_name": "Args &&... args", - "qual_name_offset": 11, + "detailed_name": "Args &&...args", + "qual_name_offset": 10, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|15793662558620604611|3|2", + "spell": "4:25-4:29|15793662558620604611|3|514", "extent": "4:15-4:29|15793662558620604611|3|0", "type": 0, "uses": [], diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index 23d24d7dd..e8aa0e94f 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -9,17 +9,17 @@ class Foo; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "3:1-3:13|0|1|0", + "extent": "1:1-1:10|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index b0feb85bf..37649b698 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -6,10 +6,24 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [9736582033442720743], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -25,8 +39,8 @@ class Foo { "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -50,9 +64,9 @@ class Foo { "qual_name_offset": 4, "short_name": "foo", "declarations": [], - "spell": "2:7-2:10|15041163540773201510|2|2", + "spell": "2:7-2:10|15041163540773201510|2|514", "extent": "2:3-2:10|15041163540773201510|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 2de0195de..5c522d445 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -8,10 +8,24 @@ int Foo::foo; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [8942920329766232482, 8942920329766232482], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -23,12 +37,12 @@ int Foo::foo; "types": [], "funcs": [], "vars": [], - "instances": [8942920329766232482], + "instances": [8942920329766232482, 8942920329766232482], "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -39,25 +53,22 @@ int Foo::foo; "derived": [], "types": [], "funcs": [], - "vars": [{ - "L": 8942920329766232482, - "R": -1 - }], + "vars": [], "instances": [], "uses": ["5:5-5:8|0|1|4"] }], "usr2var": [{ "usr": 8942920329766232482, - "detailed_name": "int Foo::foo", - "qual_name_offset": 4, + "detailed_name": "static int Foo::foo", + "qual_name_offset": 11, "short_name": "foo", - "declarations": ["2:14-2:17|15041163540773201510|2|1"], - "spell": "5:10-5:13|15041163540773201510|2|2", - "extent": "5:1-5:13|0|1|0", - "type": 17, + "declarations": ["2:14-2:17|15041163540773201510|2|513"], + "spell": "5:10-5:13|15041163540773201510|2|514", + "extent": "2:3-2:17|15041163540773201510|2|0", + "type": 53, "uses": [], - "kind": 8, - "storage": 0 + "kind": 13, + "storage": 2 }] } */ diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index 4fa731026..eb24139ce 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -8,7 +8,7 @@ void foo(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -18,7 +18,7 @@ void foo(); "storage": 0, "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "3:1-3:14|0|1|0", + "extent": "1:1-1:11|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index 61cf8c6ed..74ddc5938 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -8,26 +8,26 @@ int foo(int a, int b) { return 0; } OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 2747674671862363334, - "detailed_name": "int foo(int a, int b)", + "detailed_name": "int foo(int, int)", "qual_name_offset": 4, "short_name": "foo", "kind": 12, "storage": 0, "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], "spell": "5:5-5:8|0|1|2", - "extent": "5:1-5:36|0|1|0", + "extent": "1:1-1:18|0|1|0", "declaring_type": 0, "bases": [], "derived": [], - "vars": [14555488990109936920, 10963664335057337329], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -48,9 +48,9 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "b", "declarations": [], - "spell": "5:20-5:21|2747674671862363334|3|2", + "spell": "5:20-5:21|2747674671862363334|3|514", "extent": "5:16-5:21|2747674671862363334|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 253, "storage": 0 @@ -60,9 +60,9 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:13-5:14|2747674671862363334|3|2", + "spell": "5:13-5:14|2747674671862363334|3|514", "extent": "5:9-5:14|2747674671862363334|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 253, "storage": 0 diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index f3362df71..940112844 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -10,7 +10,7 @@ void Foo::def() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4012226004228259562, "detailed_name": "void Foo::declonly()", @@ -18,8 +18,8 @@ void Foo::def() {} "short_name": "declonly", "kind": 6, "storage": 0, - "declarations": ["2:8-2:16|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:16|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -32,10 +32,8 @@ void Foo::def() {} "short_name": "purevirtual", "kind": 6, "storage": 0, - "declarations": [], - "spell": "3:16-3:27|15041163540773201510|2|2", - "extent": "3:3-3:33|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declarations": ["3:16-3:27|15041163540773201510|2|577"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -48,10 +46,10 @@ void Foo::def() {} "short_name": "def", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|15041163540773201510|2|1"], - "spell": "7:11-7:14|15041163540773201510|2|2", - "extent": "7:1-7:19|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["4:8-4:11|15041163540773201510|2|513"], + "spell": "7:11-7:14|15041163540773201510|2|514", + "extent": "4:3-4:13|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -60,8 +58,8 @@ void Foo::def() {} }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 10bfbb881..3518fbeeb 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -8,45 +8,43 @@ enum class Foo : uint8_t { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ - "usr": 5, + "skipped_ranges": [], + "usr2func": [{ + "usr": 16985894625255407295, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], - "alias_of": 0, + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] - }, { + "vars": [439339022761937396, 15962370213938840720], + "uses": [], + "callees": [] + }], + "usr2type": [{ "usr": 2010430204259339553, - "detailed_name": "uint8_t", - "qual_name_offset": 0, + "detailed_name": "typedef unsigned char uint8_t", + "qual_name_offset": 22, "short_name": "uint8_t", "kind": 252, - "hover": "typedef unsigned char uint8_t", "declarations": [], "spell": "1:23-1:30|0|1|2", "extent": "1:1-1:30|0|1|0", - "alias_of": 5, + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["1:23-1:30|0|1|4", "2:12-2:15|0|1|4"] + "uses": [] }, { "usr": 16985894625255407295, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "enum class Foo : uint8_t {\n}", + "qual_name_offset": 11, "short_name": "Foo", "kind": 10, "declarations": [], @@ -68,22 +66,22 @@ enum class Foo : uint8_t { "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|2", + "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:4|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20", + "hover": "Foo::B = 20 = 20", "declarations": [], - "spell": "4:3-4:4|16985894625255407295|2|2", + "spell": "4:3-4:4|16985894625255407295|2|514", "extent": "4:3-4:9|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 7972f8509..ae283d350 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -7,12 +7,26 @@ enum Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ + "skipped_ranges": [], + "usr2func": [{ "usr": 16985894625255407295, - "detailed_name": "Foo", + "detailed_name": "", "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [439339022761937396, 15962370213938840720], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 16985894625255407295, + "detailed_name": "enum Foo {\n}", + "qual_name_offset": 5, "short_name": "Foo", "kind": 10, "declarations": [], @@ -29,27 +43,27 @@ enum Foo { }], "usr2var": [{ "usr": 439339022761937396, - "detailed_name": "Foo::A", + "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", - "hover": "Foo::A = 0", + "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|2", + "spell": "2:3-2:4|16985894625255407295|2|514", "extent": "2:3-2:4|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20", + "hover": "B = 20 = 20", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|2", + "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 2e4c774c1..fab7c3d35 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -14,27 +14,40 @@ enum class E : int32_t { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ - "usr": 17, + "skipped_ranges": [], + "usr2func": [{ + "usr": 2986879766914123941, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], - "alias_of": 0, + "declaring_type": 0, "bases": [], "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] + "vars": [16614320383091394267, 16847439761518576294], + "uses": [], + "callees": [] }, { - "usr": 2986879766914123941, - "detailed_name": "E", + "usr": 16985894625255407295, + "detailed_name": "", "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [439339022761937396, 15962370213938840720], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 2986879766914123941, + "detailed_name": "enum class E : int32_t {\n}", + "qual_name_offset": 11, "short_name": "E", "kind": 10, "declarations": [], @@ -50,26 +63,25 @@ enum class E : int32_t { "uses": [] }, { "usr": 14939241684006947339, - "detailed_name": "int32_t", - "qual_name_offset": 0, + "detailed_name": "typedef int int32_t", + "qual_name_offset": 12, "short_name": "int32_t", "kind": 252, - "hover": "typedef int int32_t", "declarations": [], "spell": "6:13-6:20|0|1|2", "extent": "6:1-6:20|0|1|0", - "alias_of": 17, + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["6:13-6:20|0|1|4", "8:12-8:13|0|1|4"] + "uses": [] }, { "usr": 16985894625255407295, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "enum Foo : int {\n}", + "qual_name_offset": 5, "short_name": "Foo", "kind": 10, "declarations": [], @@ -86,27 +98,27 @@ enum class E : int32_t { }], "usr2var": [{ "usr": 439339022761937396, - "detailed_name": "Foo::A", + "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", - "hover": "Foo::A = 0", + "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|2", + "spell": "2:3-2:4|16985894625255407295|2|514", "extent": "2:3-2:4|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20", + "hover": "B = 20 = 20", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|2", + "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 @@ -117,22 +129,22 @@ enum class E : int32_t { "short_name": "E0", "hover": "E::E0 = 0", "declarations": [], - "spell": "9:3-9:5|2986879766914123941|2|2", + "spell": "9:3-9:5|2986879766914123941|2|514", "extent": "9:3-9:5|2986879766914123941|2|0", - "type": 2986879766914123941, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 16847439761518576294, - "detailed_name": "E::E20", + "detailed_name": "E::E20 = 20", "qual_name_offset": 0, "short_name": "E20", - "hover": "E::E20 = 20", + "hover": "E::E20 = 20 = 20", "declarations": [], - "spell": "10:3-10:6|2986879766914123941|2|2", + "spell": "10:3-10:6|2986879766914123941|2|514", "extent": "10:3-10:11|2986879766914123941|2|0", - "type": 2986879766914123941, + "type": 0, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index 745a5a6e0..b3c24b4a8 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -9,12 +9,26 @@ Foo x = Foo::A; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ + "skipped_ranges": [], + "usr2func": [{ "usr": 16985894625255407295, - "detailed_name": "Foo", + "detailed_name": "", "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [439339022761937396, 15962370213938840720], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 16985894625255407295, + "detailed_name": "enum class Foo : int {\n}", + "qual_name_offset": 11, "short_name": "Foo", "kind": 10, "declarations": [], @@ -36,10 +50,10 @@ Foo x = Foo::A; "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|2", + "spell": "2:3-2:4|16985894625255407295|2|514", "extent": "2:3-2:4|16985894625255407295|2|0", - "type": 16985894625255407295, - "uses": ["6:14-6:15|0|1|4"], + "type": 0, + "uses": ["6:14-6:15|16985894625255407295|2|4"], "kind": 22, "storage": 0 }, { @@ -57,14 +71,14 @@ Foo x = Foo::A; "storage": 0 }, { "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20", + "hover": "Foo::B = 20 = 20", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|2", + "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 79f3922ca..bb21a22a7 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -12,12 +12,12 @@ Foo b; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "A", - "qual_name_offset": 0, + "detailed_name": "enum A {\n}", + "qual_name_offset": 5, "short_name": "A", "kind": 10, "declarations": [], @@ -33,25 +33,25 @@ Foo b; "uses": ["9:5-9:6|0|1|4"] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], "spell": "5:8-5:11|0|1|2", "extent": "5:1-7:2|0|1|0", "alias_of": 0, "bases": [], "derived": [], - "types": [], + "types": [13938528237873543349], "funcs": [], "vars": [], "instances": [12028309045033782423], "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] }, { "usr": 13892793056005362145, - "detailed_name": "B", - "qual_name_offset": 0, + "detailed_name": "enum B {\n}", + "qual_name_offset": 5, "short_name": "B", "kind": 10, "declarations": [], @@ -67,12 +67,12 @@ Foo b; "uses": ["10:5-10:6|0|1|4"] }, { "usr": 13938528237873543349, - "detailed_name": "Foo::Inner", - "qual_name_offset": 0, + "detailed_name": "struct Foo::Inner {}", + "qual_name_offset": 7, "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|2", + "spell": "6:10-6:15|10528472276654770367|2|514", "extent": "6:3-6:18|10528472276654770367|2|0", "alias_of": 0, "bases": [], @@ -81,7 +81,7 @@ Foo b; "funcs": [], "vars": [], "instances": [16721564935990383768], - "uses": ["9:9-9:14|0|1|4"] + "uses": ["9:9-9:14|10528472276654770367|2|4"] }], "usr2var": [{ "usr": 12028309045033782423, diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index 144fee637..8c012d02d 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -4,7 +4,7 @@ void foo(int a, int b); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 2747674671862363334, "detailed_name": "void foo(int a, int b)", diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index e38224531..8a934caee 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -6,7 +6,7 @@ void foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -16,7 +16,7 @@ void foo() {} "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "3:1-3:14|0|1|0", + "extent": "1:1-1:11|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index b92b0d370..9a58dfaf4 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -4,7 +4,7 @@ void foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index 52959abc1..681498522 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -5,15 +5,15 @@ class Derived : public Parent {}; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 3866412049634585509, - "detailed_name": "Parent", - "qual_name_offset": 0, + "detailed_name": "class Parent {}", + "qual_name_offset": 6, "short_name": "Parent", "kind": 5, - "declarations": ["2:24-2:30|0|1|4"], + "declarations": [], "spell": "1:7-1:13|0|1|2", "extent": "1:1-1:16|0|1|0", "alias_of": 0, @@ -23,11 +23,11 @@ class Derived : public Parent {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:30|0|1|4"] + "uses": ["2:24-2:30|0|1|1028"] }, { "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, + "detailed_name": "class Derived : public Parent {}", + "qual_name_offset": 6, "short_name": "Derived", "kind": 5, "declarations": [], diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index da6331e6e..1c9f1b9c0 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -16,30 +16,15 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ - "usr": 9, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [12990052348105569112], - "uses": [] - }, { "usr": 5863733211528032190, - "detailed_name": "Derived1", - "qual_name_offset": 0, + "detailed_name": "class Derived1 : Base1 {}", + "qual_name_offset": 6, "short_name": "Derived1", "kind": 5, - "declarations": ["13:43-13:51|0|1|4"], + "declarations": [], "spell": "8:7-8:15|0|1|2", "extent": "8:1-8:29|0|1|0", "alias_of": 0, @@ -49,31 +34,14 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:43-13:51|0|1|4"] - }, { - "usr": 7916588271848318236, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "10:19-10:20|0|1|2", - "extent": "10:10-10:20|0|1|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["11:24-11:25|0|1|4"] + "uses": ["13:43-13:51|0|1|1028"] }, { "usr": 10651399730831737929, - "detailed_name": "Derived2", - "qual_name_offset": 0, + "detailed_name": "class Derived2 : Base2 {}", + "qual_name_offset": 6, "short_name": "Derived2", "kind": 5, - "declarations": ["13:56-13:64|0|1|4"], + "declarations": [], "spell": "11:7-11:15|0|1|2", "extent": "11:1-11:29|0|1|0", "alias_of": 0, @@ -83,14 +51,14 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:56-13:64|0|1|4"] + "uses": ["13:56-13:64|0|1|1028"] }, { "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, + "detailed_name": "class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}", + "qual_name_offset": 6, "short_name": "Derived", "kind": 5, - "declarations": ["13:33-13:40|0|1|4", "13:65-13:72|0|1|4"], + "declarations": [], "spell": "13:7-13:14|0|1|2", "extent": "13:1-13:76|0|1|0", "alias_of": 0, @@ -100,14 +68,14 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:33-13:40|0|1|4", "13:65-13:72|0|1|4"] + "uses": ["13:33-13:40|0|1|1028", "13:65-13:72|0|1|1028"] }, { "usr": 11118288764693061434, - "detailed_name": "Base2", - "qual_name_offset": 0, + "detailed_name": "class Base2 {}", + "qual_name_offset": 6, "short_name": "Base2", "kind": 5, - "declarations": ["11:18-11:23|0|1|4", "13:27-13:32|0|1|4"], + "declarations": [], "spell": "5:7-5:12|0|1|2", "extent": "5:1-5:15|0|1|0", "alias_of": 0, @@ -117,14 +85,14 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["11:18-11:23|0|1|4", "13:27-13:32|0|1|4"] + "uses": ["11:18-11:23|0|1|1028", "13:27-13:32|0|1|1028"] }, { "usr": 11930058224338108382, - "detailed_name": "Base1", - "qual_name_offset": 0, + "detailed_name": "class Base1 {}", + "qual_name_offset": 6, "short_name": "Base1", "kind": 5, - "declarations": ["8:18-8:23|0|1|4", "13:17-13:22|0|1|4"], + "declarations": [], "spell": "2:7-2:12|0|1|2", "extent": "2:1-2:15|0|1|0", "alias_of": 0, @@ -134,20 +102,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["8:18-8:23|0|1|4", "13:17-13:22|0|1|4"] + "uses": ["8:18-8:23|0|1|1028", "13:17-13:22|0|1|1028"] }], - "usr2var": [{ - "usr": 12990052348105569112, - "detailed_name": "unsigned int T", - "qual_name_offset": 13, - "short_name": "", - "declarations": [], - "spell": "7:23-7:24|0|1|2", - "extent": "7:10-7:24|0|1|0", - "type": 9, - "uses": ["8:24-8:25|0|1|4"], - "kind": 26, - "storage": 0 - }] + "usr2var": [] } */ diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index 84338ad61..377426327 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -7,15 +7,15 @@ class Derived : public MiddleA, public MiddleB {}; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 3897841498936210886, - "detailed_name": "Root", - "qual_name_offset": 0, + "detailed_name": "class Root {}", + "qual_name_offset": 6, "short_name": "Root", "kind": 5, - "declarations": ["2:24-2:28|0|1|4", "3:24-3:28|0|1|4"], + "declarations": [], "spell": "1:7-1:11|0|1|2", "extent": "1:1-1:14|0|1|0", "alias_of": 0, @@ -25,11 +25,11 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:28|0|1|4", "3:24-3:28|0|1|4"] + "uses": ["2:24-2:28|0|1|1028", "3:24-3:28|0|1|1028"] }, { "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, + "detailed_name": "class Derived : public MiddleA, public MiddleB {}", + "qual_name_offset": 6, "short_name": "Derived", "kind": 5, "declarations": [], @@ -45,11 +45,11 @@ class Derived : public MiddleA, public MiddleB {}; "uses": [] }, { "usr": 11863524815063131483, - "detailed_name": "MiddleA", - "qual_name_offset": 0, + "detailed_name": "class MiddleA : public Root {}", + "qual_name_offset": 6, "short_name": "MiddleA", "kind": 5, - "declarations": ["4:24-4:31|0|1|4"], + "declarations": [], "spell": "2:7-2:14|0|1|2", "extent": "2:1-2:31|0|1|0", "alias_of": 0, @@ -59,14 +59,14 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:24-4:31|0|1|4"] + "uses": ["4:24-4:31|0|1|1028"] }, { "usr": 14022569716337624303, - "detailed_name": "MiddleB", - "qual_name_offset": 0, + "detailed_name": "class MiddleB : public Root {}", + "qual_name_offset": 6, "short_name": "MiddleB", "kind": 5, - "declarations": ["4:40-4:47|0|1|4"], + "declarations": [], "spell": "3:7-3:14|0|1|2", "extent": "3:1-3:31|0|1|0", "alias_of": 0, @@ -76,7 +76,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:40-4:47|0|1|4"] + "uses": ["4:40-4:47|0|1|1028"] }], "usr2var": [] } diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 34da20a68..446e08167 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -9,18 +9,18 @@ class Derived : public Root { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 6666242542855173890, - "detailed_name": "void Derived::foo() override", + "detailed_name": "void Derived::foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 6, "storage": 0, "declarations": [], - "spell": "5:8-5:11|10963370434658308541|2|2", + "spell": "5:8-5:11|10963370434658308541|2|2626", "extent": "5:3-5:25|10963370434658308541|2|0", - "declaring_type": 10963370434658308541, + "declaring_type": 0, "bases": [9948027785633571339], "derived": [], "vars": [], @@ -33,8 +33,8 @@ class Derived : public Root { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:16-2:19|3897841498936210886|2|1"], - "declaring_type": 3897841498936210886, + "declarations": ["2:16-2:19|3897841498936210886|2|577"], + "declaring_type": 0, "bases": [], "derived": [6666242542855173890], "vars": [], @@ -43,11 +43,11 @@ class Derived : public Root { }], "usr2type": [{ "usr": 3897841498936210886, - "detailed_name": "Root", - "qual_name_offset": 0, + "detailed_name": "class Root {}", + "qual_name_offset": 6, "short_name": "Root", "kind": 5, - "declarations": ["4:24-4:28|0|1|4"], + "declarations": [], "spell": "1:7-1:11|0|1|2", "extent": "1:1-3:2|0|1|0", "alias_of": 0, @@ -57,11 +57,11 @@ class Derived : public Root { "funcs": [9948027785633571339], "vars": [], "instances": [], - "uses": ["4:24-4:28|0|1|4"] + "uses": ["4:24-4:28|0|1|1028"] }, { "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, + "detailed_name": "class Derived : public Root {}", + "qual_name_offset": 6, "short_name": "Derived", "kind": 5, "declarations": [], diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index 0d99ad9a3..2778e0af7 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -6,7 +6,7 @@ class IFoo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3277829753446788562, "detailed_name": "virtual void IFoo::foo() = 0", @@ -14,10 +14,8 @@ class IFoo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": [], - "spell": "2:16-2:19|9949214233977131946|2|2", - "extent": "2:3-2:25|9949214233977131946|2|0", - "declaring_type": 9949214233977131946, + "declarations": ["2:16-2:19|9949214233977131946|2|577"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -26,8 +24,8 @@ class IFoo { }], "usr2type": [{ "usr": 9949214233977131946, - "detailed_name": "IFoo", - "qual_name_offset": 0, + "detailed_name": "class IFoo {}", + "qual_name_offset": 6, "short_name": "IFoo", "kind": 5, "declarations": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 83fa7a9bc..1d86907fd 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -12,7 +12,7 @@ struct Derived : Base0, Base1 { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8401779086123965305, "detailed_name": "virtual Base1::~Base1() noexcept", @@ -21,26 +21,26 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:17|15826803741381445676|2|2", + "spell": "5:11-5:12|15826803741381445676|2|578", "extent": "5:3-5:23|15826803741381445676|2|0", - "declaring_type": 15826803741381445676, + "declaring_type": 0, "bases": [], - "derived": [13164726294460837993], + "derived": [], "vars": [], "uses": [], "callees": [] }, { "usr": 13164726294460837993, - "detailed_name": "Derived::~Derived() noexcept override", + "detailed_name": "Derived::~Derived() noexcept", "qual_name_offset": 0, "short_name": "~Derived", "kind": 6, "storage": 0, "declarations": [], - "spell": "8:3-8:11|10963370434658308541|2|2", + "spell": "8:3-8:4|10963370434658308541|2|2626", "extent": "8:3-8:26|10963370434658308541|2|0", - "declaring_type": 10963370434658308541, - "bases": [16347272523198263017, 8401779086123965305], + "declaring_type": 0, + "bases": [], "derived": [], "vars": [], "uses": [], @@ -53,22 +53,22 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:11-2:17|11628904180681204356|2|2", + "spell": "2:11-2:12|11628904180681204356|2|578", "extent": "2:3-2:23|11628904180681204356|2|0", - "declaring_type": 11628904180681204356, + "declaring_type": 0, "bases": [], - "derived": [13164726294460837993], + "derived": [], "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 10963370434658308541, - "detailed_name": "Derived", - "qual_name_offset": 0, + "detailed_name": "struct Derived : Base0, Base1 {}", + "qual_name_offset": 7, "short_name": "Derived", "kind": 23, - "declarations": ["8:4-8:11|0|1|4"], + "declarations": [], "spell": "7:8-7:15|0|1|2", "extent": "7:1-9:2|0|1|0", "alias_of": 0, @@ -78,14 +78,14 @@ struct Derived : Base0, Base1 { "funcs": [13164726294460837993], "vars": [], "instances": [], - "uses": [] + "uses": ["8:4-8:11|0|1|4"] }, { "usr": 11628904180681204356, - "detailed_name": "Base0", - "qual_name_offset": 0, + "detailed_name": "struct Base0 {}", + "qual_name_offset": 7, "short_name": "Base0", "kind": 23, - "declarations": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|4"], + "declarations": [], "spell": "1:8-1:13|0|1|2", "extent": "1:1-3:2|0|1|0", "alias_of": 0, @@ -95,14 +95,14 @@ struct Derived : Base0, Base1 { "funcs": [16347272523198263017], "vars": [], "instances": [], - "uses": ["7:18-7:23|0|1|4"] + "uses": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|1028"] }, { "usr": 15826803741381445676, - "detailed_name": "Base1", - "qual_name_offset": 0, + "detailed_name": "struct Base1 {}", + "qual_name_offset": 7, "short_name": "Base1", "kind": 23, - "declarations": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|4"], + "declarations": [], "spell": "4:8-4:13|0|1|2", "extent": "4:1-6:2|0|1|0", "alias_of": 0, @@ -112,7 +112,7 @@ struct Derived : Base0, Base1 { "funcs": [8401779086123965305], "vars": [], "instances": [], - "uses": ["7:25-7:30|0|1|4"] + "uses": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|1028"] }], "usr2var": [] } diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index b1bdc4516..d37380102 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -15,7 +15,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -29,26 +29,26 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [12666114896600231317, 2981279427664991319], + "vars": [], "uses": [], - "callees": ["9:14-9:15|17926497908620168464|3|32", "10:14-10:15|17926497908620168464|3|32", "11:14-11:15|17926497908620168464|3|32"] + "callees": [] }, { "usr": 17926497908620168464, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "inline void foo()::(anon class)::operator()(int y) const", + "qual_name_offset": 12, + "short_name": "operator()", + "kind": 6, "storage": 0, "declarations": [], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["9:14-9:15|4259594751088586730|3|32", "10:14-10:15|4259594751088586730|3|32", "11:14-11:15|4259594751088586730|3|32"], + "uses": ["9:14-9:15|14635009347499519042|2|8228", "10:14-10:15|14635009347499519042|2|8228", "11:14-11:15|14635009347499519042|2|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -60,7 +60,7 @@ void foo() { "types": [], "funcs": [], "vars": [], - "instances": [12666114896600231317, 12879188959314906706], + "instances": [12666114896600231317], "uses": [] }, { "usr": 14635009347499519042, @@ -75,18 +75,19 @@ void foo() { "types": [], "funcs": [], "vars": [], - "instances": [2981279427664991319], + "instances": [], "uses": [] }], "usr2var": [{ "usr": 2981279427664991319, - "detailed_name": "lambda dosomething", - "qual_name_offset": 7, + "detailed_name": "auto dosomething", + "qual_name_offset": 5, "short_name": "dosomething", + "hover": "auto dosomething = [&x] (int y) {\n ++x;\n ++y;\n }\n", "declarations": [], "spell": "4:8-4:19|4259594751088586730|3|2", "extent": "4:3-7:4|4259594751088586730|3|0", - "type": 14635009347499519042, + "type": 0, "uses": ["9:3-9:14|4259594751088586730|3|4", "10:3-10:14|4259594751088586730|3|4", "11:3-11:14|4259594751088586730|3|4"], "kind": 13, "storage": 0 @@ -98,20 +99,18 @@ void foo() { "declarations": [], "spell": "2:7-2:8|4259594751088586730|3|2", "extent": "2:3-2:8|4259594751088586730|3|0", - "type": 17, - "uses": ["5:7-5:8|0|1|4", "4:24-4:25|4259594751088586730|3|4"], + "type": 53, + "uses": ["4:24-4:25|4259594751088586730|3|4", "5:7-5:8|4259594751088586730|3|28"], "kind": 13, "storage": 0 }, { "usr": 12879188959314906706, "detailed_name": "int y", "qual_name_offset": 4, - "short_name": "", + "short_name": "y", "declarations": [], - "spell": "4:31-4:32|4259594751088586730|3|2", - "extent": "4:27-4:32|4259594751088586730|3|0", - "type": 17, - "uses": ["6:7-6:8|4259594751088586730|3|4"], + "type": 0, + "uses": ["6:7-6:8|17926497908620168464|3|28"], "kind": 253, "storage": 0 }] diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index f29cfba38..f014946e3 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -15,7 +15,7 @@ FOO(make1(), make2); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9720930732776154610, "detailed_name": "int a()", @@ -23,15 +23,15 @@ FOO(make1(), make2); "short_name": "a", "kind": 12, "storage": 0, - "declarations": ["12:1-12:20|0|1|1"], - "spell": "12:1-12:20|0|1|2", - "extent": "12:1-12:20|0|1|0", + "declarations": ["12:1-12:4|0|1|1"], + "spell": "12:1-12:4|0|1|2", + "extent": "1:1-1:1|0|1|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": [], - "callees": ["12:5-12:10|14400399977994209582|3|32"] + "uses": ["2:7-2:8|0|1|64", "3:7-3:8|0|1|64"], + "callees": [] }, { "usr": 14400399977994209582, "detailed_name": "int make1()", @@ -46,11 +46,11 @@ FOO(make1(), make2); "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|9720930732776154610|3|32"], + "uses": ["12:5-12:10|0|1|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -74,21 +74,21 @@ FOO(make1(), make2); "declarations": [], "spell": "9:11-9:16|0|1|2", "extent": "9:1-9:20|0|1|0", - "type": 17, - "uses": ["12:14-12:19|9720930732776154610|3|4"], + "type": 53, + "uses": ["12:14-12:19|0|1|12"], "kind": 13, "storage": 0 }, { - "usr": 4261071340275951718, + "usr": 14219599523415845943, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", - "hover": "#define FOO(aaa, bbb)\n int a();\n int a() { return aaa + bbb; }", + "hover": "#define FOO", "declarations": [], "spell": "1:9-1:12|0|1|2", - "extent": "1:9-3:32|0|1|0", + "extent": "1:9-1:12|0|1|2", "type": 0, - "uses": ["12:1-12:4|0|1|4"], + "uses": ["12:1-12:20|0|1|4"], "kind": 255, "storage": 0 }] diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 00cb44ed8..50f38b941 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -11,7 +11,7 @@ int x = A; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 13788753348312146871, "detailed_name": "Foo::Foo(Foo &&) = delete", @@ -20,9 +20,9 @@ int x = A; "kind": 9, "storage": 0, "declarations": [], - "spell": "5:12-5:15|15041163540773201510|2|2", - "extent": "5:12-5:16|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "spell": "5:12-5:15|15041163540773201510|2|514", + "extent": "1:1-1:1|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -30,7 +30,7 @@ int x = A; "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -46,11 +46,11 @@ int x = A; "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["5:12-5:15|0|1|4"], + "declarations": [], "spell": "4:8-4:11|0|1|2", "extent": "4:1-6:2|0|1|0", "alias_of": 0, @@ -60,32 +60,32 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:12-5:15|15041163540773201510|2|4"] + "uses": ["5:12-5:15|0|1|4"] }], "usr2var": [{ - "usr": 2056319845419860263, - "detailed_name": "DISALLOW", + "usr": 1569772797058982873, + "detailed_name": "A", "qual_name_offset": 0, - "short_name": "DISALLOW", - "hover": "#define DISALLOW(type) type(type&&) = delete;", + "short_name": "A", + "hover": "#define A", "declarations": [], - "spell": "2:9-2:17|0|1|2", - "extent": "2:9-2:46|0|1|0", + "spell": "1:9-1:10|0|1|2", + "extent": "1:9-1:10|0|1|2", "type": 0, - "uses": ["5:3-5:11|0|1|4"], + "uses": ["8:9-8:10|0|1|4"], "kind": 255, "storage": 0 }, { - "usr": 7651988378939587454, - "detailed_name": "A", + "usr": 4904139678698066671, + "detailed_name": "DISALLOW", "qual_name_offset": 0, - "short_name": "A", - "hover": "#define A 5", + "short_name": "DISALLOW", + "hover": "#define DISALLOW", "declarations": [], - "spell": "1:9-1:10|0|1|2", - "extent": "1:9-1:12|0|1|0", + "spell": "2:9-2:17|0|1|2", + "extent": "2:9-2:17|0|1|2", "type": 0, - "uses": ["8:9-8:10|0|1|4"], + "uses": ["5:3-5:16|0|1|4"], "kind": 255, "storage": 0 }, { @@ -93,11 +93,11 @@ int x = A; "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", - "hover": "int x = A", + "hover": "int x = 5", "declarations": [], "spell": "8:5-8:6|0|1|2", - "extent": "8:1-8:10|0|1|0", - "type": 17, + "extent": "8:1-1:1|0|1|0", + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index 3eaf1f735..c423ccdf1 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -10,7 +10,7 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", @@ -18,8 +18,8 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:11|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -28,8 +28,8 @@ class Foo { }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index e9d2c040d..28caf615a 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -8,7 +8,7 @@ void Foo::foo() const {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 6446764306530590711, "detailed_name": "void Foo::foo() const", @@ -16,10 +16,10 @@ void Foo::foo() const {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1"], - "spell": "5:11-5:14|15041163540773201510|2|2", - "extent": "5:1-5:25|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:11|15041163540773201510|2|513"], + "spell": "5:11-5:14|15041163540773201510|2|514", + "extent": "2:3-2:19|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -28,8 +28,8 @@ void Foo::foo() const {} }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index 08391d632..e676130fb 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -6,7 +6,7 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", @@ -15,9 +15,9 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:11|15041163540773201510|2|2", + "spell": "2:8-2:11|15041163540773201510|2|514", "extent": "2:3-2:16|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -26,8 +26,8 @@ class Foo { }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 0787f9db2..ea2914680 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -9,13 +9,27 @@ enum Foo { OUTPUT: funky_enum.h { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 16985894625255407295, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [439339022761937396, 15962370213938840720, 8524995777615948802], + "uses": [], + "callees": [] + }], "usr2type": [{ "usr": 16985894625255407295, - "detailed_name": "Foo", + "detailed_name": "", "qual_name_offset": 0, - "short_name": "Foo", + "short_name": "", "kind": 0, "declarations": [], "alias_of": 0, @@ -29,40 +43,43 @@ OUTPUT: funky_enum.h }], "usr2var": [{ "usr": 439339022761937396, - "detailed_name": "Foo::A", + "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", - "hover": "Foo::A = 0", + "hover": "A = 0", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "4:1-4:2|16985894625255407295|2|2", + "spell": "4:1-4:2|16985894625255407295|2|514", "extent": "4:1-4:2|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 8524995777615948802, - "detailed_name": "Foo::C", + "detailed_name": "C", "qual_name_offset": 0, "short_name": "C", - "hover": "Foo::C = 2", + "hover": "C = 2", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "6:1-6:2|16985894625255407295|2|2", + "spell": "6:1-6:2|16985894625255407295|2|514", "extent": "6:1-6:2|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 15962370213938840720, - "detailed_name": "Foo::B", + "detailed_name": "B", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 1", + "hover": "B = 1", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "5:1-5:2|16985894625255407295|2|2", + "spell": "5:1-5:2|16985894625255407295|2|514", "extent": "5:1-5:2|16985894625255407295|2|0", - "type": 16985894625255407295, + "type": 0, "uses": [], "kind": 22, "storage": 0 @@ -70,16 +87,13 @@ OUTPUT: funky_enum.h } OUTPUT: funky_enum.cc { - "includes": [{ - "line": 1, - "resolved_path": "&funky_enum.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "enum Foo {\n}", + "qual_name_offset": 5, "short_name": "Foo", "kind": 10, "declarations": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 1a52c2de6..a978e97e4 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -8,8 +8,22 @@ void Impl() { OUTPUT: header.h { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ + "usr": 4481210672785600703, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [6141718166919284735, 17716334512218775320, 7285646116511901840], + "uses": [], + "callees": [] + }, { "usr": 11650481237659640387, "detailed_name": "void Foo1()", "qual_name_offset": 5, @@ -27,7 +41,7 @@ OUTPUT: header.h "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -43,10 +57,10 @@ OUTPUT: header.h "uses": [] }, { "usr": 529393482671181129, - "detailed_name": "Foo2", - "qual_name_offset": 0, + "detailed_name": "struct Foo2 {}", + "qual_name_offset": 7, "short_name": "Foo2", - "kind": 5, + "kind": 23, "declarations": [], "spell": "13:8-13:12|0|1|2", "extent": "13:1-13:15|0|1|0", @@ -60,11 +74,10 @@ OUTPUT: header.h "uses": [] }, { "usr": 619345544228965342, - "detailed_name": "Foo0", - "qual_name_offset": 0, + "detailed_name": "using Foo0 = SameFileDerived", + "qual_name_offset": 6, "short_name": "Foo0", "kind": 252, - "hover": "using Foo0 = SameFileDerived", "declarations": [], "spell": "7:7-7:11|0|1|2", "extent": "7:1-7:29|0|1|0", @@ -75,11 +88,11 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["7:7-7:11|0|1|4"] + "uses": [] }, { "usr": 4481210672785600703, - "detailed_name": "Foo3", - "qual_name_offset": 0, + "detailed_name": "enum Foo3 {\n}", + "qual_name_offset": 5, "short_name": "Foo3", "kind": 10, "declarations": [], @@ -95,11 +108,11 @@ OUTPUT: header.h "uses": [] }, { "usr": 8420119006782424779, - "detailed_name": "Base", - "qual_name_offset": 0, + "detailed_name": "struct Base {}", + "qual_name_offset": 7, "short_name": "Base", "kind": 23, - "declarations": ["5:26-5:30|0|1|4"], + "declarations": [], "spell": "3:8-3:12|0|1|2", "extent": "3:1-3:15|0|1|0", "alias_of": 0, @@ -109,11 +122,11 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["5:26-5:30|0|1|4"] + "uses": ["5:26-5:30|0|1|1028"] }, { "usr": 16750616846959666305, - "detailed_name": "SameFileDerived", - "qual_name_offset": 0, + "detailed_name": "struct SameFileDerived : Base {}", + "qual_name_offset": 7, "short_name": "SameFileDerived", "kind": 23, "declarations": [], @@ -136,58 +149,58 @@ OUTPUT: header.h "declarations": [], "spell": "17:5-17:9|0|1|2", "extent": "17:1-17:9|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 }, { "usr": 6141718166919284735, - "detailed_name": "Foo3::A", + "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", - "hover": "Foo3::A = 0", + "hover": "A = 0", "declarations": [], - "spell": "15:13-15:14|4481210672785600703|2|2", + "spell": "15:13-15:14|4481210672785600703|2|514", "extent": "15:13-15:14|4481210672785600703|2|0", - "type": 4481210672785600703, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 7285646116511901840, - "detailed_name": "Foo3::C", + "detailed_name": "C", "qual_name_offset": 0, "short_name": "C", - "hover": "Foo3::C = 2", + "hover": "C = 2", "declarations": [], - "spell": "15:19-15:20|4481210672785600703|2|2", + "spell": "15:19-15:20|4481210672785600703|2|514", "extent": "15:19-15:20|4481210672785600703|2|0", - "type": 4481210672785600703, + "type": 0, "uses": [], "kind": 22, "storage": 0 }, { "usr": 8395885290297540138, - "detailed_name": "int Foo5", - "qual_name_offset": 4, + "detailed_name": "static int Foo5", + "qual_name_offset": 11, "short_name": "Foo5", "declarations": [], "spell": "18:12-18:16|0|1|2", "extent": "18:1-18:16|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 2 }, { "usr": 17716334512218775320, - "detailed_name": "Foo3::B", + "detailed_name": "B", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo3::B = 1", + "hover": "B = 1", "declarations": [], - "spell": "15:16-15:17|4481210672785600703|2|2", + "spell": "15:16-15:17|4481210672785600703|2|514", "extent": "15:16-15:17|4481210672785600703|2|0", - "type": 4481210672785600703, + "type": 0, "uses": [], "kind": 22, "storage": 0 @@ -195,11 +208,8 @@ OUTPUT: header.h } OUTPUT: impl.cc { - "includes": [{ - "line": 0, - "resolved_path": "&header.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [{ "usr": 5817708529036841195, "detailed_name": "void Impl()", @@ -215,20 +225,20 @@ OUTPUT: impl.cc "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:7|11650481237659640387|3|32"] + "callees": [] }, { "usr": 11650481237659640387, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "void Foo1()", + "qual_name_offset": 5, + "short_name": "Foo1", + "kind": 12, "storage": 0, "declarations": [], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:7|5817708529036841195|3|32"], + "uses": ["4:3-4:7|0|1|8228"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 3469d9fcb..639d0f69c 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -8,7 +8,7 @@ void impl() { OUTPUT: simple_header.h { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 16236105532929924676, "detailed_name": "void header()", @@ -29,11 +29,8 @@ OUTPUT: simple_header.h } OUTPUT: simple_impl.cc { - "includes": [{ - "line": 0, - "resolved_path": "&simple_header.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3373269392705484958, "detailed_name": "void impl()", @@ -49,20 +46,20 @@ OUTPUT: simple_impl.cc "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:9|16236105532929924676|3|32"] + "callees": [] }, { "usr": 16236105532929924676, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "void header()", + "qual_name_offset": 5, + "short_name": "header", + "kind": 12, "storage": 0, "declarations": [], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:9|3373269392705484958|3|32"], + "uses": ["4:3-4:9|0|1|8228"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 89bae0f7f..5a607e6a9 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -6,16 +6,16 @@ void Buffer::CreateSharedBuffer() {} OUTPUT: static.h { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, "detailed_name": "static void Buffer::CreateSharedBuffer()", "qual_name_offset": 12, "short_name": "CreateSharedBuffer", - "kind": 254, - "storage": 2, - "declarations": ["4:15-4:33|9411323049603567600|2|1"], - "declaring_type": 9411323049603567600, + "kind": 6, + "storage": 0, + "declarations": ["4:15-4:33|9411323049603567600|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -24,8 +24,8 @@ OUTPUT: static.h }], "usr2type": [{ "usr": 9411323049603567600, - "detailed_name": "Buffer", - "qual_name_offset": 0, + "detailed_name": "struct Buffer {}", + "qual_name_offset": 7, "short_name": "Buffer", "kind": 23, "declarations": [], @@ -44,22 +44,19 @@ OUTPUT: static.h } OUTPUT: static.cc { - "includes": [{ - "line": 0, - "resolved_path": "&static.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, - "detailed_name": "void Buffer::CreateSharedBuffer()", - "qual_name_offset": 5, + "detailed_name": "static void Buffer::CreateSharedBuffer()", + "qual_name_offset": 12, "short_name": "CreateSharedBuffer", - "kind": 254, + "kind": 6, "storage": 0, "declarations": [], - "spell": "3:14-3:32|9411323049603567600|2|2", - "extent": "3:1-3:37|0|1|0", - "declaring_type": 9411323049603567600, + "spell": "3:14-3:32|9411323049603567600|2|514", + "extent": "4:3-4:35|9411323049603567600|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -68,10 +65,10 @@ OUTPUT: static.cc }], "usr2type": [{ "usr": 9411323049603567600, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "struct Buffer {}", + "qual_name_offset": 7, + "short_name": "Buffer", + "kind": 23, "declarations": [], "alias_of": 0, "bases": [], diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 359691cc3..c07d54abe 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -6,7 +6,7 @@ void foo(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 5010253035933134245, "detailed_name": "void (anon ns)::foo()", @@ -15,7 +15,7 @@ void foo(); "kind": 12, "storage": 0, "declarations": ["2:6-2:9|7144845543074395457|2|1"], - "declaring_type": 7144845543074395457, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 81038adcc..4a65e65e5 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -6,7 +6,7 @@ void foo(int a, int b); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 18343102288837190527, "detailed_name": "void hello::foo(int a, int b)", @@ -14,8 +14,8 @@ void foo(int a, int b); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["2:6-2:9|2029211996748007610|2|1"], - "declaring_type": 2029211996748007610, + "declarations": ["2:6-2:9|2029211996748007610|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -24,35 +24,18 @@ void foo(int a, int b); }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "hello", - "qual_name_offset": 0, + "detailed_name": "namespace hello {\n}", + "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": [], - "spell": "1:11-1:16|0|1|2", - "extent": "1:1-3:2|0|1|0", + "declarations": ["1:11-1:16|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], "types": [], "funcs": [18343102288837190527], "vars": [], "instances": [], - "uses": ["1:11-1:16|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [2029211996748007610], - "types": [], - "funcs": [], - "vars": [], - "instances": [], "uses": [] }], "usr2var": [] diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index c909296eb..08bec46ec 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -6,7 +6,7 @@ void foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 243328841292951622, "detailed_name": "void hello::foo()", @@ -15,9 +15,9 @@ void foo() {} "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:9|2029211996748007610|2|2", + "spell": "2:6-2:9|2029211996748007610|2|514", "extent": "2:1-2:14|2029211996748007610|2|0", - "declaring_type": 2029211996748007610, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -26,35 +26,18 @@ void foo() {} }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "hello", - "qual_name_offset": 0, + "detailed_name": "namespace hello {\n}", + "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": [], - "spell": "1:11-1:16|0|1|2", - "extent": "1:1-3:2|0|1|0", + "declarations": ["1:11-1:16|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], "types": [], "funcs": [243328841292951622], "vars": [], "instances": [], - "uses": ["1:11-1:16|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [2029211996748007610], - "types": [], - "funcs": [], - "vars": [], - "instances": [], "uses": [] }], "usr2var": [] diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index a50505d3c..4e728b302 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -8,7 +8,7 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", @@ -16,8 +16,8 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|1"], - "declaring_type": 4508214972876735896, + "declarations": ["3:8-3:11|4508214972876735896|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -26,29 +26,27 @@ class Foo { }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "hello", - "qual_name_offset": 0, + "detailed_name": "namespace hello {\n}", + "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": [], - "spell": "1:11-1:16|0|1|2", - "extent": "1:1-5:2|0|1|0", + "declarations": ["1:11-1:16|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], - "types": [], + "types": [4508214972876735896], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|0|1|4"] + "uses": [] }, { "usr": 4508214972876735896, - "detailed_name": "hello::Foo", - "qual_name_offset": 0, + "detailed_name": "class hello::Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|2", + "spell": "2:7-2:10|2029211996748007610|2|514", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], @@ -58,21 +56,6 @@ class Foo { "vars": [], "instances": [], "uses": [] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [2029211996748007610], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] }], "usr2var": [] } diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 68f7f8d88..12efc78bb 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -10,7 +10,7 @@ void Foo::foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", @@ -18,10 +18,10 @@ void Foo::foo() {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|1"], - "spell": "6:11-6:14|4508214972876735896|2|2", - "extent": "6:1-6:19|2029211996748007610|2|0", - "declaring_type": 4508214972876735896, + "declarations": ["3:8-3:11|4508214972876735896|2|513"], + "spell": "6:11-6:14|4508214972876735896|2|514", + "extent": "3:3-3:13|4508214972876735896|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -30,29 +30,27 @@ void Foo::foo() {} }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "hello", - "qual_name_offset": 0, + "detailed_name": "namespace hello {\n}", + "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": [], - "spell": "1:11-1:16|0|1|2", - "extent": "1:1-7:2|0|1|0", + "declarations": ["1:11-1:16|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], - "types": [], + "types": [4508214972876735896], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|0|1|4"] + "uses": [] }, { "usr": 4508214972876735896, - "detailed_name": "hello::Foo", - "qual_name_offset": 0, + "detailed_name": "class hello::Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|2", + "spell": "2:7-2:10|2029211996748007610|2|514", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], @@ -61,22 +59,7 @@ void Foo::foo() {} "funcs": [10487325150128053272], "vars": [], "instances": [], - "uses": ["6:6-6:9|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [2029211996748007610], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] + "uses": ["6:6-6:9|2029211996748007610|2|4"] }], "usr2var": [] } diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index 97259490b..3890719dc 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -8,7 +8,7 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 10487325150128053272, "detailed_name": "void hello::Foo::foo()", @@ -17,9 +17,9 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "3:8-3:11|4508214972876735896|2|2", + "spell": "3:8-3:11|4508214972876735896|2|514", "extent": "3:3-3:16|4508214972876735896|2|0", - "declaring_type": 4508214972876735896, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -28,29 +28,27 @@ class Foo { }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "hello", - "qual_name_offset": 0, + "detailed_name": "namespace hello {\n}", + "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": [], - "spell": "1:11-1:16|0|1|2", - "extent": "1:1-5:2|0|1|0", + "declarations": ["1:11-1:16|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], - "types": [], + "types": [4508214972876735896], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:16|0|1|4"] + "uses": [] }, { "usr": 4508214972876735896, - "detailed_name": "hello::Foo", - "qual_name_offset": 0, + "detailed_name": "class hello::Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|2", + "spell": "2:7-2:10|2029211996748007610|2|514", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], @@ -60,21 +58,6 @@ class Foo { "vars": [], "instances": [], "uses": [] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [2029211996748007610], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] }], "usr2var": [] } diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 9b768031a..88f1adf34 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -17,7 +17,7 @@ void func() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 10818727483146447186, "detailed_name": "void func()", @@ -31,12 +31,26 @@ void func() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [6030927277961448585, 7657277353101371136], + "vars": [], + "uses": [], + "callees": [] + }, { + "usr": 14450849931009540802, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [15042442838933090518], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -52,90 +66,64 @@ void func() { "uses": [] }, { "usr": 926793467007732869, - "detailed_name": "foo", - "qual_name_offset": 0, + "detailed_name": "namespace foo {\n}", + "qual_name_offset": 10, "short_name": "foo", "kind": 3, - "declarations": [], - "spell": "1:11-1:14|0|1|2", - "extent": "1:1-7:2|0|1|0", + "declarations": ["1:11-1:14|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], - "derived": [17805385787823406700], - "types": [], + "bases": [], + "derived": [], + "types": [17805385787823406700], "funcs": [], "vars": [], "instances": [], - "uses": ["1:11-1:14|0|1|4", "9:17-9:20|0|1|4", "12:11-12:14|10818727483146447186|3|4"] + "uses": ["9:17-9:20|0|1|4", "12:11-12:14|0|1|4"] }, { "usr": 11879713791858506216, - "detailed_name": "fbz", - "qual_name_offset": 0, + "detailed_name": "namespace fbz = foo::bar::baz", + "qual_name_offset": 10, "short_name": "fbz", - "kind": 0, - "declarations": [], - "spell": "9:11-9:14|0|1|2", - "extent": "9:1-9:30|0|1|0", - "alias_of": 0, + "kind": 252, + "declarations": ["9:11-9:14|0|1|1"], + "alias_of": 14450849931009540802, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["13:11-13:14|10818727483146447186|3|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [926793467007732869], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] + "uses": ["13:11-13:14|0|1|4"] }, { "usr": 14450849931009540802, - "detailed_name": "foo::bar::baz", - "qual_name_offset": 0, + "detailed_name": "namespace foo::bar::baz {\n}", + "qual_name_offset": 10, "short_name": "baz", "kind": 3, - "declarations": [], - "spell": "3:20-3:23|17805385787823406700|2|2", - "extent": "3:10-5:11|17805385787823406700|2|0", + "declarations": ["3:20-3:23|17805385787823406700|2|513"], "alias_of": 0, - "bases": [17805385787823406700], + "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [{ - "L": 15042442838933090518, - "R": -1 - }], + "vars": [], "instances": [], - "uses": ["3:20-3:23|17805385787823406700|2|4", "9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] + "uses": ["9:27-9:30|17805385787823406700|2|4", "12:21-12:24|17805385787823406700|2|4"] }, { "usr": 17805385787823406700, - "detailed_name": "foo::bar", - "qual_name_offset": 0, + "detailed_name": "namespace foo::bar {\n}", + "qual_name_offset": 10, "short_name": "bar", "kind": 3, - "declarations": [], - "spell": "2:15-2:18|926793467007732869|2|2", - "extent": "2:5-6:6|926793467007732869|2|0", + "declarations": ["2:15-2:18|926793467007732869|2|513"], "alias_of": 0, - "bases": [926793467007732869], - "derived": [14450849931009540802], - "types": [], + "bases": [], + "derived": [], + "types": [14450849931009540802], "funcs": [], "vars": [], "instances": [], - "uses": ["2:15-2:18|926793467007732869|2|4", "9:22-9:25|0|1|4", "12:16-12:19|10818727483146447186|3|4"] + "uses": ["9:22-9:25|926793467007732869|2|4", "12:16-12:19|926793467007732869|2|4"] }], "usr2var": [{ "usr": 6030927277961448585, @@ -146,7 +134,7 @@ void func() { "declarations": [], "spell": "12:7-12:8|10818727483146447186|3|2", "extent": "12:3-12:29|10818727483146447186|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -159,7 +147,7 @@ void func() { "declarations": [], "spell": "13:7-13:8|10818727483146447186|3|2", "extent": "13:3-13:19|10818727483146447186|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -170,10 +158,10 @@ void func() { "short_name": "qux", "hover": "int foo::bar::baz::qux = 42", "declarations": [], - "spell": "4:18-4:21|14450849931009540802|2|2", + "spell": "4:18-4:21|14450849931009540802|2|514", "extent": "4:14-4:26|14450849931009540802|2|0", - "type": 17, - "uses": ["12:26-12:29|0|1|4", "13:16-13:19|0|1|4"], + "type": 53, + "uses": ["12:26-12:29|14450849931009540802|2|12", "13:16-13:19|14450849931009540802|2|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 3d7ad72a7..c412f7c08 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -13,7 +13,7 @@ void Runner() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 631910859630953711, "detailed_name": "void Runner()", @@ -29,7 +29,21 @@ void Runner() { "derived": [], "vars": [], "uses": [], - "callees": ["7:7-7:13|17328473273923617489|3|32", "9:3-9:9|17328473273923617489|3|32"] + "callees": [] + }, { + "usr": 11072669167287398027, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [12898699035586282159], + "uses": [], + "callees": [] }, { "usr": 17328473273923617489, "detailed_name": "void ns::Accept(int a)", @@ -38,17 +52,17 @@ void Runner() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:8-3:14|11072669167287398027|2|2", + "spell": "3:8-3:14|11072669167287398027|2|514", "extent": "3:3-3:24|11072669167287398027|2|0", - "declaring_type": 11072669167287398027, + "declaring_type": 0, "bases": [], "derived": [], - "vars": [3649375698083002347], - "uses": ["7:7-7:13|631910859630953711|3|32", "9:3-9:9|631910859630953711|3|32"], + "vars": [], + "uses": ["7:7-7:13|11072669167287398027|2|8228", "9:3-9:9|11072669167287398027|2|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -64,39 +78,19 @@ void Runner() { "uses": [] }, { "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": [], - "spell": "1:11-1:13|0|1|2", - "extent": "1:1-4:2|0|1|0", + "declarations": ["1:11-1:13|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], "types": [], "funcs": [17328473273923617489], - "vars": [{ - "L": 12898699035586282159, - "R": -1 - }], - "instances": [], - "uses": ["1:11-1:13|0|1|4", "7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [11072669167287398027], - "types": [], - "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["7:3-7:5|0|1|4", "7:14-7:16|0|1|4", "8:19-8:21|0|1|4"] }], "usr2var": [{ "usr": 3649375698083002347, @@ -104,9 +98,9 @@ void Runner() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "3:19-3:20|17328473273923617489|3|2", + "spell": "3:19-3:20|17328473273923617489|3|514", "extent": "3:15-3:20|17328473273923617489|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 253, "storage": 0 @@ -116,10 +110,10 @@ void Runner() { "qual_name_offset": 4, "short_name": "Foo", "declarations": [], - "spell": "2:7-2:10|11072669167287398027|2|2", + "spell": "2:7-2:10|11072669167287398027|2|514", "extent": "2:3-2:10|11072669167287398027|2|0", - "type": 17, - "uses": ["7:18-7:21|631910859630953711|3|4", "9:10-9:13|631910859630953711|3|4"], + "type": 53, + "uses": ["7:18-7:21|11072669167287398027|2|12", "9:10-9:13|11072669167287398027|2|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index a50ec0551..2463ce439 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -10,7 +10,7 @@ Foo &operator += (const Foo&, const int&); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3545323327609582678, "detailed_name": "void Foo::operator()(bool)", @@ -18,8 +18,8 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["3:8-3:18|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["3:8-3:16|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -32,8 +32,8 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["4:7-4:17|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["4:7-4:15|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -47,9 +47,9 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:18|15041163540773201510|2|2", + "spell": "2:8-2:16|15041163540773201510|2|514", "extent": "2:3-2:27|15041163540773201510|2|0", - "declaring_type": 15041163540773201510, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -62,7 +62,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator+=", "kind": 12, "storage": 0, - "declarations": ["7:6-7:17|0|1|1"], + "declarations": ["7:6-7:14|0|1|1"], "declaring_type": 0, "bases": [], "derived": [], @@ -72,8 +72,8 @@ Foo &operator += (const Foo&, const int&); }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 6bff6f6e5..f17ccd169 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -10,16 +10,16 @@ void Foo::Register(Manager* m) { OUTPUT: static_function_in_type.h { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, "detailed_name": "static void ns::Foo::Register(ns::Manager *)", "qual_name_offset": 12, "short_name": "Register", - "kind": 254, - "storage": 2, - "declarations": ["6:15-6:23|17262466801709381811|2|1"], - "declaring_type": 17262466801709381811, + "kind": 6, + "storage": 0, + "declarations": ["6:15-6:23|17262466801709381811|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -28,11 +28,11 @@ OUTPUT: static_function_in_type.h }], "usr2type": [{ "usr": 1972401196751872203, - "detailed_name": "ns::Manager", - "qual_name_offset": 0, + "detailed_name": "class ns::Manager", + "qual_name_offset": 6, "short_name": "Manager", "kind": 5, - "declarations": ["3:7-3:14|11072669167287398027|2|1"], + "declarations": ["3:7-3:14|11072669167287398027|2|513"], "alias_of": 0, "bases": [], "derived": [], @@ -40,47 +40,30 @@ OUTPUT: static_function_in_type.h "funcs": [], "vars": [], "instances": [], - "uses": ["6:24-6:31|0|1|4"] + "uses": ["6:24-6:31|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": [], - "spell": "1:11-1:13|0|1|2", - "extent": "1:1-9:2|0|1|0", - "alias_of": 0, - "bases": [13838176792705659279], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["1:11-1:13|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "declarations": ["1:11-1:13|0|1|1"], "alias_of": 0, "bases": [], - "derived": [11072669167287398027], - "types": [], + "derived": [], + "types": [1972401196751872203, 17262466801709381811], "funcs": [], "vars": [], "instances": [], "uses": [] }, { "usr": 17262466801709381811, - "detailed_name": "ns::Foo", - "qual_name_offset": 0, + "detailed_name": "struct ns::Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|11072669167287398027|2|2", + "spell": "5:8-5:11|11072669167287398027|2|514", "extent": "5:1-7:2|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -95,34 +78,31 @@ OUTPUT: static_function_in_type.h } OUTPUT: static_function_in_type.cc { - "includes": [{ - "line": 0, - "resolved_path": "&static_function_in_type.h" - }], - "skipped_by_preprocessor": [], + "includes": [], + "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "void ns::Foo::Register(ns::Manager *m)", - "qual_name_offset": 5, + "detailed_name": "static void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 12, "short_name": "Register", - "kind": 254, + "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:19|17262466801709381811|2|2", - "extent": "5:1-6:2|11072669167287398027|2|0", - "declaring_type": 17262466801709381811, + "spell": "5:11-5:19|17262466801709381811|2|514", + "extent": "6:3-6:33|17262466801709381811|2|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [13569879755236306838], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 1972401196751872203, - "detailed_name": "ns::Manager", - "qual_name_offset": 0, + "detailed_name": "class ns::Manager", + "qual_name_offset": 6, "short_name": "Manager", - "kind": 0, + "kind": 5, "declarations": [], "alias_of": 0, "bases": [], @@ -131,34 +111,17 @@ OUTPUT: static_function_in_type.cc "funcs": [], "vars": [], "instances": [13569879755236306838], - "uses": ["5:20-5:27|0|1|4"] + "uses": ["5:20-5:27|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": [], - "spell": "3:11-3:13|0|1|2", - "extent": "3:1-7:2|0|1|0", - "alias_of": 0, - "bases": [13838176792705659279], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["3:11-3:13|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "declarations": ["3:11-3:13|0|1|1"], "alias_of": 0, "bases": [], - "derived": [11072669167287398027], + "derived": [], "types": [], "funcs": [], "vars": [], @@ -166,10 +129,10 @@ OUTPUT: static_function_in_type.cc "uses": [] }, { "usr": 17262466801709381811, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, + "detailed_name": "struct ns::Foo {}", + "qual_name_offset": 7, + "short_name": "Foo", + "kind": 23, "declarations": [], "alias_of": 0, "bases": [], @@ -178,7 +141,7 @@ OUTPUT: static_function_in_type.cc "funcs": [17019747379608639279], "vars": [], "instances": [], - "uses": ["5:6-5:9|0|1|4"] + "uses": ["5:6-5:9|11072669167287398027|2|4"] }], "usr2var": [{ "usr": 13569879755236306838, @@ -186,7 +149,7 @@ OUTPUT: static_function_in_type.cc "qual_name_offset": 13, "short_name": "m", "declarations": [], - "spell": "5:29-5:30|17019747379608639279|3|2", + "spell": "5:29-5:30|17019747379608639279|3|514", "extent": "5:20-5:30|17019747379608639279|3|0", "type": 1972401196751872203, "uses": [], diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 5a123d894..9a2edd7d8 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -7,18 +7,18 @@ OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [], "usr2var": [{ - "usr": 11674328179498211370, + "usr": 14219599523415845943, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO", "declarations": [], "spell": "2:9-2:12|0|1|2", - "extent": "2:9-2:12|0|1|0", + "extent": "2:9-2:12|0|1|2", "type": 0, "uses": [], "kind": 255, diff --git a/index_tests/preprocessor/skipped.cc b/index_tests/preprocessor/skipped.cc index c4345e170..74577e1f9 100644 --- a/index_tests/preprocessor/skipped.cc +++ b/index_tests/preprocessor/skipped.cc @@ -17,7 +17,7 @@ void hello(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": ["2:1-4:7", "6:1-10:7", "12:1-14:7"], + "skipped_ranges": ["2:1-5:1", "6:1-11:1", "12:1-15:1"], "usr2func": [], "usr2type": [], "usr2var": [] diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index ce0a4953a..ab8af6b31 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -11,7 +11,7 @@ void Foo::Bar(Template&) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8412238651648388423, "detailed_name": "void Foo::Bar(Template &)", @@ -19,10 +19,10 @@ void Foo::Bar(Template&) {} "short_name": "Bar", "kind": 6, "storage": 0, - "declarations": ["5:8-5:11|15041163540773201510|2|1"], - "spell": "8:11-8:14|15041163540773201510|2|2", - "extent": "8:1-8:36|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["5:8-5:11|15041163540773201510|2|513"], + "spell": "8:11-8:14|15041163540773201510|2|514", + "extent": "5:3-5:30|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -31,8 +31,8 @@ void Foo::Bar(Template&) {} }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -48,8 +48,8 @@ void Foo::Bar(Template&) {} "uses": ["8:6-8:9|0|1|4"] }, { "usr": 17107291254533526269, - "detailed_name": "Template", - "qual_name_offset": 0, + "detailed_name": "class Template {}", + "qual_name_offset": 6, "short_name": "Template", "kind": 5, "declarations": [], diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 302086bfc..7ec48af76 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -18,10 +18,38 @@ namespace ns { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 11072669167287398027, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [12898699035586282159, 9008550860229740818], + "uses": [], + "callees": [] + }, { + "usr": 12688716854043726585, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [4731849186641714451, 4731849186641714451], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -37,12 +65,12 @@ namespace ns { "uses": [] }, { "usr": 1532099849728741556, - "detailed_name": "ns::VarType", - "qual_name_offset": 0, + "detailed_name": "enum ns::VarType {\n}", + "qual_name_offset": 5, "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "2:8-2:15|11072669167287398027|2|2", + "spell": "2:8-2:15|11072669167287398027|2|514", "extent": "2:3-2:18|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -50,95 +78,54 @@ namespace ns { "types": [], "funcs": [], "vars": [], - "instances": [4731849186641714451], - "uses": ["6:22-6:29|0|1|4", "6:44-6:51|0|1|4", "10:18-10:25|0|1|4"] - }, { - "usr": 2205716167465743256, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["10:33-10:34|0|1|4"] + "instances": [4731849186641714451, 4731849186641714451], + "uses": ["6:22-6:29|11072669167287398027|2|4", "6:44-6:51|11072669167287398027|2|4", "10:18-10:25|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": [], - "spell": "1:11-1:13|0|1|2", - "extent": "1:1-15:2|0|1|0", + "declarations": ["1:11-1:13|0|1|1"], "alias_of": 0, - "bases": [13838176792705659279], + "bases": [], "derived": [], - "types": [], + "types": [1532099849728741556, 12688716854043726585], "funcs": [], - "vars": [{ - "L": 12898699035586282159, - "R": -1 - }, { - "L": 9008550860229740818, - "R": -1 - }], + "vars": [], "instances": [], - "uses": ["1:11-1:13|0|1|4"] + "uses": [] }, { "usr": 12688716854043726585, - "detailed_name": "ns::Holder", - "qual_name_offset": 0, + "detailed_name": "struct ns::Holder {}", + "qual_name_offset": 7, "short_name": "Holder", - "kind": 5, + "kind": 23, "declarations": [], - "spell": "5:10-5:16|11072669167287398027|2|2", + "spell": "5:10-5:16|11072669167287398027|2|514", "extent": "5:3-7:4|11072669167287398027|2|0", "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], - "vars": [{ - "L": 4731849186641714451, - "R": -1 - }], - "instances": [], - "uses": ["10:26-10:32|0|1|4", "13:13-13:19|0|1|4", "14:14-14:20|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [11072669167287398027], - "types": [], - "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["10:26-10:32|11072669167287398027|2|4", "13:13-13:19|11072669167287398027|2|4", "14:14-14:20|11072669167287398027|2|4"] }], "usr2var": [{ "usr": 4731849186641714451, - "detailed_name": "const ns::VarType ns::Holder::static_var", - "qual_name_offset": 18, + "detailed_name": "static constexpr ns::VarType ns::Holder::static_var", + "qual_name_offset": 29, "short_name": "static_var", - "hover": "const ns::VarType ns::Holder::static_var = (VarType)0x0", - "declarations": ["6:30-6:40|12688716854043726585|2|1"], - "spell": "10:37-10:47|12688716854043726585|2|2", - "extent": "9:3-10:47|11072669167287398027|2|0", + "hover": "static constexpr ns::VarType ns::Holder::static_var = (ns::VarType)0", + "declarations": ["6:30-6:40|12688716854043726585|2|513"], + "spell": "10:37-10:47|12688716854043726585|2|514", + "extent": "6:5-6:55|12688716854043726585|2|0", "type": 1532099849728741556, - "uses": ["13:26-13:36|0|1|4", "14:27-14:37|0|1|4"], - "kind": 8, - "storage": 0 + "uses": ["13:26-13:36|12688716854043726585|2|12", "14:27-14:37|12688716854043726585|2|12"], + "kind": 13, + "storage": 2 }, { "usr": 9008550860229740818, "detailed_name": "int ns::Foo2", @@ -146,9 +133,9 @@ namespace ns { "short_name": "Foo2", "hover": "int ns::Foo2 = Holder::static_var", "declarations": [], - "spell": "14:7-14:11|11072669167287398027|2|2", + "spell": "14:7-14:11|11072669167287398027|2|514", "extent": "14:3-14:37|11072669167287398027|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -159,9 +146,9 @@ namespace ns { "short_name": "Foo", "hover": "int ns::Foo = Holder::static_var", "declarations": [], - "spell": "13:7-13:10|11072669167287398027|2|2", + "spell": "13:7-13:10|11072669167287398027|2|514", "extent": "13:3-13:36|11072669167287398027|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index 5e18a280a..f136e2539 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -24,7 +24,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 6875364467121018690, "detailed_name": "void foo()", @@ -41,6 +41,20 @@ void foo() { "vars": [], "uses": [], "callees": [] + }, { + "usr": 8402783583255987702, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [5866801090710377175], + "uses": [], + "callees": [] }, { "usr": 8905286151237717330, "detailed_name": "void C::bar()", @@ -48,8 +62,8 @@ void foo() { "short_name": "bar", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|8402783583255987702|2|1"], - "declaring_type": 8402783583255987702, + "declarations": ["4:8-4:11|8402783583255987702|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -58,10 +72,10 @@ void foo() { }], "usr2type": [{ "usr": 8402783583255987702, - "detailed_name": "C", - "qual_name_offset": 0, + "detailed_name": "struct C {}", + "qual_name_offset": 7, "short_name": "C", - "kind": 5, + "kind": 23, "declarations": [], "spell": "2:8-2:9|0|1|2", "extent": "2:1-5:2|0|1|0", @@ -76,23 +90,6 @@ void foo() { }], "instances": [], "uses": [] - }, { - "usr": 14750650276757822712, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "1:17-1:18|0|1|2", - "extent": "1:11-1:18|0|1|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["3:3-3:4|0|1|4"] }], "usr2var": [{ "usr": 5866801090710377175, @@ -100,7 +97,7 @@ void foo() { "qual_name_offset": 2, "short_name": "x", "declarations": [], - "spell": "3:5-3:6|8402783583255987702|2|2", + "spell": "3:5-3:6|8402783583255987702|2|514", "extent": "3:3-3:6|8402783583255987702|2|0", "type": 0, "uses": [], diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 63b81fd93..426d5be3f 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -15,26 +15,40 @@ namespace ns { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8221803074608342407, "detailed_name": "static int ns::Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 254, - "storage": 2, + "kind": 6, + "storage": 0, "declarations": [], - "spell": "5:16-5:19|14042997404480181958|2|2", + "spell": "5:16-5:19|14042997404480181958|2|514", "extent": "5:5-7:6|14042997404480181958|2|0", - "declaring_type": 14042997404480181958, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["10:21-10:24|11072669167287398027|2|32", "11:22-11:25|11072669167287398027|2|32"], + "uses": ["10:21-10:24|14042997404480181958|2|36", "11:22-11:25|14042997404480181958|2|36"], + "callees": [] + }, { + "usr": 11072669167287398027, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [15768138241775955040, 3182917058194750998], + "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -50,50 +64,27 @@ namespace ns { "uses": [] }, { "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": [], - "spell": "1:11-1:13|0|1|2", - "extent": "1:1-12:2|0|1|0", - "alias_of": 0, - "bases": [13838176792705659279], - "derived": [], - "types": [], - "funcs": [], - "vars": [{ - "L": 15768138241775955040, - "R": -1 - }, { - "L": 3182917058194750998, - "R": -1 - }], - "instances": [], - "uses": ["1:11-1:13|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], + "declarations": ["1:11-1:13|0|1|1"], "alias_of": 0, "bases": [], - "derived": [11072669167287398027], - "types": [], + "derived": [], + "types": [14042997404480181958], "funcs": [], "vars": [], "instances": [], "uses": [] }, { "usr": 14042997404480181958, - "detailed_name": "ns::Foo", - "qual_name_offset": 0, + "detailed_name": "struct ns::Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], - "spell": "3:10-3:13|11072669167287398027|2|2", + "spell": "3:10-3:13|11072669167287398027|2|514", "extent": "3:3-8:4|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -102,7 +93,7 @@ namespace ns { "funcs": [8221803074608342407], "vars": [], "instances": [], - "uses": ["10:11-10:14|0|1|4", "11:11-11:14|0|1|4"] + "uses": ["10:11-10:14|11072669167287398027|2|4", "11:11-11:14|11072669167287398027|2|4"] }], "usr2var": [{ "usr": 3182917058194750998, @@ -111,9 +102,9 @@ namespace ns { "short_name": "b", "hover": "int ns::b = Foo::foo()", "declarations": [], - "spell": "11:7-11:8|11072669167287398027|2|2", + "spell": "11:7-11:8|11072669167287398027|2|514", "extent": "11:3-11:35|11072669167287398027|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -124,9 +115,9 @@ namespace ns { "short_name": "a", "hover": "int ns::a = Foo::foo()", "declarations": [], - "spell": "10:7-10:8|11072669167287398027|2|2", + "spell": "10:7-10:8|11072669167287398027|2|514", "extent": "10:3-10:33|11072669167287398027|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 519372a41..fada88f9b 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -10,54 +10,45 @@ namespace ns { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ + "skipped_ranges": [], + "usr2func": [{ "usr": 11072669167287398027, - "detailed_name": "ns", - "qual_name_offset": 0, - "short_name": "ns", - "kind": 3, - "declarations": [], - "spell": "1:11-1:13|0|1|2", - "extent": "1:1-7:2|0|1|0", - "alias_of": 0, - "bases": [13838176792705659279], - "derived": [], - "types": [], - "funcs": [], - "vars": [{ - "L": 15768138241775955040, - "R": -1 - }, { - "L": 3182917058194750998, - "R": -1 - }], - "instances": [], - "uses": ["1:11-1:13|0|1|4"] - }, { - "usr": 13838176792705659279, "detailed_name": "", "qual_name_offset": 0, "short_name": "", "kind": 0, + "storage": 0, "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [15768138241775955040, 3182917058194750998], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 11072669167287398027, + "detailed_name": "namespace ns {\n}", + "qual_name_offset": 10, + "short_name": "ns", + "kind": 3, + "declarations": ["1:11-1:13|0|1|1"], "alias_of": 0, "bases": [], - "derived": [11072669167287398027], - "types": [], + "derived": [], + "types": [14042997404480181958], "funcs": [], "vars": [], "instances": [], "uses": [] }, { "usr": 14042997404480181958, - "detailed_name": "ns::Foo", - "qual_name_offset": 0, + "detailed_name": "class ns::Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|2", + "spell": "3:9-3:12|11072669167287398027|2|514", "extent": "3:3-3:15|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -66,15 +57,15 @@ namespace ns { "funcs": [], "vars": [], "instances": [15768138241775955040, 3182917058194750998], - "uses": ["5:3-5:6|0|1|4", "6:3-6:6|0|1|4"] + "uses": ["5:3-5:6|11072669167287398027|2|4", "6:3-6:6|11072669167287398027|2|4"] }], "usr2var": [{ "usr": 3182917058194750998, - "detailed_name": "Foo ns::b", - "qual_name_offset": 10, + "detailed_name": "Foo b", + "qual_name_offset": 4, "short_name": "b", "declarations": [], - "spell": "6:13-6:14|11072669167287398027|2|2", + "spell": "6:13-6:14|11072669167287398027|2|514", "extent": "6:3-6:14|11072669167287398027|2|0", "type": 14042997404480181958, "uses": [], @@ -86,7 +77,7 @@ namespace ns { "qual_name_offset": 9, "short_name": "a", "declarations": [], - "spell": "5:12-5:13|11072669167287398027|2|2", + "spell": "5:12-5:13|11072669167287398027|2|514", "extent": "5:3-5:13|11072669167287398027|2|0", "type": 14042997404480181958, "uses": [], diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 3e4d59f77..deca63d96 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -46,21 +46,49 @@ void foo(float Value); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ + "usr": 3861597222587452538, + "detailed_name": "template<> void foo(float Value)", + "qual_name_offset": 16, + "short_name": "foo", + "kind": 12, + "storage": 0, + "declarations": ["43:6-43:9|0|1|1"], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { "usr": 6113470698424012876, "detailed_name": "void vector >::clear()", - "qual_name_offset": 31, + "qual_name_offset": 5, "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["27:8-27:13|1663022413889915338|2|1"], - "declaring_type": 1663022413889915338, + "declarations": ["27:8-27:13|1663022413889915338|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], "callees": [] + }, { + "usr": 9201299975592934124, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [15477793821005285152, 4917621020431490070], + "uses": [], + "callees": [] }, { "usr": 17498190318698490707, "detailed_name": "void foo(T Value)", @@ -68,13 +96,13 @@ void foo(float Value); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["43:6-43:9|0|1|1"], + "declarations": [], "spell": "39:6-39:9|0|1|2", "extent": "39:1-39:21|0|1|0", "declaring_type": 0, "bases": [], "derived": [], - "vars": [17826688417349629938], + "vars": [], "uses": [], "callees": [] }, { @@ -84,8 +112,8 @@ void foo(float Value); "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["13:8-13:13|7440942986741176606|2|1"], - "declaring_type": 7440942986741176606, + "declarations": ["13:8-13:13|7440942986741176606|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -93,7 +121,7 @@ void foo(float Value); "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -107,27 +135,10 @@ void foo(float Value); "vars": [], "instances": [13914496963221806870], "uses": [] - }, { - "usr": 218068462278884837, - "detailed_name": "function", - "qual_name_offset": 0, - "short_name": "function", - "kind": 5, - "declarations": [], - "spell": "5:7-5:15|0|1|2", - "extent": "4:1-5:30|0|1|0", - "alias_of": 0, - "bases": [15019211479263750068], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [2933643612409209903], - "uses": ["7:1-7:9|0|1|4"] }, { "usr": 1663022413889915338, - "detailed_name": "vector", - "qual_name_offset": 0, + "detailed_name": "template<> class vector> {}", + "qual_name_offset": 17, "short_name": "vector", "kind": 5, "declarations": [], @@ -139,12 +150,12 @@ void foo(float Value); "types": [], "funcs": [6113470698424012876], "vars": [], - "instances": [], + "instances": [15931696253641284761], "uses": [] }, { "usr": 5760043510674081814, - "detailed_name": "Z1", - "qual_name_offset": 0, + "detailed_name": "struct Z1 {}", + "qual_name_offset": 7, "short_name": "Z1", "kind": 23, "declarations": [], @@ -158,61 +169,27 @@ void foo(float Value); "vars": [], "instances": [], "uses": ["32:8-32:10|0|1|4"] - }, { - "usr": 7143192229126273961, - "detailed_name": "Args", - "qual_name_offset": 0, - "short_name": "Args", - "kind": 26, - "declarations": [], - "spell": "4:34-4:38|0|1|2", - "extent": "4:22-4:38|0|1|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:18-5:22|0|1|4"] }, { "usr": 7440942986741176606, - "detailed_name": "vector", - "qual_name_offset": 0, + "detailed_name": "class vector {}", + "qual_name_offset": 6, "short_name": "vector", "kind": 5, - "declarations": ["17:7-17:13|0|1|4", "26:7-26:13|0|1|4"], + "declarations": [], "spell": "12:7-12:13|0|1|2", "extent": "12:1-14:2|0|1|0", "alias_of": 0, "bases": [], - "derived": [16155717907537731864, 1663022413889915338], + "derived": [1663022413889915338], "types": [], "funcs": [18107614608385228556], "vars": [], - "instances": [5792869548777559988, 3566687051827176322, 15931696253641284761], - "uses": ["30:1-30:7|0|1|4", "31:1-31:7|0|1|4", "32:1-32:7|0|1|4", "33:1-33:7|0|1|4"] - }, { - "usr": 8880262253425334092, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "16:19-16:20|0|1|2", - "extent": "16:10-16:20|0|1|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["17:14-17:15|0|1|4"] + "instances": [5792869548777559988, 86949563628772958, 3566687051827176322], + "uses": ["17:7-17:13|0|1|4", "26:7-26:13|0|1|4", "30:1-30:7|0|1|4", "31:1-31:7|0|1|4", "32:1-32:7|0|1|4", "33:1-33:7|0|1|4"] }, { "usr": 9201299975592934124, - "detailed_name": "Enum", - "qual_name_offset": 0, + "detailed_name": "enum Enum {\n}", + "qual_name_offset": 5, "short_name": "Enum", "kind": 10, "declarations": [], @@ -226,30 +203,13 @@ void foo(float Value); "vars": [], "instances": [], "uses": [] - }, { - "usr": 9673599782548740467, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "4:19-4:20|0|1|2", - "extent": "4:10-4:20|0|1|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:16-5:17|0|1|4"] }, { "usr": 10124869160135436852, - "detailed_name": "Z2", - "qual_name_offset": 0, + "detailed_name": "struct Z2 {}", + "qual_name_offset": 7, "short_name": "Z2", "kind": 23, - "declarations": ["26:14-26:16|0|1|4"], + "declarations": [], "spell": "23:8-23:10|0|1|2", "extent": "23:1-23:13|0|1|0", "alias_of": 0, @@ -259,48 +219,29 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["33:8-33:10|0|1|4"] - }, { - "usr": 14111105212951082474, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "38:20-38:21|17498190318698490707|3|2", - "extent": "38:11-38:21|17498190318698490707|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["39:10-39:11|0|1|4"] + "uses": ["26:14-26:16|0|1|4", "33:8-33:10|0|1|4"] }, { "usr": 15019211479263750068, - "detailed_name": "function", - "qual_name_offset": 0, + "detailed_name": "class function", + "qual_name_offset": 6, "short_name": "function", "kind": 5, - "declarations": ["2:7-2:15|0|1|1", "5:7-5:15|0|1|4"], - "spell": "2:7-2:15|0|1|2", - "extent": "1:1-2:15|0|1|0", + "declarations": ["2:7-2:15|0|1|1"], "alias_of": 0, "bases": [], - "derived": [218068462278884837], + "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["7:1-7:9|0|1|4"] + "instances": [2933643612409209903], + "uses": ["5:7-5:15|0|1|4", "7:1-7:9|0|1|4"] }, { "usr": 15695704394170757108, - "detailed_name": "allocator", - "qual_name_offset": 0, + "detailed_name": "class allocator", + "qual_name_offset": 6, "short_name": "allocator", "kind": 5, - "declarations": ["9:28-9:37|0|1|1", "11:39-11:48|0|1|4"], + "declarations": ["9:28-9:37|0|1|1"], "alias_of": 0, "bases": [], "derived": [], @@ -308,24 +249,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": [] - }, { - "usr": 16155717907537731864, - "detailed_name": "vector", - "qual_name_offset": 0, - "short_name": "vector", - "kind": 5, - "declarations": [], - "spell": "17:7-17:13|0|1|2", - "extent": "16:1-17:20|0|1|0", - "alias_of": 0, - "bases": [7440942986741176606], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [86949563628772958], - "uses": ["31:1-31:7|0|1|4"] + "uses": ["11:39-11:48|0|1|4"] }], "usr2var": [{ "usr": 86949563628772958, @@ -335,19 +259,19 @@ void foo(float Value); "declarations": [], "spell": "31:14-31:17|0|1|2", "extent": "31:1-31:17|0|1|0", - "type": 16155717907537731864, + "type": 7440942986741176606, "uses": [], "kind": 13, "storage": 0 }, { "usr": 2933643612409209903, "detailed_name": "function f", - "qual_name_offset": 21, + "qual_name_offset": 0, "short_name": "f", "declarations": [], "spell": "7:21-7:22|0|1|2", "extent": "7:1-7:22|0|1|0", - "type": 218068462278884837, + "type": 15019211479263750068, "uses": [], "kind": 13, "storage": 0 @@ -365,14 +289,14 @@ void foo(float Value); "storage": 0 }, { "usr": 4917621020431490070, - "detailed_name": "Enum::Enum1", + "detailed_name": "Enum1", "qual_name_offset": 0, "short_name": "Enum1", - "hover": "Enum::Enum1 = 1", + "hover": "Enum1 = 1", "declarations": [], - "spell": "36:10-36:15|9201299975592934124|2|2", + "spell": "36:10-36:15|9201299975592934124|2|514", "extent": "36:10-36:15|9201299975592934124|2|0", - "type": 9201299975592934124, + "type": 0, "uses": [], "kind": 22, "storage": 0 @@ -390,28 +314,28 @@ void foo(float Value); "storage": 0 }, { "usr": 13914496963221806870, - "detailed_name": "const int kOnst", - "qual_name_offset": 10, + "detailed_name": "static const int kOnst", + "qual_name_offset": 17, "short_name": "kOnst", - "hover": "const int kOnst = 7", + "hover": "static const int kOnst = 7", "declarations": [], "spell": "41:18-41:23|0|1|2", "extent": "41:1-41:27|0|1|0", - "type": 17, - "uses": ["43:27-43:32|0|1|4"], + "type": 53, + "uses": ["43:27-43:32|0|1|12"], "kind": 13, "storage": 2 }, { "usr": 15477793821005285152, - "detailed_name": "Enum::Enum0", + "detailed_name": "Enum0", "qual_name_offset": 0, "short_name": "Enum0", - "hover": "Enum::Enum0 = 0", + "hover": "Enum0 = 0", "declarations": [], - "spell": "36:3-36:8|9201299975592934124|2|2", + "spell": "36:3-36:8|9201299975592934124|2|514", "extent": "36:3-36:8|9201299975592934124|2|0", - "type": 9201299975592934124, - "uses": ["43:20-43:25|0|1|4"], + "type": 0, + "uses": ["43:20-43:25|9201299975592934124|2|4"], "kind": 22, "storage": 0 }, { @@ -422,7 +346,7 @@ void foo(float Value); "declarations": [], "spell": "33:12-33:15|0|1|2", "extent": "33:1-33:15|0|1|0", - "type": 7440942986741176606, + "type": 1663022413889915338, "uses": [], "kind": 13, "storage": 0 @@ -432,7 +356,7 @@ void foo(float Value); "qual_name_offset": 2, "short_name": "Value", "declarations": [], - "spell": "39:12-39:17|17498190318698490707|3|2", + "spell": "39:12-39:17|17498190318698490707|3|514", "extent": "39:10-39:17|17498190318698490707|3|0", "type": 0, "uses": [], diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index c9eaf9fb1..9e0fe0cb4 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -21,18 +21,34 @@ void Template::Foo() {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ + "usr": 6995843774014807426, + "detailed_name": "void Template::Foo()", + "qual_name_offset": 5, + "short_name": "Foo", + "kind": 6, + "storage": 0, + "declarations": [], + "spell": "10:22-10:25|17649312483543982122|2|514", + "extent": "3:3-3:13|17649312483543982122|2|0", + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": [] + }, { "usr": 11994188353303124840, - "detailed_name": "template void Template::Foo()", - "qual_name_offset": 24, + "detailed_name": "void Template::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|17107291254533526269|2|1", "10:22-10:25|0|1|1"], - "spell": "7:19-7:22|17107291254533526269|2|2", - "extent": "6:1-7:24|0|1|0", - "declaring_type": 17107291254533526269, + "declarations": ["3:8-3:11|17107291254533526269|2|513"], + "spell": "7:19-7:22|17107291254533526269|2|514", + "extent": "3:3-3:13|17107291254533526269|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -41,8 +57,8 @@ void Template::Foo() {} }], "usr2type": [{ "usr": 17107291254533526269, - "detailed_name": "Template", - "qual_name_offset": 0, + "detailed_name": "class Template {}", + "qual_name_offset": 6, "short_name": "Template", "kind": 5, "declarations": [], @@ -56,6 +72,21 @@ void Template::Foo() {} "vars": [], "instances": [], "uses": ["7:6-7:14|0|1|4", "10:6-10:14|0|1|4"] + }, { + "usr": 17649312483543982122, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [6995843774014807426], + "vars": [], + "instances": [], + "uses": [] }], "usr2var": [] } diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 0a109c29d..ea9f0bf04 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -12,26 +12,26 @@ int b = Foo::foo(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8340731781048851399, "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 254, - "storage": 2, + "kind": 6, + "storage": 0, "declarations": [], - "spell": "3:14-3:17|10528472276654770367|2|2", + "spell": "3:14-3:17|10528472276654770367|2|514", "extent": "3:3-5:4|10528472276654770367|2|0", - "declaring_type": 10528472276654770367, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:19-8:22|0|1|32", "9:20-9:23|0|1|32"], + "uses": ["8:19-8:22|10528472276654770367|2|36", "9:20-9:23|10528472276654770367|2|36"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -47,10 +47,10 @@ int b = Foo::foo(); "uses": [] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], "spell": "2:8-2:11|0|1|2", "extent": "2:1-6:2|0|1|0", @@ -72,7 +72,7 @@ int b = Foo::foo(); "declarations": [], "spell": "9:5-9:6|0|1|2", "extent": "9:1-9:25|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -85,7 +85,7 @@ int b = Foo::foo(); "declarations": [], "spell": "8:5-8:6|0|1|2", "extent": "8:1-8:24|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 034a54edf..52533cdd0 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -13,26 +13,26 @@ int b = Foo::foo(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9034026360701857235, "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 254, - "storage": 2, + "kind": 6, + "storage": 0, "declarations": [], - "spell": "4:14-4:17|10528472276654770367|2|2", + "spell": "4:14-4:17|10528472276654770367|2|514", "extent": "4:3-6:4|10528472276654770367|2|0", - "declaring_type": 10528472276654770367, + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["9:19-9:22|0|1|32", "10:20-10:23|0|1|32"], + "uses": ["9:19-9:22|10528472276654770367|2|36", "10:20-10:23|10528472276654770367|2|36"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -48,10 +48,10 @@ int b = Foo::foo(); "uses": [] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], "spell": "2:8-2:11|0|1|2", "extent": "2:1-7:2|0|1|0", @@ -73,7 +73,7 @@ int b = Foo::foo(); "declarations": [], "spell": "10:5-10:6|0|1|2", "extent": "10:1-10:33|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -86,7 +86,7 @@ int b = Foo::foo(); "declarations": [], "spell": "9:5-9:6|0|1|2", "extent": "9:1-9:31|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 15989f195..ddc6495ee 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -31,12 +31,12 @@ VarDecl b OUTPUT: { "includes": [], - "skipped_by_preprocessor": ["12:1-28:7"], + "skipped_ranges": ["12:1-29:1"], "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "A", - "qual_name_offset": 0, + "detailed_name": "enum A {\n}", + "qual_name_offset": 5, "short_name": "A", "kind": 10, "declarations": [], @@ -52,25 +52,25 @@ VarDecl b "uses": ["9:5-9:6|0|1|4"] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], "spell": "5:8-5:11|0|1|2", "extent": "5:1-7:2|0|1|0", "alias_of": 0, "bases": [], "derived": [], - "types": [], + "types": [13938528237873543349], "funcs": [], "vars": [], "instances": [], "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] }, { "usr": 13892793056005362145, - "detailed_name": "B", - "qual_name_offset": 0, + "detailed_name": "enum B {\n}", + "qual_name_offset": 5, "short_name": "B", "kind": 10, "declarations": [], @@ -86,12 +86,12 @@ VarDecl b "uses": ["10:5-10:6|0|1|4"] }, { "usr": 13938528237873543349, - "detailed_name": "Foo::Inner", - "qual_name_offset": 0, + "detailed_name": "struct Foo::Inner {}", + "qual_name_offset": 7, "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|2", + "spell": "6:10-6:15|10528472276654770367|2|514", "extent": "6:3-6:18|10528472276654770367|2|0", "alias_of": 0, "bases": [], @@ -100,7 +100,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [16721564935990383768, 12028309045033782423], - "uses": ["9:9-9:14|0|1|4", "10:9-10:14|0|1|4"] + "uses": ["9:9-9:14|10528472276654770367|2|4", "10:9-10:14|10528472276654770367|2|4"] }], "usr2var": [{ "usr": 12028309045033782423, diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index ab398ea8f..e6b7b4a6e 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -10,10 +10,24 @@ int b = Foo::var; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 10528472276654770367, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [13545144895171991916], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -29,10 +43,10 @@ int b = Foo::var; "uses": [] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": [], "spell": "2:8-2:11|0|1|2", "extent": "2:1-4:2|0|1|0", @@ -54,20 +68,20 @@ int b = Foo::var; "declarations": [], "spell": "7:5-7:6|0|1|2", "extent": "7:1-7:23|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 }, { "usr": 13545144895171991916, - "detailed_name": "const int Foo::var", - "qual_name_offset": 10, + "detailed_name": "static constexpr int Foo::var", + "qual_name_offset": 21, "short_name": "var", - "hover": "const int Foo::var = 3", - "declarations": ["3:24-3:27|10528472276654770367|2|1"], - "type": 17, - "uses": ["6:19-6:22|0|1|4", "7:20-7:23|0|1|4"], - "kind": 8, + "hover": "static constexpr int Foo::var = 3", + "declarations": ["3:24-3:27|10528472276654770367|2|513"], + "type": 53, + "uses": ["6:19-6:22|10528472276654770367|2|12", "7:20-7:23|10528472276654770367|2|12"], + "kind": 13, "storage": 2 }, { "usr": 16721564935990383768, @@ -78,7 +92,7 @@ int b = Foo::var; "declarations": [], "spell": "6:5-6:6|0|1|2", "extent": "6:1-6:22|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index 5e7722689..aa6b9d0b7 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -13,14 +13,14 @@ int b = foo(); OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 326583651986177228, "detailed_name": "static int foo()", "qual_name_offset": 11, "short_name": "foo", "kind": 12, - "storage": 2, + "storage": 0, "declarations": [], "spell": "2:12-2:15|0|1|2", "extent": "2:1-4:2|0|1|0", @@ -28,11 +28,11 @@ int b = foo(); "bases": [], "derived": [], "vars": [], - "uses": ["6:9-6:12|0|1|32", "7:9-7:12|0|1|32"], + "uses": ["6:9-6:12|0|1|36", "7:9-7:12|0|1|36"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -56,7 +56,7 @@ int b = foo(); "declarations": [], "spell": "7:5-7:6|0|1|2", "extent": "7:1-7:20|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 @@ -69,7 +69,7 @@ int b = foo(); "declarations": [], "spell": "6:5-6:6|0|1|2", "extent": "6:1-6:19|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 5eecc0044..c4dbcd5b4 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -8,12 +8,12 @@ Foo b; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -31,7 +31,7 @@ Foo b; "usr2var": [{ "usr": 12028309045033782423, "detailed_name": "Foo b", - "qual_name_offset": 10, + "qual_name_offset": 4, "short_name": "b", "declarations": [], "spell": "5:11-5:12|0|1|2", diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 61ee17ee3..f64125be3 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -34,12 +34,12 @@ UnexposedDecl var OUTPUT: { "includes": [], - "skipped_by_preprocessor": ["12:1-28:7"], + "skipped_ranges": ["12:1-29:1"], "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "A", - "qual_name_offset": 0, + "detailed_name": "enum A {\n}", + "qual_name_offset": 5, "short_name": "A", "kind": 10, "declarations": [], @@ -53,25 +53,10 @@ UnexposedDecl var "vars": [], "instances": [16721564935990383768], "uses": ["7:1-7:2|0|1|4", "7:11-7:12|0|1|4"] - }, { - "usr": 11919899838872947844, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:1-5:2|0|1|4", "5:9-5:10|0|1|4"] }, { "usr": 13892793056005362145, - "detailed_name": "B", - "qual_name_offset": 0, + "detailed_name": "enum B {\n}", + "qual_name_offset": 5, "short_name": "B", "kind": 10, "declarations": [], @@ -96,7 +81,7 @@ UnexposedDecl var "spell": "5:3-5:6|0|1|2", "extent": "5:1-5:12|0|1|0", "type": 0, - "uses": ["7:7-7:10|0|1|4", "8:7-8:10|0|1|4"], + "uses": ["7:7-7:10|0|1|12", "8:7-8:10|0|1|12"], "kind": 13, "storage": 0 }, { diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index b52a6ff76..56f38ebf2 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -7,10 +7,38 @@ union vector3 { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 1428566502523368801, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [3348817847649945564, 4821094820988543895, 15292551660437765731], + "uses": [], + "callees": [] + }, { + "usr": 17937907487590875128, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [1963212417280098348], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 21, + "usr": 82, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -22,16 +50,16 @@ union vector3 { "types": [], "funcs": [], "vars": [], - "instances": [3348817847649945564, 4821094820988543895, 15292551660437765731, 1963212417280098348], + "instances": [3348817847649945564, 4821094820988543895, 15292551660437765731], "uses": [] }, { "usr": 1428566502523368801, - "detailed_name": "vector3::(anon struct)", + "detailed_name": "struct {}", "qual_name_offset": 0, - "short_name": "(anon struct)", + "short_name": "", "kind": 23, "declarations": [], - "spell": "2:3-2:9|17937907487590875128|2|2", + "spell": "2:3-2:9|17937907487590875128|2|514", "extent": "2:3-2:28|17937907487590875128|2|0", "alias_of": 0, "bases": [], @@ -52,27 +80,21 @@ union vector3 { "uses": [] }, { "usr": 17937907487590875128, - "detailed_name": "vector3", - "qual_name_offset": 0, + "detailed_name": "union vector3 {}", + "qual_name_offset": 6, "short_name": "vector3", - "kind": 23, + "kind": 5, "declarations": [], "spell": "1:7-1:14|0|1|2", "extent": "1:1-4:2|0|1|0", "alias_of": 0, "bases": [], "derived": [], - "types": [], + "types": [1428566502523368801], "funcs": [], "vars": [{ - "L": 3348817847649945564, - "R": -1 - }, { - "L": 4821094820988543895, - "R": -1 - }, { - "L": 15292551660437765731, - "R": -1 + "L": 12549098950381705776, + "R": 0 }, { "L": 1963212417280098348, "R": 0 @@ -82,14 +104,13 @@ union vector3 { }], "usr2var": [{ "usr": 1963212417280098348, - "detailed_name": "float [3] vector3::v", - "qual_name_offset": 10, + "detailed_name": "float vector3::v[3]", + "qual_name_offset": 6, "short_name": "v", - "hover": "float [3] vector3::v[3]", "declarations": [], - "spell": "3:9-3:10|17937907487590875128|2|2", + "spell": "3:9-3:10|17937907487590875128|2|514", "extent": "3:3-3:13|17937907487590875128|2|0", - "type": 21, + "type": 0, "uses": [], "kind": 8, "storage": 0 @@ -99,9 +120,9 @@ union vector3 { "qual_name_offset": 6, "short_name": "x", "declarations": [], - "spell": "2:18-2:19|1428566502523368801|2|2", + "spell": "2:18-2:19|1428566502523368801|2|514", "extent": "2:12-2:19|1428566502523368801|2|0", - "type": 21, + "type": 82, "uses": [], "kind": 8, "storage": 0 @@ -111,9 +132,9 @@ union vector3 { "qual_name_offset": 6, "short_name": "y", "declarations": [], - "spell": "2:21-2:22|1428566502523368801|2|2", + "spell": "2:21-2:22|1428566502523368801|2|514", "extent": "2:12-2:22|1428566502523368801|2|0", - "type": 21, + "type": 82, "uses": [], "kind": 8, "storage": 0 @@ -123,9 +144,9 @@ union vector3 { "qual_name_offset": 6, "short_name": "z", "declarations": [], - "spell": "2:24-2:25|1428566502523368801|2|2", + "spell": "2:24-2:25|1428566502523368801|2|514", "extent": "2:12-2:25|1428566502523368801|2|0", - "type": 21, + "type": 82, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index 45abe03a3..96407a128 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -5,14 +5,14 @@ static func g; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8105378401105136463, "detailed_name": "static int g(const int *, const int *)", "qual_name_offset": 11, "short_name": "g", "kind": 12, - "storage": 2, + "storage": 0, "declarations": ["2:13-2:14|0|1|1"], "declaring_type": 0, "bases": [], @@ -23,29 +23,13 @@ static func g; }], "usr2type": [{ "usr": 10383876566159302459, - "detailed_name": "func", - "qual_name_offset": 0, + "detailed_name": "typedef int (func)(const int *, const int *)", + "qual_name_offset": 12, "short_name": "func", "kind": 252, - "hover": "typedef int (func)(const int *a, const int *b)", "declarations": [], "spell": "1:14-1:18|0|1|2", "extent": "1:1-1:47|0|1|0", - "alias_of": 13838176792705659279, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["1:14-1:18|0|1|4", "2:8-2:12|0|1|4"] - }, { - "usr": 13838176792705659279, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], "alias_of": 0, "bases": [], "derived": [], @@ -53,7 +37,7 @@ static func g; "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["2:8-2:12|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 87949e04b..3745475b2 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -7,10 +7,24 @@ union Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 8501689086387244262, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [9529311430721959843, 8804696910588009104], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 3, + "usr": 37, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -25,7 +39,7 @@ union Foo { "instances": [8804696910588009104], "uses": [] }, { - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -41,10 +55,10 @@ union Foo { "uses": [] }, { "usr": 8501689086387244262, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "union Foo {}", + "qual_name_offset": 6, "short_name": "Foo", - "kind": 23, + "kind": 5, "declarations": [], "spell": "1:7-1:10|0|1|2", "extent": "1:1-4:2|0|1|0", @@ -65,13 +79,13 @@ union Foo { }], "usr2var": [{ "usr": 8804696910588009104, - "detailed_name": "bool Foo::b", - "qual_name_offset": 5, + "detailed_name": "Foo::bool b", + "qual_name_offset": 0, "short_name": "b", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|2", + "spell": "3:8-3:9|8501689086387244262|2|514", "extent": "3:3-3:9|8501689086387244262|2|0", - "type": 3, + "type": 37, "uses": [], "kind": 8, "storage": 0 @@ -81,9 +95,9 @@ union Foo { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|2", + "spell": "2:7-2:8|8501689086387244262|2|514", "extent": "2:3-2:8|8501689086387244262|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index c856ca050..4b36fa873 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -15,8 +15,22 @@ void act(Foo*) { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ + "usr": 8501689086387244262, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [9529311430721959843, 8804696910588009104], + "uses": [], + "callees": [] + }, { "usr": 13982179977217945200, "detailed_name": "void act(Foo *)", "qual_name_offset": 5, @@ -34,7 +48,7 @@ void act(Foo*) { "callees": [] }], "usr2type": [{ - "usr": 3, + "usr": 37, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -49,7 +63,7 @@ void act(Foo*) { "instances": [8804696910588009104], "uses": [] }, { - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -65,10 +79,10 @@ void act(Foo*) { "uses": [] }, { "usr": 8501689086387244262, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "union Foo {}", + "qual_name_offset": 6, "short_name": "Foo", - "kind": 23, + "kind": 5, "declarations": [], "spell": "1:7-1:10|0|1|2", "extent": "1:1-4:2|0|1|0", @@ -96,33 +110,31 @@ void act(Foo*) { "spell": "6:5-6:6|0|1|2", "extent": "6:1-6:6|0|1|0", "type": 8501689086387244262, - "uses": ["9:3-9:4|13982179977217945200|3|4"], + "uses": ["9:3-9:4|0|1|4"], "kind": 13, "storage": 0 }, { "usr": 8804696910588009104, - "detailed_name": "bool Foo::b", - "qual_name_offset": 5, + "detailed_name": "Foo::bool b : 3", + "qual_name_offset": 0, "short_name": "b", - "hover": "bool Foo::b : 3", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|2", + "spell": "3:8-3:9|8501689086387244262|2|514", "extent": "3:3-3:13|8501689086387244262|2|0", - "type": 3, + "type": 37, "uses": [], "kind": 8, "storage": 0 }, { "usr": 9529311430721959843, - "detailed_name": "int Foo::a", + "detailed_name": "int Foo::a : 5", "qual_name_offset": 4, "short_name": "a", - "hover": "int Foo::a : 5", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|2", + "spell": "2:7-2:8|8501689086387244262|2|514", "extent": "2:3-2:12|8501689086387244262|2|0", - "type": 17, - "uses": ["9:5-9:6|13982179977217945200|3|4"], + "type": 53, + "uses": ["9:5-9:6|8501689086387244262|2|20"], "kind": 8, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 8213dac84..d109e087b 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -12,7 +12,7 @@ Foo::Foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", @@ -27,7 +27,7 @@ Foo::Foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|3385168158331140247|3|32"], + "uses": ["8:3-8:9|0|1|8228"], "callees": [] }, { "usr": 3385168158331140247, @@ -36,23 +36,23 @@ Foo::Foo() { "short_name": "Foo", "kind": 9, "storage": 0, - "declarations": ["4:3-4:6|15041163540773201510|2|1"], - "spell": "7:6-7:9|15041163540773201510|2|2", - "extent": "7:1-9:2|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["4:3-4:6|15041163540773201510|2|513"], + "spell": "7:6-7:9|15041163540773201510|2|514", + "extent": "4:3-4:8|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], "uses": [], - "callees": ["8:3-8:9|468307235068920063|3|32"] + "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["4:3-4:6|0|1|4", "7:6-7:9|0|1|4"], + "declarations": [], "spell": "3:8-3:11|0|1|2", "extent": "3:1-5:2|0|1|0", "alias_of": 0, @@ -62,7 +62,7 @@ Foo::Foo() { "funcs": [3385168158331140247], "vars": [], "instances": [], - "uses": ["4:3-4:6|15041163540773201510|2|4", "7:6-7:9|0|1|4", "7:1-7:4|0|1|4"] + "uses": ["4:3-4:6|0|1|4", "7:1-7:4|0|1|4", "7:6-7:9|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 819b679e5..45e3af74d 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -10,7 +10,7 @@ void caller() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 3787803219955606747, "detailed_name": "bool called(bool a, bool b)", @@ -23,7 +23,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|11404881820527069090|3|32"], + "uses": ["6:14-6:20|0|1|8228"], "callees": [] }, { "usr": 11404881820527069090, @@ -40,20 +40,20 @@ void caller() { "derived": [], "vars": [], "uses": [], - "callees": ["6:14-6:20|3787803219955606747|3|32"] + "callees": [] }], "usr2type": [], "usr2var": [{ - "usr": 1290746656694198202, + "usr": 16326993795872073150, "detailed_name": "MACRO_CALL", "qual_name_offset": 0, "short_name": "MACRO_CALL", - "hover": "#define MACRO_CALL(e) e", + "hover": "#define MACRO_CALL", "declarations": [], "spell": "1:9-1:19|0|1|2", - "extent": "1:9-1:24|0|1|0", + "extent": "1:9-1:19|0|1|2", "type": 0, - "uses": ["6:3-6:13|0|1|4"], + "uses": ["6:3-6:33|0|1|4"], "kind": 255, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index c1f3a38b2..9ca6b37a6 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -15,7 +15,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", @@ -28,7 +28,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|10177235824697315808|3|32"], + "uses": ["5:3-5:9|0|1|8228"], "callees": [] }, { "usr": 4259594751088586730, @@ -45,7 +45,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": ["9:3-9:9|10177235824697315808|3|32"] + "callees": [] }, { "usr": 10177235824697315808, "detailed_name": "void caller()", @@ -60,8 +60,8 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:3-9:9|4259594751088586730|3|32"], - "callees": ["5:3-5:9|468307235068920063|3|32"] + "uses": ["9:3-9:9|0|1|8228"], + "callees": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index a3a1b1c81..f4a075192 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -12,7 +12,7 @@ Wrapper caller() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 468307235068920063, "detailed_name": "int called()", @@ -27,7 +27,7 @@ Wrapper caller() { "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|11404881820527069090|3|32"], + "uses": ["8:10-8:16|0|1|8228"], "callees": [] }, { "usr": 10544127002917214589, @@ -36,12 +36,12 @@ Wrapper caller() { "short_name": "Wrapper", "kind": 9, "storage": 0, - "declarations": ["2:3-2:10|13611487872560323389|2|1"], - "declaring_type": 13611487872560323389, + "declarations": ["2:3-2:10|13611487872560323389|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:18|11404881820527069090|3|288"], + "uses": ["8:10-8:16|13611487872560323389|2|8228"], "callees": [] }, { "usr": 11404881820527069090, @@ -58,15 +58,15 @@ Wrapper caller() { "derived": [], "vars": [], "uses": [], - "callees": ["8:10-8:18|10544127002917214589|3|288", "8:10-8:16|468307235068920063|3|32"] + "callees": [] }], "usr2type": [{ "usr": 13611487872560323389, - "detailed_name": "Wrapper", - "qual_name_offset": 0, + "detailed_name": "struct Wrapper {}", + "qual_name_offset": 7, "short_name": "Wrapper", "kind": 23, - "declarations": ["2:3-2:10|0|1|4"], + "declarations": [], "spell": "1:8-1:15|0|1|2", "extent": "1:1-3:2|0|1|0", "alias_of": 0, @@ -76,7 +76,7 @@ Wrapper caller() { "funcs": [10544127002917214589], "vars": [], "instances": [], - "uses": ["2:3-2:10|13611487872560323389|2|4", "7:1-7:8|0|1|4"] + "uses": ["2:3-2:10|0|1|4", "7:1-7:8|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 19080a4c9..68dd2c212 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -11,7 +11,7 @@ void user() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 5264867802674151787, "detailed_name": "void used()", @@ -26,7 +26,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|32", "7:12-7:16|9376923949268137283|3|32"], + "uses": ["6:18-6:22|0|1|132", "7:12-7:16|0|1|132"], "callees": [] }, { "usr": 9376923949268137283, @@ -41,9 +41,9 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [16088407831770615719], + "vars": [], "uses": [], - "callees": ["6:18-6:22|5264867802674151787|3|32", "6:18-6:22|5264867802674151787|3|32", "7:3-7:10|12924914488846929470|3|32", "7:12-7:16|5264867802674151787|3|32"] + "callees": [] }, { "usr": 12924914488846929470, "detailed_name": "void consume(void (*)())", @@ -58,15 +58,16 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["7:3-7:10|9376923949268137283|3|32"], + "uses": ["7:3-7:10|0|1|8228"], "callees": [] }], "usr2type": [], "usr2var": [{ "usr": 16088407831770615719, - "detailed_name": "void (*)() x", - "qual_name_offset": 11, + "detailed_name": "void (*x)()", + "qual_name_offset": 7, "short_name": "x", + "hover": "void (*x)() = &used", "declarations": [], "spell": "6:10-6:11|9376923949268137283|3|2", "extent": "6:3-6:22|9376923949268137283|3|0", diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 7a33f6cb9..9c435a9a8 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -11,7 +11,7 @@ void user() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9376923949268137283, "detailed_name": "void user()", @@ -25,9 +25,9 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [4636142131003982569], + "vars": [], "uses": [], - "callees": ["6:18-6:22|18417145003926999463|3|32", "6:18-6:22|18417145003926999463|3|32"] + "callees": [] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", @@ -35,18 +35,18 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:12|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|32"], + "uses": ["6:18-6:22|15041163540773201510|2|132"], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -63,10 +63,10 @@ void user() { }], "usr2var": [{ "usr": 4636142131003982569, - "detailed_name": "void (Foo::*)() x", - "qual_name_offset": 16, + "detailed_name": "auto x", + "qual_name_offset": 5, "short_name": "x", - "hover": "void (Foo::*)() x = &Foo::Used", + "hover": "auto x = &Foo::Used", "declarations": [], "spell": "6:8-6:9|9376923949268137283|3|2", "extent": "6:3-6:22|9376923949268137283|3|0", diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 6c2db9e6b..b2c0e8967 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -7,7 +7,7 @@ void caller() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", @@ -22,7 +22,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["3:3-3:9|11404881820527069090|3|32"], + "uses": ["3:3-3:9|0|1|8228"], "callees": [] }, { "usr": 11404881820527069090, @@ -39,7 +39,7 @@ void caller() { "derived": [], "vars": [], "uses": [], - "callees": ["3:3-3:9|468307235068920063|3|32"] + "callees": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 842c3ec81..db90d666b 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -11,7 +11,7 @@ void user() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9376923949268137283, "detailed_name": "void user()", @@ -25,9 +25,9 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [14045150712868309451], + "vars": [], "uses": [], - "callees": ["7:6-7:10|18417145003926999463|3|32"] + "callees": [] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", @@ -35,18 +35,18 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:12|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:10|9376923949268137283|3|32"], + "uses": ["7:6-7:10|15041163540773201510|2|8228"], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -71,7 +71,7 @@ void user() { "spell": "6:8-6:9|9376923949268137283|3|2", "extent": "6:3-6:19|9376923949268137283|3|0", "type": 15041163540773201510, - "uses": ["7:3-7:4|9376923949268137283|3|4"], + "uses": ["7:3-7:4|9376923949268137283|3|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 291322b4a..45c77afce 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -10,14 +10,14 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9630503130605430498, "detailed_name": "static int helper()", "qual_name_offset": 11, "short_name": "helper", "kind": 12, - "storage": 2, + "storage": 0, "declarations": [], "spell": "1:12-1:18|0|1|2", "extent": "1:1-3:2|0|1|0", @@ -25,11 +25,25 @@ class Foo { "bases": [], "derived": [], "vars": [], - "uses": ["6:11-6:17|15041163540773201510|2|32"], + "uses": ["6:11-6:17|0|1|36"], + "callees": [] + }, { + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [4220150017963593039], + "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -45,8 +59,8 @@ class Foo { "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -71,9 +85,9 @@ class Foo { "short_name": "x", "hover": "int Foo::x = helper()", "declarations": [], - "spell": "6:7-6:8|15041163540773201510|2|2", + "spell": "6:7-6:8|15041163540773201510|2|514", "extent": "6:3-6:19|15041163540773201510|2|0", - "type": 17, + "type": 53, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index f082dc33b..bf7c7c5ad 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -7,7 +7,7 @@ void usage() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -20,7 +20,7 @@ void usage() { "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:6|6767773193109753523|3|32"], + "uses": ["4:3-4:6|0|1|8228"], "callees": [] }, { "usr": 6767773193109753523, @@ -37,7 +37,7 @@ void usage() { "derived": [], "vars": [], "uses": [], - "callees": ["4:3-4:6|4259594751088586730|3|32"] + "callees": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index ae5bf98ac..b00ff4fa8 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -10,7 +10,7 @@ void usage() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 6767773193109753523, "detailed_name": "void usage()", @@ -24,9 +24,9 @@ void usage() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [16229832321010999607], + "vars": [], "uses": [], - "callees": ["7:6-7:9|17922201480358737771|3|32"] + "callees": [] }, { "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", @@ -34,18 +34,18 @@ void usage() { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1"], - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:11|15041163540773201510|2|513"], + "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:9|6767773193109753523|3|32"], + "uses": ["7:6-7:9|15041163540773201510|2|8228"], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -70,7 +70,7 @@ void usage() { "spell": "6:8-6:9|6767773193109753523|3|2", "extent": "6:3-6:19|6767773193109753523|3|0", "type": 15041163540773201510, - "uses": ["7:3-7:4|6767773193109753523|3|4"], + "uses": ["7:3-7:4|6767773193109753523|3|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 48dcdfbdc..9be1e81a0 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -10,7 +10,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -26,7 +26,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": ["5:3-5:9|10585861037135727329|3|32", "6:3-6:9|10585861037135727329|3|32"] + "callees": [] }, { "usr": 10585861037135727329, "detailed_name": "void accept(T)", @@ -39,27 +39,10 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|4259594751088586730|3|32", "6:3-6:9|4259594751088586730|3|32"], + "uses": ["5:3-5:9|0|1|8228", "6:3-6:9|0|1|8228"], "callees": [] }], - "usr2type": [{ - "usr": 13420564603121289209, - "detailed_name": "T", - "qual_name_offset": 0, - "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "1:19-1:20|10585861037135727329|3|2", - "extent": "1:10-1:20|10585861037135727329|3|0", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["2:13-2:14|0|1|4"] - }], + "usr2type": [], "usr2var": [] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index bc6eb0aac..56da2161c 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -14,7 +14,7 @@ unique_ptr* return_type() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 16359708726068806331, "detailed_name": "unique_ptr *return_type()", @@ -28,14 +28,14 @@ unique_ptr* return_type() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [3364438781074774169], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 3286534761799572592, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, + "detailed_name": "class unique_ptr {}", + "qual_name_offset": 6, "short_name": "unique_ptr", "kind": 5, "declarations": [], @@ -51,8 +51,8 @@ unique_ptr* return_type() { "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|0|1|4"] }, { "usr": 4750332761459066907, - "detailed_name": "S", - "qual_name_offset": 0, + "detailed_name": "struct S {}", + "qual_name_offset": 7, "short_name": "S", "kind": 23, "declarations": [], @@ -81,8 +81,8 @@ unique_ptr* return_type() { "storage": 0 }, { "usr": 12857919739649552168, - "detailed_name": "unique_ptr f0", - "qual_name_offset": 17, + "detailed_name": "static unique_ptr f0", + "qual_name_offset": 24, "short_name": "f0", "declarations": [], "spell": "6:25-6:27|0|1|2", @@ -93,8 +93,8 @@ unique_ptr* return_type() { "storage": 2 }, { "usr": 18075066956054788088, - "detailed_name": "unique_ptr f1", - "qual_name_offset": 14, + "detailed_name": "static unique_ptr f1", + "qual_name_offset": 21, "short_name": "f1", "declarations": [], "spell": "7:22-7:24|0|1|2", diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 0236115c5..615d36a28 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -82,7 +82,7 @@ unique_ptr* Foo::foo() { return nullptr; } OUTPUT: { "includes": [], - "skipped_by_preprocessor": ["7:1-14:7", "17:1-32:7", "35:1-39:7", "42:1-52:7", "57:1-63:7", "68:1-78:7"], + "skipped_ranges": ["7:1-15:1", "17:1-33:1", "35:1-40:1", "42:1-53:1", "57:1-64:1", "68:1-79:1"], "usr2func": [{ "usr": 1246637699196435450, "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", @@ -122,10 +122,10 @@ unique_ptr* Foo::foo() { return nullptr; } "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["65:23-65:26|15041163540773201510|2|1"], - "spell": "79:26-79:29|15041163540773201510|2|2", - "extent": "79:1-79:51|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["65:23-65:26|15041163540773201510|2|513"], + "spell": "79:26-79:29|15041163540773201510|2|514", + "extent": "65:3-65:28|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -144,14 +144,14 @@ unique_ptr* Foo::foo() { return nullptr; } "declaring_type": 0, "bases": [], "derived": [], - "vars": [500112618220246], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 4310164820010458371, - "detailed_name": "S1", - "qual_name_offset": 0, + "detailed_name": "struct S1", + "qual_name_offset": 7, "short_name": "S1", "kind": 23, "declarations": ["4:8-4:10|0|1|1"], @@ -165,8 +165,8 @@ unique_ptr* Foo::foo() { return nullptr; } "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|0|1|4", "65:14-65:16|0|1|4", "79:12-79:14|0|1|4"] }, { "usr": 12728490517004312484, - "detailed_name": "S2", - "qual_name_offset": 0, + "detailed_name": "struct S2", + "qual_name_offset": 7, "short_name": "S2", "kind": 23, "declarations": ["5:8-5:10|0|1|1"], @@ -180,8 +180,8 @@ unique_ptr* Foo::foo() { return nullptr; } "uses": ["15:34-15:36|0|1|4", "15:39-15:41|0|1|4", "33:27-33:29|0|1|4", "33:32-33:34|0|1|4", "33:67-33:69|0|1|4", "54:29-54:31|0|1|4", "54:34-54:36|0|1|4", "65:18-65:20|0|1|4", "79:16-79:18|0|1|4"] }, { "usr": 14209198335088845323, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, + "detailed_name": "class unique_ptr", + "qual_name_offset": 6, "short_name": "unique_ptr", "kind": 5, "declarations": ["2:7-2:17|0|1|1"], @@ -195,8 +195,8 @@ unique_ptr* Foo::foo() { return nullptr; } "uses": ["15:8-15:18|0|1|4", "15:19-15:29|0|1|4", "33:1-33:11|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:3-54:13|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -225,8 +225,8 @@ unique_ptr* Foo::foo() { return nullptr; } "storage": 0 }, { "usr": 2933643612409209903, - "detailed_name": "unique_ptr, S2> f", - "qual_name_offset": 35, + "detailed_name": "extern unique_ptr, S2> f", + "qual_name_offset": 42, "short_name": "f", "declarations": ["15:43-15:44|0|1|1"], "type": 14209198335088845323, diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 7487a11eb..75aed976a 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -9,12 +9,12 @@ static unique_ptr foo; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 3286534761799572592, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, + "detailed_name": "class unique_ptr {}", + "qual_name_offset": 6, "short_name": "unique_ptr", "kind": 5, "declarations": [], @@ -30,8 +30,8 @@ static unique_ptr foo; "uses": ["6:8-6:18|0|1|4"] }, { "usr": 4750332761459066907, - "detailed_name": "S", - "qual_name_offset": 0, + "detailed_name": "struct S", + "qual_name_offset": 7, "short_name": "S", "kind": 23, "declarations": ["4:8-4:9|0|1|1"], @@ -46,8 +46,8 @@ static unique_ptr foo; }], "usr2var": [{ "usr": 3398408600781120939, - "detailed_name": "unique_ptr foo", - "qual_name_offset": 14, + "detailed_name": "static unique_ptr foo", + "qual_name_offset": 21, "short_name": "foo", "declarations": [], "spell": "6:22-6:25|0|1|2", diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index 813461cb4..f03978d73 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -5,12 +5,12 @@ extern T t; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 5673439900521455039, - "detailed_name": "T", - "qual_name_offset": 0, + "detailed_name": "struct T {}", + "qual_name_offset": 7, "short_name": "T", "kind": 23, "declarations": [], @@ -27,8 +27,8 @@ extern T t; }], "usr2var": [{ "usr": 1346710425945444872, - "detailed_name": "T t", - "qual_name_offset": 2, + "detailed_name": "extern T t", + "qual_name_offset": 0, "short_name": "t", "declarations": ["3:10-3:11|0|1|1"], "type": 5673439900521455039, diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index e24018323..87e2514df 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -10,12 +10,26 @@ struct Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [14314859014962085433, 14727441168849658842], + "uses": [], + "callees": [] + }], "usr2type": [{ "usr": 8508299082070213750, - "detailed_name": "ImplementedType", - "qual_name_offset": 0, + "detailed_name": "struct ImplementedType {}", + "qual_name_offset": 7, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -31,8 +45,8 @@ struct Foo { "uses": ["6:3-6:18|0|1|4"] }, { "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, + "detailed_name": "struct ForwardType", + "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|0|1|1"], @@ -46,8 +60,8 @@ struct Foo { "uses": ["5:3-5:14|0|1|4"] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -70,11 +84,11 @@ struct Foo { }], "usr2var": [{ "usr": 14314859014962085433, - "detailed_name": "ForwardType *Foo::a", - "qual_name_offset": 13, + "detailed_name": "ForwFoo::ardType *a", + "qual_name_offset": 0, "short_name": "a", "declarations": [], - "spell": "5:16-5:17|15041163540773201510|2|2", + "spell": "5:16-5:17|15041163540773201510|2|514", "extent": "5:3-5:17|15041163540773201510|2|0", "type": 13749354388332789217, "uses": [], @@ -86,7 +100,7 @@ struct Foo { "qual_name_offset": 16, "short_name": "b", "declarations": [], - "spell": "6:19-6:20|15041163540773201510|2|2", + "spell": "6:19-6:20|15041163540773201510|2|514", "extent": "6:3-6:20|15041163540773201510|2|0", "type": 8508299082070213750, "uses": [], diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 1a9218ed9..b4462a95e 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -10,7 +10,7 @@ void Foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4654328188330986029, "detailed_name": "void Foo()", @@ -24,14 +24,14 @@ void Foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [16374832544037266261, 2580122838476012357], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 8508299082070213750, - "detailed_name": "ImplementedType", - "qual_name_offset": 0, + "detailed_name": "struct ImplementedType {}", + "qual_name_offset": 7, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -47,8 +47,8 @@ void Foo() { "uses": ["6:3-6:18|0|1|4"] }, { "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, + "detailed_name": "struct ForwardType", + "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|0|1|1"], @@ -76,7 +76,7 @@ void Foo() { }, { "usr": 16374832544037266261, "detailed_name": "ForwardType *a", - "qual_name_offset": 13, + "qual_name_offset": 0, "short_name": "a", "declarations": [], "spell": "5:16-5:17|4654328188330986029|3|2", diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 3de9198f0..7ccd5eef8 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -7,7 +7,7 @@ void foo(ForwardType* f, ImplementedType a) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 1699390678058422036, "detailed_name": "void foo(ForwardType *f, ImplementedType a)", @@ -21,14 +21,14 @@ void foo(ForwardType* f, ImplementedType a) {} "declaring_type": 0, "bases": [], "derived": [], - "vars": [13058491096576226774, 11055777568039014776], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 8508299082070213750, - "detailed_name": "ImplementedType", - "qual_name_offset": 0, + "detailed_name": "struct ImplementedType {}", + "qual_name_offset": 7, "short_name": "ImplementedType", "kind": 23, "declarations": [], @@ -44,8 +44,8 @@ void foo(ForwardType* f, ImplementedType a) {} "uses": ["4:26-4:41|0|1|4"] }, { "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, + "detailed_name": "struct ForwardType", + "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|0|1|1"], @@ -64,7 +64,7 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 16, "short_name": "a", "declarations": [], - "spell": "4:42-4:43|1699390678058422036|3|2", + "spell": "4:42-4:43|1699390678058422036|3|514", "extent": "4:26-4:43|1699390678058422036|3|0", "type": 8508299082070213750, "uses": [], @@ -76,7 +76,7 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 13, "short_name": "f", "declarations": [], - "spell": "4:23-4:24|1699390678058422036|3|2", + "spell": "4:23-4:24|1699390678058422036|3|514", "extent": "4:10-4:24|1699390678058422036|3|0", "type": 13749354388332789217, "uses": [], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index e96b64182..36e88a1a6 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -12,7 +12,7 @@ void foo(Foo* f, Foo*) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8908726657907936744, "detailed_name": "void foo(Foo *f, Foo *)", @@ -22,18 +22,18 @@ void foo(Foo* f, Foo*) {} "storage": 0, "declarations": ["3:6-3:9|0|1|1"], "spell": "4:6-4:9|0|1|2", - "extent": "4:1-4:26|0|1|0", + "extent": "3:1-3:23|0|1|0", "declaring_type": 0, "bases": [], "derived": [], - "vars": [13823260660189154978], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|0|1|1"], @@ -52,7 +52,7 @@ void foo(Foo* f, Foo*) {} "qual_name_offset": 5, "short_name": "f", "declarations": [], - "spell": "4:15-4:16|8908726657907936744|3|2", + "spell": "4:15-4:16|8908726657907936744|3|514", "extent": "4:10-4:16|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index cc06d8a62..f9e6096d3 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -4,7 +4,7 @@ void foo(ForwardType*) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 15327735280790448926, "detailed_name": "void foo(ForwardType *)", @@ -24,8 +24,8 @@ void foo(ForwardType*) {} }], "usr2type": [{ "usr": 13749354388332789217, - "detailed_name": "ForwardType", - "qual_name_offset": 0, + "detailed_name": "struct ForwardType", + "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, "declarations": ["1:8-1:19|0|1|1"], diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 22c1bf592..df3b9b42a 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -10,7 +10,7 @@ void foo(Type& a0, const Type& a1) { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 16858540520096802573, "detailed_name": "void foo(Type &a0, const Type &a1)", @@ -24,14 +24,14 @@ void foo(Type& a0, const Type& a1) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, + "detailed_name": "struct Type {}", + "qual_name_offset": 7, "short_name": "Type", "kind": 23, "declarations": [], @@ -76,7 +76,7 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 6, "short_name": "a0", "declarations": [], - "spell": "3:16-3:18|16858540520096802573|3|2", + "spell": "3:16-3:18|16858540520096802573|3|514", "extent": "3:10-3:18|16858540520096802573|3|0", "type": 13487927231218873822, "uses": [], @@ -113,7 +113,7 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 12, "short_name": "a1", "declarations": [], - "spell": "3:32-3:34|16858540520096802573|3|2", + "spell": "3:32-3:34|16858540520096802573|3|514", "extent": "3:20-3:34|16858540520096802573|3|0", "type": 13487927231218873822, "uses": [], diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index d344aa6a9..55225b5e1 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -4,12 +4,12 @@ static Type t; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, + "detailed_name": "struct Type {}", + "qual_name_offset": 7, "short_name": "Type", "kind": 23, "declarations": [], @@ -26,8 +26,8 @@ static Type t; }], "usr2var": [{ "usr": 6601831367240627080, - "detailed_name": "Type t", - "qual_name_offset": 5, + "detailed_name": "static Type t", + "qual_name_offset": 0, "short_name": "t", "declarations": [], "spell": "2:13-2:14|0|1|2", diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 736caf8a8..3669d942d 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -21,7 +21,7 @@ static Type* bar() { return nullptr; } OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4240751906910175539, "detailed_name": "void Foo::Empty()", @@ -29,10 +29,10 @@ static Type* bar() { return nullptr; } "short_name": "Empty", "kind": 6, "storage": 0, - "declarations": ["9:8-9:13|15041163540773201510|2|1"], - "spell": "13:11-13:16|15041163540773201510|2|2", - "extent": "13:1-13:21|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["9:8-9:13|15041163540773201510|2|513"], + "spell": "13:11-13:16|15041163540773201510|2|514", + "extent": "9:3-9:15|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -47,7 +47,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "5:7-5:10|0|1|2", - "extent": "5:1-5:32|0|1|0", + "extent": "3:1-3:12|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -60,7 +60,7 @@ static Type* bar() { return nullptr; } "qual_name_offset": 19, "short_name": "external", "kind": 12, - "storage": 1, + "storage": 0, "declarations": ["15:20-15:28|0|1|1"], "declaring_type": 0, "bases": [], @@ -75,10 +75,10 @@ static Type* bar() { return nullptr; } "short_name": "Get", "kind": 6, "storage": 0, - "declarations": ["8:9-8:12|15041163540773201510|2|1"], - "spell": "12:12-12:15|15041163540773201510|2|2", - "extent": "12:1-12:40|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["8:9-8:12|15041163540773201510|2|513"], + "spell": "12:12-12:15|15041163540773201510|2|514", + "extent": "8:3-8:17|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -90,10 +90,10 @@ static Type* bar() { return nullptr; } "qual_name_offset": 13, "short_name": "bar", "kind": 12, - "storage": 2, + "storage": 0, "declarations": ["17:14-17:17|0|1|1"], "spell": "18:14-18:17|0|1|2", - "extent": "18:1-18:39|0|1|0", + "extent": "17:1-17:19|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -103,8 +103,8 @@ static Type* bar() { return nullptr; } }], "usr2type": [{ "usr": 13487927231218873822, - "detailed_name": "Type", - "qual_name_offset": 0, + "detailed_name": "struct Type", + "qual_name_offset": 7, "short_name": "Type", "kind": 23, "declarations": ["1:8-1:12|0|1|1"], @@ -118,8 +118,8 @@ static Type* bar() { return nullptr; } "uses": ["3:1-3:5|0|1|4", "4:1-4:5|0|1|4", "5:1-5:5|0|1|4", "8:3-8:7|0|1|4", "12:1-12:5|0|1|4", "15:14-15:18|0|1|4", "17:8-17:12|0|1|4", "18:8-18:12|0|1|4"] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index 02d1ebbbd..d3c6dc4ff 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -13,7 +13,7 @@ void accept3(Foo3*) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 558620830317390922, "detailed_name": "void accept1(Foo1 *)", @@ -80,27 +80,11 @@ void accept3(Foo3*) {} "callees": [] }], "usr2type": [{ - "usr": 17, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] - }, { "usr": 1544499294580512394, - "detailed_name": "Foo1", - "qual_name_offset": 0, + "detailed_name": "using Foo1 = Foo *", + "qual_name_offset": 6, "short_name": "Foo1", "kind": 252, - "hover": "using Foo1 = Foo*", "declarations": [], "spell": "2:7-2:11|0|1|2", "extent": "2:1-2:18|0|1|0", @@ -111,29 +95,28 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["2:7-2:11|0|1|4", "4:14-4:18|0|1|4", "8:14-8:18|0|1|4"] + "uses": ["4:14-4:18|0|1|4", "8:14-8:18|0|1|4"] }, { "usr": 2638219001294786365, - "detailed_name": "Foo4", - "qual_name_offset": 0, + "detailed_name": "using Foo4 = int", + "qual_name_offset": 6, "short_name": "Foo4", "kind": 252, - "hover": "using Foo4 = int", "declarations": [], "spell": "5:7-5:11|0|1|2", "extent": "5:1-5:17|0|1|0", - "alias_of": 17, + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["5:7-5:11|0|1|4"] + "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|0|1|1"], @@ -147,11 +130,10 @@ void accept3(Foo3*) {} "uses": ["2:14-2:17|0|1|4", "3:9-3:12|0|1|4", "7:13-7:16|0|1|4"] }, { "usr": 15466821155413653804, - "detailed_name": "Foo2", - "qual_name_offset": 0, + "detailed_name": "typedef Foo Foo2", + "qual_name_offset": 12, "short_name": "Foo2", "kind": 252, - "hover": "typedef Foo Foo2", "declarations": [], "spell": "3:13-3:17|0|1|2", "extent": "3:1-3:17|0|1|0", @@ -162,14 +144,13 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["3:13-3:17|0|1|4", "9:14-9:18|0|1|4"] + "uses": ["9:14-9:18|0|1|4"] }, { "usr": 17897026942631673064, - "detailed_name": "Foo3", - "qual_name_offset": 0, + "detailed_name": "using Foo3 = Foo1", + "qual_name_offset": 6, "short_name": "Foo3", "kind": 252, - "hover": "using Foo3 = Foo1", "declarations": [], "spell": "4:7-4:11|0|1|2", "extent": "4:1-4:18|0|1|0", @@ -180,7 +161,7 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["4:7-4:11|0|1|4", "10:14-10:18|0|1|4"] + "uses": ["10:14-10:18|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index 92b4f6b2d..457ed5874 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -8,32 +8,31 @@ typedef Foo Foo2; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ "usr": 1544499294580512394, - "detailed_name": "Foo1", - "qual_name_offset": 0, + "detailed_name": "using Foo1 = Foo", + "qual_name_offset": 6, "short_name": "Foo1", "kind": 252, - "hover": "using Foo1 = Foo", "declarations": [], "spell": "4:7-4:11|0|1|2", "extent": "4:1-4:22|0|1|0", - "alias_of": 10528472276654770367, + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["4:7-4:11|0|1|4", "5:13-5:17|0|1|4"] + "uses": ["5:13-5:17|0|1|4"] }, { "usr": 10528472276654770367, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo", + "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, + "kind": 23, "declarations": ["2:8-2:11|0|1|1"], "alias_of": 0, "bases": [], @@ -45,22 +44,21 @@ typedef Foo Foo2; "uses": ["4:14-4:17|0|1|4", "5:9-5:12|0|1|4"] }, { "usr": 15933698173231330933, - "detailed_name": "Foo2", - "qual_name_offset": 0, + "detailed_name": "typedef Foo Foo2", + "qual_name_offset": 18, "short_name": "Foo2", "kind": 252, - "hover": "typedef Foo Foo2", "declarations": [], "spell": "5:19-5:23|0|1|2", "extent": "5:1-5:23|0|1|0", - "alias_of": 10528472276654770367, + "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], "instances": [], - "uses": ["5:19-5:23|0|1|4"] + "uses": [] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index dc881608f..933027432 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -13,7 +13,7 @@ extern Foo foo; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 9488177941273031343, "detailed_name": "Foo *Foo::make()", @@ -21,20 +21,20 @@ extern Foo foo; "short_name": "make", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1"], - "spell": "5:11-5:15|15041163540773201510|2|2", - "extent": "5:1-8:2|0|1|0", - "declaring_type": 15041163540773201510, + "declarations": ["2:8-2:12|15041163540773201510|2|513"], + "spell": "5:11-5:15|15041163540773201510|2|514", + "extent": "2:3-2:14|15041163540773201510|2|0", + "declaring_type": 0, "bases": [], "derived": [], - "vars": [16380484338511689669], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -51,8 +51,8 @@ extern Foo foo; }], "usr2var": [{ "usr": 14455976355866885943, - "detailed_name": "Foo foo", - "qual_name_offset": 4, + "detailed_name": "extern Foo foo", + "qual_name_offset": 11, "short_name": "foo", "declarations": ["10:12-10:15|0|1|1"], "type": 15041163540773201510, diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 13229c6db..412d94c13 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -18,7 +18,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -32,9 +32,9 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [8039186520399841081], + "vars": [], "uses": [], - "callees": ["14:3-14:9|18319417758892371313|3|32", "14:14-14:17|11404602816585117695|3|32"] + "callees": [] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", @@ -47,7 +47,21 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:14-14:17|4259594751088586730|3|32"], + "uses": ["14:14-14:17|0|1|8228"], + "callees": [] + }, { + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [11489549839875479478, 9648311402855509901, 11489549839875479478], + "uses": [], "callees": [] }, { "usr": 18319417758892371313, @@ -61,11 +75,11 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|32"], + "uses": ["14:3-14:9|0|1|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -77,12 +91,12 @@ void foo() { "types": [], "funcs": [], "vars": [], - "instances": [11489549839875479478, 9648311402855509901, 8039186520399841081], + "instances": [11489549839875479478, 9648311402855509901, 11489549839875479478, 8039186520399841081], "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -96,9 +110,6 @@ void foo() { "vars": [{ "L": 9648311402855509901, "R": 0 - }, { - "L": 11489549839875479478, - "R": -1 }], "instances": [], "uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"] @@ -112,8 +123,8 @@ void foo() { "declarations": [], "spell": "13:7-13:8|4259594751088586730|3|2", "extent": "13:3-13:12|4259594751088586730|3|0", - "type": 17, - "uses": ["14:10-14:11|4259594751088586730|3|4"], + "type": 53, + "uses": ["14:10-14:11|4259594751088586730|3|12"], "kind": 13, "storage": 0 }, { @@ -122,25 +133,25 @@ void foo() { "qual_name_offset": 4, "short_name": "field_var", "declarations": [], - "spell": "7:7-7:16|15041163540773201510|2|2", + "spell": "7:7-7:16|15041163540773201510|2|514", "extent": "7:3-7:16|15041163540773201510|2|0", - "type": 17, - "uses": ["14:28-14:37|4259594751088586730|3|4"], + "type": 53, + "uses": ["14:28-14:37|15041163540773201510|2|12"], "kind": 8, "storage": 0 }, { "usr": 11489549839875479478, - "detailed_name": "int Foo::static_var", - "qual_name_offset": 4, + "detailed_name": "static int Foo::static_var", + "qual_name_offset": 11, "short_name": "static_var", "hover": "int Foo::static_var = 0", - "declarations": ["6:14-6:24|15041163540773201510|2|1"], - "spell": "10:10-10:20|15041163540773201510|2|2", - "extent": "10:1-10:24|0|1|0", - "type": 17, - "uses": ["14:45-14:55|4259594751088586730|3|4"], - "kind": 8, - "storage": 0 + "declarations": ["6:14-6:24|15041163540773201510|2|513"], + "spell": "10:10-10:20|15041163540773201510|2|514", + "extent": "6:3-6:24|15041163540773201510|2|0", + "type": 53, + "uses": ["14:45-14:55|15041163540773201510|2|12"], + "kind": 13, + "storage": 2 }] } */ diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 483cf69c8..0e84edd68 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -10,7 +10,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -26,7 +26,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": ["6:3-6:9|18319417758892371313|3|32", "6:10-6:13|11404602816585117695|3|32", "6:18-6:21|11404602816585117695|3|32"] + "callees": [] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", @@ -41,7 +41,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:10-6:13|4259594751088586730|3|32", "6:18-6:21|4259594751088586730|3|32"], + "uses": ["6:10-6:13|0|1|8228", "6:18-6:21|0|1|8228"], "callees": [] }, { "usr": 18319417758892371313, @@ -55,7 +55,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:9|4259594751088586730|3|32"], + "uses": ["6:3-6:9|0|1|8228"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 3e6eaeffd..10bb73fec 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -11,7 +11,7 @@ void caller() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 468307235068920063, "detailed_name": "void called()", @@ -26,7 +26,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["4:13-4:19|11404881820527069090|3|32", "7:3-7:9|11404881820527069090|3|32"], + "uses": ["4:13-4:19|0|1|132", "7:3-7:9|0|1|8228"], "callees": [] }, { "usr": 11404881820527069090, @@ -41,22 +41,22 @@ void caller() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [9121974011454213596], + "vars": [], "uses": [], - "callees": ["4:13-4:19|468307235068920063|3|32", "4:13-4:19|468307235068920063|3|32", "7:3-7:9|468307235068920063|3|32"] + "callees": [] }], "usr2type": [], "usr2var": [{ "usr": 9121974011454213596, - "detailed_name": "void (*)() x", - "qual_name_offset": 11, + "detailed_name": "auto x", + "qual_name_offset": 5, "short_name": "x", - "hover": "void (*)() x = &called", + "hover": "auto x = &called", "declarations": [], "spell": "4:8-4:9|11404881820527069090|3|2", "extent": "4:3-4:19|11404881820527069090|3|0", "type": 0, - "uses": ["5:3-5:4|11404881820527069090|3|4"], + "uses": ["5:3-5:4|11404881820527069090|3|8236"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index e8c6daffe..fae2ad3d0 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -21,7 +21,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -35,9 +35,9 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [14669930844300034456], + "vars": [], "uses": [], - "callees": ["14:3-14:9|17175780305784503374|3|32", "15:3-15:9|17175780305784503374|3|32", "16:3-16:9|12086644540399881766|3|32", "17:3-17:9|17175780305784503374|3|32"] + "callees": [] }, { "usr": 12086644540399881766, "detailed_name": "void accept(int *)", @@ -50,7 +50,21 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["16:3-16:9|4259594751088586730|3|32"], + "uses": ["16:3-16:9|0|1|8228"], + "callees": [] + }, { + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [4220150017963593039, 3873837747174060388], + "uses": [], "callees": [] }, { "usr": 17175780305784503374, @@ -64,11 +78,11 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|32", "15:3-15:9|4259594751088586730|3|32", "17:3-17:9|4259594751088586730|3|32"], + "uses": ["14:3-14:9|0|1|8228", "15:3-15:9|0|1|8228", "17:3-17:9|0|1|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -84,8 +98,8 @@ void foo() { "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -112,10 +126,10 @@ void foo() { "qual_name_offset": 4, "short_name": "y", "declarations": [], - "spell": "4:7-4:8|15041163540773201510|2|2", + "spell": "4:7-4:8|15041163540773201510|2|514", "extent": "4:3-4:8|15041163540773201510|2|0", - "type": 17, - "uses": ["17:12-17:13|4259594751088586730|3|4"], + "type": 53, + "uses": ["17:12-17:13|15041163540773201510|2|12"], "kind": 8, "storage": 0 }, { @@ -124,10 +138,10 @@ void foo() { "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "3:7-3:8|15041163540773201510|2|2", + "spell": "3:7-3:8|15041163540773201510|2|514", "extent": "3:3-3:8|15041163540773201510|2|0", - "type": 17, - "uses": ["12:5-12:6|4259594751088586730|3|4", "13:5-13:6|4259594751088586730|3|4", "14:12-14:13|4259594751088586730|3|4", "15:12-15:13|4259594751088586730|3|4", "16:13-16:14|4259594751088586730|3|4"], + "type": 53, + "uses": ["12:5-12:6|15041163540773201510|2|20", "13:5-13:6|15041163540773201510|2|4", "14:12-14:13|15041163540773201510|2|12", "15:12-15:13|15041163540773201510|2|12", "16:13-16:14|15041163540773201510|2|132"], "kind": 8, "storage": 0 }, { diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index d9d0b08cb..4dad3dd95 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -12,7 +12,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -28,7 +28,21 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": ["8:3-8:9|17175780305784503374|3|32"] + "callees": [] + }, { + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [8599782646965457351], + "uses": [], + "callees": [] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", @@ -41,11 +55,11 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|4259594751088586730|3|32"], + "uses": ["8:3-8:9|0|1|8228"], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -61,8 +75,8 @@ void foo() { "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo {}", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": [], @@ -79,13 +93,13 @@ void foo() { }], "usr2var": [{ "usr": 8599782646965457351, - "detailed_name": "int Foo::x", - "qual_name_offset": 4, + "detailed_name": "static int Foo::x", + "qual_name_offset": 11, "short_name": "x", - "declarations": ["2:14-2:15|15041163540773201510|2|1"], - "type": 17, - "uses": ["8:15-8:16|4259594751088586730|3|4"], - "kind": 8, + "declarations": ["2:14-2:15|15041163540773201510|2|513"], + "type": 53, + "uses": ["8:15-8:16|15041163540773201510|2|12"], + "kind": 13, "storage": 2 }] } diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 1d7a86cfe..18372325e 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -11,12 +11,26 @@ const VarType Holder::static_var; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 10028537921178202800, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [7057400933868440116, 7057400933868440116], + "uses": [], + "callees": [] + }], "usr2type": [{ "usr": 5792006888140599735, - "detailed_name": "VarType", - "qual_name_offset": 0, + "detailed_name": "enum VarType {\n}", + "qual_name_offset": 5, "short_name": "VarType", "kind": 10, "declarations": [], @@ -28,12 +42,12 @@ const VarType Holder::static_var; "types": [], "funcs": [], "vars": [], - "instances": [7057400933868440116], + "instances": [7057400933868440116, 7057400933868440116], "uses": ["4:20-4:27|0|1|4", "4:42-4:49|0|1|4", "7:7-7:14|0|1|4"] }, { "usr": 10028537921178202800, - "detailed_name": "Holder", - "qual_name_offset": 0, + "detailed_name": "struct Holder {}", + "qual_name_offset": 7, "short_name": "Holder", "kind": 23, "declarations": [], @@ -44,26 +58,23 @@ const VarType Holder::static_var; "derived": [], "types": [], "funcs": [], - "vars": [{ - "L": 7057400933868440116, - "R": -1 - }], + "vars": [], "instances": [], "uses": ["7:15-7:21|0|1|4"] }], "usr2var": [{ "usr": 7057400933868440116, - "detailed_name": "const VarType Holder::static_var", - "qual_name_offset": 14, + "detailed_name": "static constexpr VarType Holder::static_var", + "qual_name_offset": 25, "short_name": "static_var", - "hover": "const VarType Holder::static_var = (VarType)0x0", - "declarations": ["4:28-4:38|10028537921178202800|2|1"], - "spell": "7:23-7:33|10028537921178202800|2|2", - "extent": "7:1-7:33|0|1|0", + "hover": "static constexpr VarType Holder::static_var = (VarType)0", + "declarations": ["4:28-4:38|10028537921178202800|2|513"], + "spell": "7:23-7:33|10028537921178202800|2|514", + "extent": "4:3-4:53|10028537921178202800|2|0", "type": 5792006888140599735, "uses": [], - "kind": 8, - "storage": 0 + "kind": 13, + "storage": 2 }] } */ diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 894dcadc2..2dbbf1c28 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -7,7 +7,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -26,7 +26,7 @@ void foo() { "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -43,12 +43,12 @@ void foo() { }], "usr2var": [{ "usr": 16721564935990383768, - "detailed_name": "int a", - "qual_name_offset": 4, + "detailed_name": "extern int a", + "qual_name_offset": 11, "short_name": "a", "declarations": ["1:12-1:13|0|1|1"], - "type": 17, - "uses": ["4:3-4:4|4259594751088586730|3|4"], + "type": 53, + "uses": ["4:3-4:4|0|1|20"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 2b833d1aa..0a97cd9b1 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -5,7 +5,7 @@ void foo(int a) { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 11998306017310352355, "detailed_name": "void foo(int a)", @@ -19,12 +19,12 @@ void foo(int a) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [10063793875496522529], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -45,9 +45,9 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|2", + "spell": "1:14-1:15|11998306017310352355|3|514", "extent": "1:10-1:15|11998306017310352355|3|0", - "type": 17, + "type": 53, "uses": ["2:3-2:4|11998306017310352355|3|4"], "kind": 253, "storage": 0 diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 1843caba4..4eb8c8039 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -6,7 +6,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -20,12 +20,12 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [14014650769929566957], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -48,8 +48,8 @@ void foo() { "declarations": [], "spell": "2:7-2:8|4259594751088586730|3|2", "extent": "2:3-2:8|4259594751088586730|3|0", - "type": 17, - "uses": ["3:3-3:4|4259594751088586730|3|4"], + "type": 53, + "uses": ["3:3-3:4|4259594751088586730|3|20"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 11590ae2b..23e465f0b 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -11,7 +11,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -25,12 +25,12 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [13311055950748663970, 14036425367303419504], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -53,8 +53,8 @@ void foo() { "declarations": [], "spell": "2:7-2:8|4259594751088586730|3|2", "extent": "2:3-2:8|4259594751088586730|3|0", - "type": 17, - "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], + "type": 53, + "uses": ["3:3-3:4|4259594751088586730|3|20", "8:3-8:4|4259594751088586730|3|20"], "kind": 13, "storage": 0 }, { @@ -65,8 +65,8 @@ void foo() { "declarations": [], "spell": "5:9-5:10|4259594751088586730|3|2", "extent": "5:5-5:10|4259594751088586730|3|0", - "type": 17, - "uses": ["6:5-6:6|4259594751088586730|3|4"], + "type": 53, + "uses": ["6:5-6:6|4259594751088586730|3|20"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index e10ac0f1a..d94f26e56 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -11,7 +11,7 @@ void foo(int a) { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 11998306017310352355, "detailed_name": "void foo(int a)", @@ -25,12 +25,12 @@ void foo(int a) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [11608231465452906059, 6997229590862003559], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -53,8 +53,8 @@ void foo(int a) { "declarations": [], "spell": "4:9-4:10|11998306017310352355|3|2", "extent": "4:5-4:10|11998306017310352355|3|0", - "type": 17, - "uses": ["5:5-5:6|11998306017310352355|3|4"], + "type": 53, + "uses": ["5:5-5:6|11998306017310352355|3|20"], "kind": 13, "storage": 0 }, { @@ -63,10 +63,10 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|2", + "spell": "1:14-1:15|11998306017310352355|3|514", "extent": "1:10-1:15|11998306017310352355|3|0", - "type": 17, - "uses": ["2:3-2:4|11998306017310352355|3|4", "7:3-7:4|11998306017310352355|3|4"], + "type": 53, + "uses": ["2:3-2:4|11998306017310352355|3|20", "7:3-7:4|11998306017310352355|3|20"], "kind": 253, "storage": 0 }] diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 9b4661a97..aaee22260 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -8,7 +8,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -27,7 +27,7 @@ void foo() { "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -44,14 +44,14 @@ void foo() { }], "usr2var": [{ "usr": 11823161916242867318, - "detailed_name": "int a", - "qual_name_offset": 4, + "detailed_name": "static int a", + "qual_name_offset": 0, "short_name": "a", "declarations": [], "spell": "1:12-1:13|0|1|2", "extent": "1:1-1:13|0|1|0", - "type": 17, - "uses": ["4:3-4:4|4259594751088586730|3|4"], + "type": 53, + "uses": ["4:3-4:4|0|1|20"], "kind": 13, "storage": 2 }] diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 191c62cae..408ed5664 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -5,12 +5,26 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ + "skipped_ranges": [], + "usr2func": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", + "detailed_name": "", "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [13799811842374292251], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -34,7 +48,7 @@ class Foo { "qual_name_offset": 5, "short_name": "member", "declarations": [], - "spell": "2:8-2:14|15041163540773201510|2|2", + "spell": "2:8-2:14|15041163540773201510|2|514", "extent": "2:3-2:14|15041163540773201510|2|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 0dfb2dc9e..3e6689ce4 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -7,12 +7,26 @@ Foo* Foo::member = nullptr; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], - "usr2type": [{ + "skipped_ranges": [], + "usr2func": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", + "detailed_name": "", "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [5844987037615239736, 5844987037615239736], + "uses": [], + "callees": [] + }], + "usr2type": [{ + "usr": 15041163540773201510, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -23,26 +37,23 @@ Foo* Foo::member = nullptr; "derived": [], "types": [], "funcs": [], - "vars": [{ - "L": 5844987037615239736, - "R": -1 - }], - "instances": [5844987037615239736], + "vars": [], + "instances": [5844987037615239736, 5844987037615239736], "uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] }], "usr2var": [{ "usr": 5844987037615239736, - "detailed_name": "Foo *Foo::member", - "qual_name_offset": 5, + "detailed_name": "static Foo *Foo::member", + "qual_name_offset": 12, "short_name": "member", "hover": "Foo *Foo::member = nullptr", - "declarations": ["2:15-2:21|15041163540773201510|2|1"], - "spell": "4:11-4:17|15041163540773201510|2|2", - "extent": "4:1-4:27|0|1|0", + "declarations": ["2:15-2:21|15041163540773201510|2|513"], + "spell": "4:11-4:17|15041163540773201510|2|514", + "extent": "2:3-2:21|15041163540773201510|2|0", "type": 15041163540773201510, "uses": [], - "kind": 8, - "storage": 0 + "kind": 13, + "storage": 2 }] } */ diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index 61a741653..694d8bc9c 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -5,10 +5,24 @@ class Foo { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], - "usr2func": [], + "skipped_ranges": [], + "usr2func": [{ + "usr": 15041163540773201510, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [5844987037615239736], + "uses": [], + "callees": [] + }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -24,8 +38,8 @@ class Foo { "uses": [] }, { "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -42,13 +56,13 @@ class Foo { }], "usr2var": [{ "usr": 5844987037615239736, - "detailed_name": "int Foo::member", - "qual_name_offset": 4, + "detailed_name": "static int Foo::member", + "qual_name_offset": 11, "short_name": "member", - "declarations": ["2:14-2:20|15041163540773201510|2|1"], - "type": 17, + "declarations": ["2:14-2:20|15041163540773201510|2|513"], + "type": 53, "uses": [], - "kind": 8, + "kind": 13, "storage": 2 }] } diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index be3796f7b..9848e6e2c 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -8,7 +8,7 @@ void f() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 880549676430489861, "detailed_name": "void f()", @@ -22,14 +22,14 @@ void f() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [10601729374837386290, 18422884837902130475], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "class Foo {}", + "qual_name_offset": 6, "short_name": "Foo", "kind": 5, "declarations": [], @@ -41,28 +41,28 @@ void f() { "types": [], "funcs": [], "vars": [], - "instances": [10601729374837386290, 18422884837902130475], + "instances": [18422884837902130475], "uses": ["3:16-3:19|0|1|4", "4:17-4:20|0|1|4"] }], "usr2var": [{ "usr": 10601729374837386290, - "detailed_name": "Foo *x", + "detailed_name": "auto x", "qual_name_offset": 5, "short_name": "x", - "hover": "Foo *x = new Foo()", + "hover": "auto x = new Foo()", "declarations": [], "spell": "3:8-3:9|880549676430489861|3|2", "extent": "3:3-3:21|880549676430489861|3|0", - "type": 15041163540773201510, + "type": 0, "uses": [], "kind": 13, "storage": 0 }, { "usr": 18422884837902130475, - "detailed_name": "Foo *y", - "qual_name_offset": 5, + "detailed_name": "auto *y", + "qual_name_offset": 6, "short_name": "y", - "hover": "Foo *y = new Foo()", + "hover": "auto *y = new Foo()", "declarations": [], "spell": "4:9-4:10|880549676430489861|3|2", "extent": "4:3-4:22|880549676430489861|3|0", diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index d68ab3820..dd9b4cf9b 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -8,7 +8,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -22,14 +22,14 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [13198746475679542317], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|0|1|1"], diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index ca65c7d34..2e27fe010 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -6,7 +6,7 @@ void foo(Foo* p0, Foo* p1) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 8908726657907936744, "detailed_name": "void foo(Foo *p0, Foo *p1)", @@ -20,14 +20,14 @@ void foo(Foo* p0, Foo* p1) {} "declaring_type": 0, "bases": [], "derived": [], - "vars": [8730439006497971620, 2525014371090380500], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 15041163540773201510, - "detailed_name": "Foo", - "qual_name_offset": 0, + "detailed_name": "struct Foo", + "qual_name_offset": 7, "short_name": "Foo", "kind": 23, "declarations": ["1:8-1:11|0|1|1"], @@ -46,7 +46,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p1", "declarations": [], - "spell": "3:24-3:26|8908726657907936744|3|2", + "spell": "3:24-3:26|8908726657907936744|3|514", "extent": "3:19-3:26|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], @@ -58,7 +58,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p0", "declarations": [], - "spell": "3:15-3:17|8908726657907936744|3|2", + "spell": "3:15-3:17|8908726657907936744|3|514", "extent": "3:10-3:17|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index c63782085..99b79d879 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -3,7 +3,7 @@ void foo(int, int) {} OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 2747674671862363334, "detailed_name": "void foo(int, int)", diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index e56738091..38e22362f 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -11,7 +11,7 @@ void foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -25,12 +25,12 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [1894874819807168345, 4508045017817092115], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -53,8 +53,8 @@ void foo() { "declarations": [], "spell": "2:7-2:8|4259594751088586730|3|2", "extent": "2:3-2:8|4259594751088586730|3|0", - "type": 17, - "uses": ["3:3-3:4|4259594751088586730|3|4", "8:3-8:4|4259594751088586730|3|4"], + "type": 53, + "uses": ["3:3-3:4|4259594751088586730|3|20", "8:3-8:4|4259594751088586730|3|20"], "kind": 13, "storage": 0 }, { @@ -65,8 +65,8 @@ void foo() { "declarations": [], "spell": "5:9-5:10|4259594751088586730|3|2", "extent": "5:5-5:10|4259594751088586730|3|0", - "type": 17, - "uses": ["6:5-6:6|4259594751088586730|3|4"], + "type": 53, + "uses": ["6:5-6:6|4259594751088586730|3|20"], "kind": 13, "storage": 0 }] diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index 7aac0a2c2..ecfdec495 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -5,7 +5,7 @@ void foo(int p) { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 11998306017310352355, "detailed_name": "void foo(int p)", @@ -19,12 +19,12 @@ void foo(int p) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [5875271969926422921, 11404600766177939811], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -45,9 +45,9 @@ void foo(int p) { "qual_name_offset": 4, "short_name": "p", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|2", + "spell": "1:14-1:15|11998306017310352355|3|514", "extent": "1:10-1:15|11998306017310352355|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 253, "storage": 0 @@ -60,7 +60,7 @@ void foo(int p) { "declarations": [], "spell": "2:9-2:10|11998306017310352355|3|2", "extent": "2:5-2:14|11998306017310352355|3|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index 24f01ca44..c76dd406a 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -3,10 +3,10 @@ static int global = 0; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -23,14 +23,14 @@ static int global = 0; }], "usr2var": [{ "usr": 6834525061342585382, - "detailed_name": "int global", - "qual_name_offset": 4, + "detailed_name": "static int global", + "qual_name_offset": 11, "short_name": "global", - "hover": "int global = 0", + "hover": "static int global = 0", "declarations": [], "spell": "1:12-1:18|0|1|2", "extent": "1:1-1:22|0|1|0", - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index a7d883724..8ca10b9ec 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -3,10 +3,10 @@ extern int global; OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [], "usr2type": [{ - "usr": 17, + "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -23,11 +23,11 @@ extern int global; }], "usr2var": [{ "usr": 9937941849651546906, - "detailed_name": "int global", - "qual_name_offset": 4, + "detailed_name": "extern int global", + "qual_name_offset": 11, "short_name": "global", "declarations": ["1:12-1:18|0|1|1"], - "type": 17, + "type": 53, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 055024e1d..50004c7f3 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -10,7 +10,7 @@ void Foo() { OUTPUT: { "includes": [], - "skipped_by_preprocessor": [], + "skipped_ranges": [], "usr2func": [{ "usr": 4654328188330986029, "detailed_name": "void Foo()", @@ -24,14 +24,14 @@ void Foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [6975456769752895964], + "vars": [], "uses": [], "callees": [] }], "usr2type": [{ "usr": 4750332761459066907, - "detailed_name": "S", - "qual_name_offset": 0, + "detailed_name": "struct S {}", + "qual_name_offset": 7, "short_name": "S", "kind": 23, "declarations": [], @@ -47,11 +47,10 @@ void Foo() { "uses": ["2:11-2:12|0|1|4"] }, { "usr": 7434820806199665424, - "detailed_name": "F", - "qual_name_offset": 0, + "detailed_name": "using F = S", + "qual_name_offset": 6, "short_name": "F", "kind": 252, - "hover": "using F = S", "declarations": [], "spell": "2:7-2:8|0|1|2", "extent": "2:1-2:12|0|1|0", @@ -62,7 +61,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [6975456769752895964], - "uses": ["2:7-2:8|0|1|4", "4:3-4:4|0|1|4"] + "uses": ["4:3-4:4|0|1|4"] }], "usr2var": [{ "usr": 6975456769752895964, diff --git a/src/file_consumer.cc b/src/file_consumer.cc index b32a8ed59..928d36b52 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -95,25 +95,16 @@ FileConsumer::FileConsumer(VFS* vfs, const std::string& parse_file) IndexFile* FileConsumer::TryConsumeFile( const clang::FileEntry& File, std::unordered_map* file_contents_map) { - std::string file_name = FileName(File); - if (!File.isValid()) { - if (!file_name.empty()) { - LOG_S(ERROR) << "Could not get unique file id for " << file_name - << " when parsing " << parse_file_; - } - return nullptr; - } - - // Try to find cached local result. - unsigned UID = File.getUID(); - auto it = local_.find(UID); + auto UniqueID = File.getUniqueID(); + auto it = local_.find(UniqueID); if (it != local_.end()) return it->second.get(); + std::string file_name = FileName(File); // We did not take the file from global. Cache that we failed so we don't try // again and return nullptr. if (!vfs_->Mark(file_name, thread_id_, 2)) { - local_[UID] = nullptr; + local_[UniqueID] = nullptr; return nullptr; } @@ -124,8 +115,8 @@ IndexFile* FileConsumer::TryConsumeFile( return nullptr; // Build IndexFile instance. - local_[UID] = std::make_unique(UID, file_name, *contents); - return local_[UID].get(); + local_[UniqueID] = std::make_unique(UniqueID, file_name, *contents); + return local_[UniqueID].get(); } std::vector> FileConsumer::TakeLocalState() { diff --git a/src/file_consumer.h b/src/file_consumer.h index 0697f3b9a..5fb8e2601 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -8,8 +8,8 @@ #include #include +#include #include -#include #include struct IndexFile; @@ -66,7 +66,7 @@ struct FileConsumer { std::vector> TakeLocalState(); private: - std::unordered_map> local_; + std::map> local_; VFS* vfs_; std::string parse_file_; int thread_id_; diff --git a/src/indexer.cc b/src/indexer.cc index 2c9a29ac3..5bb2056a9 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -23,16 +23,17 @@ using llvm::Timer; #include #include #include +#include #include #include namespace { struct IndexParam { - llvm::DenseSet SeenUID; - std::vector seen_files; + std::map SeenUniqueID; std::unordered_map file_contents; std::unordered_map file2write_time; + llvm::DenseMap Decl2usr; // Only use this when strictly needed (ie, primary translation unit is // needed). Most logic should get the IndexFile instance via @@ -43,39 +44,42 @@ struct IndexParam { IndexFile* primary_file = nullptr; ASTUnit& Unit; + ASTContext* Ctx; FileConsumer* file_consumer = nullptr; NamespaceHelper ns; IndexParam(ASTUnit& Unit, FileConsumer* file_consumer) : Unit(Unit), file_consumer(file_consumer) {} -}; -IndexFile *ConsumeFile(IndexParam ¶m, const FileEntry &File) { - IndexFile *db = - param.file_consumer->TryConsumeFile(File, ¶m.file_contents); - - // If this is the first time we have seen the file (ignoring if we are - // generating an index for it): - if (param.SeenUID.insert(File.getUID()).second) { - std::string file_name = FileName(File); - // Add to all files we have seen so we can generate proper dependency - // graph. - param.seen_files.push_back(file_name); - - // Set modification time. - std::optional write_time = LastWriteTime(file_name); - LOG_IF_S(ERROR, !write_time) + IndexFile *ConsumeFile(const FileEntry &File) { + IndexFile *db = + file_consumer->TryConsumeFile(File, &file_contents); + + // If this is the first time we have seen the file (ignoring if we are + // generating an index for it): + auto it = SeenUniqueID.try_emplace(File.getUniqueID()); + if (it.second) { + std::string file_name = FileName(File); + // Add to all files we have seen so we can generate proper dependency + // graph. + it.first->second = file_name; + + // Set modification time. + std::optional write_time = LastWriteTime(file_name); + LOG_IF_S(ERROR, !write_time) << "failed to fetch write time for " << file_name; - if (write_time) - param.file2write_time[file_name] = *write_time; - } + if (write_time) + file2write_time[file_name] = *write_time; + } - return db; -} + return db; + } +}; Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, unsigned *UID, bool token) { + SourceRange R, llvm::sys::fs::UniqueID *UniqueID, + bool token) { SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); std::pair BInfo = SM.getDecomposedLoc(BLoc); std::pair EInfo = SM.getDecomposedLoc(ELoc); @@ -89,38 +93,29 @@ Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, if (c0 > INT16_MAX) c0 = 0; if (l1 > INT16_MAX) l1 = 0; if (c1 > INT16_MAX) c1 = 0; - if (UID) { + if (UniqueID) { if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) - *UID = F->getUID(); + *UniqueID = F->getUniqueID(); else - *UID = 0; + *UniqueID = llvm::sys::fs::UniqueID(0, 0); } return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}}; } Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R) { - return FromSourceRange(SM, LangOpts, R, nullptr, false); + SourceRange R, + llvm::sys::fs::UniqueID *UniqueID = nullptr) { + return FromSourceRange(SM, LangOpts, R, UniqueID, false); } Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, unsigned *UID = nullptr) { - return FromSourceRange(SM, LangOpts, R, UID, true); -} - -Position ResolveSourceLocation(const SourceManager &SM, SourceLocation Loc, - FileID *F = nullptr) { - std::pair D = SM.getDecomposedLoc(Loc); - if (F) - *F = D.first; - unsigned line = SM.getLineNumber(D.first, D.second) - 1; - unsigned col = SM.getColumnNumber(D.first, D.second) - 1; - return {int16_t(line > INT16_MAX ? 0 : line), - int16_t(col > INT16_MAX ? 0 : col)}; + SourceRange R, + llvm::sys::fs::UniqueID *UniqueID = nullptr) { + return FromSourceRange(SM, LangOpts, R, UniqueID, true); } -SymbolKind GetSymbolKind(const Decl& D) { - switch (D.getKind()) { +SymbolKind GetSymbolKind(const Decl* D) { + switch (D->getKind()) { case Decl::TranslationUnit: return SymbolKind::File; case Decl::FunctionTemplate: @@ -137,6 +132,7 @@ SymbolKind GetSymbolKind(const Decl& D) { case Decl::Enum: case Decl::Record: case Decl::CXXRecord: + case Decl::ClassTemplateSpecialization: case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: @@ -157,6 +153,7 @@ const Decl* GetTypeDecl(QualType T) { Decl *D = nullptr; const Type *TP; for(;;) { + T = T.getUnqualifiedType(); TP = T.getTypePtrOrNull(); if (!TP) return D; @@ -266,9 +263,9 @@ const Decl* GetSpecialized(const Decl* D) { } class IndexDataConsumer : public index::IndexDataConsumer { +public: ASTContext *Ctx; IndexParam& param; - llvm::DenseMap Decl2usr; std::string GetComment(const Decl* D) { SourceManager &SM = Ctx->getSourceManager(); @@ -325,92 +322,119 @@ class IndexDataConsumer : public index::IndexDataConsumer { return ret; } - Usr GetUsr(const Decl* D) { + Usr GetUsr(const Decl* D) const { D = D->getCanonicalDecl(); - auto R = Decl2usr.try_emplace(D); + auto R = param.Decl2usr.try_emplace(D); if (R.second) { SmallString<256> USR; index::generateUSRForDecl(D, USR); - R.first->second = HashUsr({USR.data(), USR.size()}); + R.first->second = HashUsr(USR); } return R.first->second; } - template - void SetName(const Decl *D, std::string_view short_name, - std::string_view qualified, Def &def, - PrintingPolicy *Policy = nullptr) { - SmallString<256> Str; - llvm::raw_svector_ostream OS(Str); - if (Policy) { - D->print(OS, *Policy); - } else { - PrintingPolicy PP(Ctx->getLangOpts()); - PP.AnonymousTagLocations = false; - PP.TerseOutput = true; - // PP.PolishForDeclaration = true; - PP.ConstantsAsWritten = true; - PP.SuppressTagKeyword = false; - PP.FullyQualifiedName = false; - D->print(OS, PP); + Use GetUse(IndexFile *db, Range range, const DeclContext *DC, + Role role) const { + if (!DC) + return Use{{range, 0, SymbolKind::File, role}}; + const Decl *D = cast(DC); + switch (GetSymbolKind(D)) { + case SymbolKind::Func: + return Use{{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}}; + case SymbolKind::Type: + return Use{{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}}; + case SymbolKind::Var: + return Use{{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}}; + default: + return Use{{range, 0, SymbolKind::File, role}}; } + } - std::string name = OS.str(); + PrintingPolicy GetDefaultPolicy() const { + PrintingPolicy PP(Ctx->getLangOpts()); + PP.AnonymousTagLocations = false; + PP.TerseOutput = true; + PP.PolishForDeclaration = true; + PP.ConstantsAsWritten = true; + PP.SuppressTagKeyword = true; + PP.SuppressInitializers = true; + PP.FullyQualifiedName = false; + return PP; + } + + static void SimplifyAnonymous(std::string& name) { for (std::string::size_type i = 0;;) { if ((i = name.find("(anonymous ", i)) == std::string::npos) break; i++; - if (name.size() > 10 + 9 && name.compare(10, 9, "namespace")) - name.replace(i, 10 + 9, "anon ns"); + if (name.size() - i > 19 && name.compare(i + 10, 9, "namespace") == 0) + name.replace(i, 19, "anon ns"); else - name.replace(i, 10, "anon"); + name.replace(i, 9, "anon"); } + } + + template + void SetName(const Decl *D, std::string_view short_name, + std::string_view qualified, Def &def, bool hover = false) { + SmallString<256> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP = GetDefaultPolicy(); + if (hover) + PP.SuppressInitializers = false; + D->print(OS, PP); + + std::string name = OS.str(); + SimplifyAnonymous(name); auto i = name.find(short_name); if (i == std::string::npos) { // e.g. operator type-parameter-1 i = 0; - def.short_name_offset = 0; + if (!hover) + def.short_name_offset = 0; } else if (short_name.size()) { name.replace(i, short_name.size(), qualified); - def.short_name_offset = i + qualified.size() - short_name.size(); + if (!hover) + def.short_name_offset = i + qualified.size() - short_name.size(); } else { - def.short_name_offset = i; + if (!hover) + def.short_name_offset = i; } - def.short_name_size = short_name.size(); - for (int paren = 0; i; i--) { - // Skip parentheses in "(anon struct)::name" - if (name[i - 1] == ')') - paren++; - else if (name[i - 1] == '(') - paren--; - else if (!(paren > 0 || isalnum(name[i - 1]) || - name[i - 1] == '_' || name[i - 1] == ':')) - break; + if (hover) { + if (name != def.detailed_name) + def.hover = Intern(name); + } else { + def.short_name_size = short_name.size(); + for (int paren = 0; i; i--) { + // Skip parentheses in "(anon struct)::name" + if (name[i - 1] == ')') + paren++; + else if (name[i - 1] == '(') + paren--; + else if (!(paren > 0 || isalnum(name[i - 1]) || name[i - 1] == '_' || + name[i - 1] == ':')) + break; + } + def.qual_name_offset = i; + def.detailed_name = Intern(name); } - def.qual_name_offset = i; - def.detailed_name = Intern(name); } - Use GetUse(IndexFile* db, Range range, const DeclContext *DC, Role role) { - if (!DC) - return Use{{range, 0, SymbolKind::File, role}}; - const Decl *D = cast(DC); - switch (GetSymbolKind(*D)) { - case SymbolKind::Func: - return Use{{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}}; - case SymbolKind::Type: - return Use{{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}}; - case SymbolKind::Var: - return Use{{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}}; - default: - return Use{{range, 0, SymbolKind::File, role}}; + void AddMacroUse(SourceManager &SM, std::vector &uses, + SourceLocation Spell) const { + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); + if (FE) { + IndexFile *db = param.ConsumeFile(*FE); + Range spell = + FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); + uses.push_back(GetUse(db, spell, nullptr, Role::Dynamic)); } } public: IndexDataConsumer(IndexParam& param) : param(param) {} void initialize(ASTContext &Ctx) override { - this->Ctx = &Ctx; + this->Ctx = param.Ctx = &Ctx; } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, @@ -433,22 +457,24 @@ class IndexDataConsumer : public index::IndexDataConsumer { } #endif SourceLocation Spell = SM.getSpellingLoc(Loc); - Range spell = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); + Loc = SM.getFileLoc(Loc); + Range loc = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Loc, Loc)); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc)); if (!FE) { + // TODO #if LLVM_VERSION_MAJOR < 7 auto P = SM.getExpansionRange(Loc); - spell = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); + loc = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); FE = SM.getFileEntryForID(SM.getFileID(P.first)); #else auto R = SM.getExpansionRange(Loc); - spell = FromTokenRange(SM, Ctx->getLangOpts(), R.getAsRange()); + loc = FromTokenRange(SM, Ctx->getLangOpts(), R.getAsRange()); FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); #endif if (!FE) return true; } - IndexFile *db = ConsumeFile(param, *FE); + IndexFile *db = param.ConsumeFile(*FE); if (!db) return true; @@ -466,13 +492,33 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (auto* ND = dyn_cast(D)) { short_name = ND->getNameAsString(); qualified = ND->getQualifiedNameAsString(); + SimplifyAnonymous(qualified); } IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; - SymbolKind kind = GetSymbolKind(*D); + SymbolKind kind = GetSymbolKind(D); Usr usr = GetUsr(D); + + auto do_def_decl = [&](auto *entity) { + if (!entity->def.detailed_name[0]) { + SetName(D, short_name, qualified, entity->def); + if (g_config->index.comments) + entity->def.comments = Intern(GetComment(D)); + } + if (is_def) { + entity->def.spell = GetUse(db, loc, LexDC, role); + // extent may come from a declaration. + entity->def.extent = GetUse(db, extent, LexDC, Role::None); + } else if (is_decl) { + entity->declarations.push_back(GetUse(db, loc, LexDC, role)); + } else { + entity->uses.push_back(GetUse(db, loc, LexDC, role)); + } + if (Spell != Loc) + AddMacroUse(SM, entity->uses, Spell); + }; switch (kind) { case SymbolKind::Invalid: LOG_S(INFO) << "Unhandled " << int(D->getKind()); @@ -481,63 +527,65 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; case SymbolKind::Func: func = &db->ToFunc(usr); - if (!func->def.detailed_name[0]) { - SetName(D, short_name, qualified, func->def); - if (g_config->index.comments) - func->def.comments = Intern(GetComment(D)); + do_def_decl(func); + if (is_def || is_decl) { + const Decl* DC = cast(SemDC); + if (GetSymbolKind(DC) == SymbolKind::Type) + db->ToType(GetUsr(DC)).def.funcs.push_back(usr); } - if (is_def || (is_decl && !func->def.spell)) { - if (func->def.spell) - func->declarations.push_back(*func->def.spell); - func->def.spell = GetUse(db, spell, LexDC, role); - func->def.extent = GetUse(db, extent, LexDC, Role::None); - if (auto *FD = dyn_cast(D)) { - DeclarationNameInfo Info = FD->getNameInfo(); - func->def.spell = GetUse( - db, FromTokenRange(SM, Ctx->getLangOpts(), Info.getSourceRange()), - LexDC, role); - } - } else - func->uses.push_back(GetUse(db, spell, LexDC, role)); break; case SymbolKind::Type: type = &db->ToType(usr); - if (!type->def.detailed_name[0]) { - SetName(D, short_name, qualified, type->def); - if (g_config->index.comments) - type->def.comments = Intern(GetComment(D)); + do_def_decl(type); + if (is_def || is_decl) { + const Decl* DC = cast(SemDC); + if (GetSymbolKind(DC) == SymbolKind::Type) + db->ToType(GetUsr(DC)).def.types.push_back(usr); } - if (is_def || (is_decl && !type->def.spell)) { - if (type->def.spell) - type->declarations.push_back(*type->def.spell); - type->def.spell = GetUse(db, spell, LexDC, role); - type->def.extent = GetUse(db, extent, LexDC, Role::None); - } else - type->uses.push_back(GetUse(db, spell, LexDC, role)); break; case SymbolKind::Var: var = &db->ToVar(usr); - if (!var->def.detailed_name[0]) { - SetName(D, short_name, qualified, var->def); - if (g_config->index.comments) - var->def.comments = Intern(GetComment(D)); - } - if (is_def || (is_decl && !var->def.spell)) { - if (var->def.spell) - var->declarations.push_back(*var->def.spell); - var->def.spell = GetUse(db, spell, LexDC, role); - var->def.extent = GetUse(db, extent, LexDC, Role::None); + do_def_decl(var); + if (is_def || is_decl) { + const Decl* DC = cast(SemDC); + if (GetSymbolKind(DC) == SymbolKind::Type) + db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); + else if (auto *ND = dyn_cast(SemDC)) + db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); + QualType T; if (auto *VD = dyn_cast(D)) { var->def.storage = VD->getStorageClass(); - QualType T = VD->getType(); - for (const Decl* D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { - Usr usr1 = GetUsr(D1); - if (db->usr2type.count(usr1)) - var->def.type = usr1; + T = VD->getType(); + // O(n^2) + for (auto I : VD->redecls()) + if (I->hasInit()) { + // TODO missing "static" in definition + SetName(I, short_name, qualified, var->def, true); + break; + } + } else if (auto *FD = dyn_cast(D)) { + T = FD->getType(); + if (FD->hasInClassInitializer()) + SetName(D, short_name, qualified, var->def, true); + } + if (!T.isNull()) { + if (auto *BT = T->getAs()) { + Usr usr1 = static_cast(BT->getKind()); + var->def.type = usr1; + db->ToType(usr1).instances.push_back(usr); + } else { + for (const Decl *D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { + Usr usr1 = GetUsr(D1); + auto it = db->usr2type.find(usr1); + if (it != db->usr2type.end()) { + var->def.type = usr1; + it->second.instances.push_back(usr); + break; + } + } } } - } else - var->uses.push_back(GetUse(db, spell, LexDC, role)); + } break; } @@ -558,11 +606,37 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::Enum: type->def.kind = lsSymbolKind::Enum; break; - case Decl::Record: - case Decl::CXXRecord: - type->def.kind = lsSymbolKind::Struct; + case Decl::CXXRecord: { + auto *RD = cast(D); + if (is_def && RD->hasDefinition()) { + for (const CXXBaseSpecifier &Base : RD->bases()) { + QualType T = Base.getType(); + const NamedDecl *BaseD = nullptr; + if (auto *TDT = T->getAs()) { + BaseD = TDT->getDecl(); + } else if (auto *TST = T->getAs()) { + BaseD = TST->getTemplateName().getAsTemplateDecl(); + } else if (auto *RT = T->getAs()) { + BaseD = RT->getDecl(); + } + if (BaseD) { + Usr usr1 = GetUsr(BaseD); + auto it = db->usr2type.find(usr1); + if (it != db->usr2type.end()) { + type->def.bases.push_back(usr1); + it->second.derived.push_back(usr); + } + } + } + } + } + [[fallthrough]]; + case Decl::Record: { + auto *RD = cast(D); + // spec has no Union, use Class + type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct + : lsSymbolKind::Class; if (is_def) { - auto *RD = cast(D); bool can_get_offset = RD->isCompleteDefinition() && !RD->isDependentType(); for (FieldDecl *FD : RD->fields()) @@ -570,6 +644,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); } break; + } case Decl::ClassTemplate: type->def.kind = lsSymbolKind::Class; break; @@ -579,6 +654,35 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::TypeAliasTemplate: type->def.kind = lsSymbolKind::TypeAlias; break; + case Decl::ClassTemplateSpecialization: + type->def.kind = lsSymbolKind::Class; + if (is_def || is_decl) { + if (auto *RD = dyn_cast(D)) { + Decl *D1 = nullptr; + if (auto *SD = dyn_cast(RD)) + D1 = SD->getSpecializedTemplate(); + else if (auto *SD = dyn_cast(RD)) { + llvm::PointerUnion + Result = SD->getSpecializedTemplateOrPartial(); + if (Result.is()) + D1 = Result.get(); + else + D1 = Result.get(); + + } else + D1 = RD->getInstantiatedFromMemberClass(); + if (D1) { + Usr usr1 = GetUsr(D1); + auto it = db->usr2type.find(usr1); + if (it != db->usr2type.end()) { + type->def.bases.push_back(usr1); + it->second.derived.push_back(usr); + } + } + } + } + break; case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: @@ -597,6 +701,20 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::CXXMethod: func->def.kind = lsSymbolKind::Method; + if (is_def || is_decl) { + if (auto *ND = dyn_cast(D)) { + SmallVector OverDecls; + Ctx->getOverriddenMethods(ND, OverDecls); + for (const auto* ND1 : OverDecls) { + Usr usr1 = GetUsr(ND1); + auto it = db->usr2func.find(usr1); + if (it != db->usr2func.end()) { + func->def.bases.push_back(usr1); + it->second.derived.push_back(usr); + } + } + } + } break; case Decl::CXXConstructor: case Decl::CXXConversion: @@ -605,29 +723,29 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::CXXDestructor: func->def.kind = lsSymbolKind::Method; break; + case Decl::Field: + var->def.kind = lsSymbolKind::Field; + break; case Decl::Var: - case Decl::ParmVar: + case Decl::Decomposition: var->def.kind = lsSymbolKind::Variable; - if (is_def) { - if (auto* FD = dyn_cast(SemDC)) - db->ToFunc(GetUsr(FD)).def.vars.push_back(usr); - else if (auto* ND = dyn_cast(SemDC)) - db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); - } - [[fallthrough]]; - case Decl::Field: + break; case Decl::ImplicitParam: - case Decl::Decomposition: + case Decl::ParmVar: + // ccls extension + var->def.kind = lsSymbolKind::Parameter; break; - case Decl::EnumConstant: { - auto *ECD = cast(D); - const auto& Val = ECD->getInitVal(); - std::string init = - " = " + (Val.isSigned() ? std::to_string(Val.getSExtValue()) - : std::to_string(Val.getZExtValue())); - var->def.detailed_name = Intern(var->def.detailed_name + init); + case Decl::EnumConstant: + var->def.kind = lsSymbolKind::EnumMember; + if (is_def) { + auto *ECD = cast(D); + const auto &Val = ECD->getInitVal(); + std::string init = + " = " + (Val.isSigned() ? std::to_string(Val.getSExtValue()) + : std::to_string(Val.getZExtValue())); + var->def.hover = Intern(var->def.detailed_name + init); + } break; - } default: LOG_S(INFO) << "Unhandled " << int(D->getKind()); break; @@ -635,14 +753,90 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; } }; + +class IndexPPCallbacks : public PPCallbacks { + SourceManager& SM; + IndexParam& param; + + std::pair GetMacro(const Token& Tok) const { + StringRef Name = Tok.getIdentifierInfo()->getName(); + SmallString<256> USR("@macro@"); + USR += Name; + return {Name, HashUsr(USR)}; + } + +public: + IndexPPCallbacks(SourceManager& SM, IndexParam& param) : SM(SM), param(param) {} + void MacroDefined(const Token &Tok, const MacroDirective *MD) override { + llvm::sys::fs::UniqueID UniqueID; + SourceLocation L = MD->getLocation(); + auto range = + FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); + if (!FE) + return; + if (IndexFile *db = param.ConsumeFile(*FE)) { + auto[Name, usr] = GetMacro(Tok); + IndexVar &var = db->ToVar(usr); + if (!var.def.detailed_name[0]) { + var.def.detailed_name = Intern(Name); + var.def.short_name_size = Name.size(); + // TODO defin + var.def.hover = Intern(Twine("#define ", Name).str()); + var.def.kind = lsSymbolKind::Macro; + if (var.def.spell) + var.declarations.push_back(*var.def.spell); + var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}}; + var.def.extent = var.def.spell; + } + } + } + void MacroExpands(const Token &Tok, const MacroDefinition &MD, + SourceRange R, const MacroArgs *Args) override { + llvm::sys::fs::UniqueID UniqueID; + auto range = FromTokenRange(SM, param.Ctx->getLangOpts(), R, &UniqueID); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + if (!FE) + return; + if (IndexFile *db = param.ConsumeFile(*FE)) { + auto[Name, usr] = GetMacro(Tok); + IndexVar &var = db->ToVar(usr); + var.uses.push_back({{range, 0, SymbolKind::File, Role::Reference}}); + } + } + void MacroUndefined(const Token &Tok, const MacroDefinition &MD, + const MacroDirective *UD) override { + SourceLocation L = UD->getLocation(); + MacroExpands(Tok, MD, {L, L}, nullptr); + } + void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { + llvm::sys::fs::UniqueID UniqueID; + auto range = FromCharRange(SM, param.Ctx->getLangOpts(), Range, &UniqueID); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin())); + if (IndexFile *db = param.ConsumeFile(*FE)) + db->skipped_ranges.push_back(range); + } +}; + +class IndexFrontendAction : public ASTFrontendAction { + IndexParam& param; +public: + IndexFrontendAction(IndexParam& param) : param(param) {} + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { + Preprocessor &PP = CI.getPreprocessor(); + PP.addPPCallbacks(std::make_unique(PP.getSourceManager(), param)); + return std::make_unique(); + } +}; } const int IndexFile::kMajorVersion = 16; const int IndexFile::kMinorVersion = 1; -IndexFile::IndexFile(unsigned UID, const std::string &path, +IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) - : UID(UID), path(path), file_contents(contents) {} + : UniqueID(UniqueID), path(path), file_contents(contents) {} IndexFunc& IndexFile::ToFunc(Usr usr) { auto ret = usr2func.try_emplace(usr); @@ -701,8 +895,6 @@ std::vector> ClangIndexer::Index( std::vector Args; for (auto& arg: args) Args.push_back(arg.c_str()); - Args.push_back("-Xclang"); - Args.push_back("-detailed-preprocessing-record"); Args.push_back("-fno-spell-checking"); auto PCHCO = std::make_shared(); IntrusiveRefCntPtr @@ -735,8 +927,8 @@ std::vector> ClangIndexer::Index( index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; - std::unique_ptr IndexAction = - createIndexingAction(DataConsumer, IndexOpts, nullptr); + std::unique_ptr IndexAction = createIndexingAction( + DataConsumer, IndexOpts, std::make_unique(param)); llvm::CrashRecoveryContextCleanupRegistrar IndexActionCleanup( IndexAction.get()); @@ -755,33 +947,19 @@ std::vector> ClangIndexer::Index( // ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) // .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); + const SourceManager& SM = Unit->getSourceManager(); + const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); + param.primary_file = param.ConsumeFile(*FE); std::unordered_map inc_to_line; // TODO if (param.primary_file) for (auto& inc : param.primary_file->includes) inc_to_line[inc.resolved_path] = inc.line; - llvm::DenseMap> UID2skipped; - { - const SourceManager& SM = Unit->getSourceManager(); - PreprocessingRecord *PPRec = Unit->getPreprocessor().getPreprocessingRecord(); - if (PPRec) { - const std::vector& Skipped = PPRec->getSkippedRanges(); - for (auto& R : Skipped) { - unsigned UID; - Range range = FromTokenRange(SM, Unit->getLangOpts(), R, &UID); - UID2skipped[UID].push_back(range); - } - } - } - auto result = param.file_consumer->TakeLocalState(); for (std::unique_ptr& entry : result) { entry->import_file = file; entry->args = args; - auto it = UID2skipped.find(entry->UID); - if (it != UID2skipped.end()) - entry->skipped_ranges = std::move(it->second); for (auto& it : entry->usr2func) { // e.g. declaration + out-of-line definition Uniquify(it.second.derived); @@ -817,7 +995,7 @@ std::vector> ClangIndexer::Index( // Update dependencies for the file. Do not include the file in its own // dependency set. - for (const std::string& path : param.seen_files) + for (auto & [ _, path ] : param.SeenUniqueID) if (path != entry->path && path != entry->import_file) entry->dependencies[path] = param.file2write_time[path]; } diff --git a/src/indexer.h b/src/indexer.h index 441dc44ce..9deae62d3 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -249,7 +249,7 @@ struct IndexFile { // files accepted by newer ccls. static const int kMinorVersion; - unsigned UID; + llvm::sys::fs::UniqueID UniqueID; std::string path; std::vector args; int64_t last_write_time = 0; @@ -275,7 +275,8 @@ struct IndexFile { // File contents at the time of index. Not serialized. std::string file_contents; - IndexFile(unsigned UID, const std::string& path, const std::string& contents); + IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, + const std::string &contents); IndexFunc& ToFunc(Usr usr); IndexType& ToType(Usr usr); diff --git a/src/query.cc b/src/query.cc index 3d40f6c4d..b4f8c6136 100644 --- a/src/query.cc +++ b/src/query.cc @@ -172,7 +172,8 @@ bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, IndexFile* current) { IndexUpdate r; - static IndexFile empty(0u, current->path, ""); + static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path, + ""); if (!previous) previous = ∅ diff --git a/src/serializer.cc b/src/serializer.cc index 458d268a1..423154bd5 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -426,7 +426,8 @@ std::unique_ptr Deserialize( if (major != IndexFile::kMajorVersion || minor != IndexFile::kMinorVersion) throw std::invalid_argument("Invalid version"); - file = std::make_unique(0u, path, file_content); + file = std::make_unique(sys::fs::UniqueID(0, 0), path, + file_content); Reflect(reader, *file); } catch (std::invalid_argument& e) { LOG_S(INFO) << "failed to deserialize '" << path @@ -450,7 +451,8 @@ std::unique_ptr Deserialize( if (reader.HasParseError()) return nullptr; - file = std::make_unique(0u, path, file_content); + file = std::make_unique(sys::fs::UniqueID(0, 0), path, + file_content); JsonReader json_reader{&reader}; try { Reflect(json_reader, *file); diff --git a/src/utils.cc b/src/utils.cc index c10b92469..36c277a36 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -38,6 +38,10 @@ uint64_t HashUsr(std::string_view s) { return ret; } +uint64_t HashUsr(llvm::StringRef s) { + return HashUsr(std::string_view(s.data(), s.size())); +} + bool EndsWith(std::string_view s, std::string_view suffix) { return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); diff --git a/src/utils.h b/src/utils.h index 3b3bb511f..49af3555c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -9,10 +9,15 @@ #include #include +namespace llvm { +class StringRef; +} + void TrimInPlace(std::string& s); std::string Trim(std::string s); uint64_t HashUsr(std::string_view s); +uint64_t HashUsr(llvm::StringRef s); // Returns true if |value| starts/ends with |start| or |ending|. bool StartsWith(std::string_view value, std::string_view start); From cc65ea94ed260fe1808b758da406aa924c839b44 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 00:46:53 -0700 Subject: [PATCH 130/378] Misc changes to clangIndex --- index_tests/class_forward_declaration.cc | 2 +- index_tests/constructors/invalid_reference.cc | 2 +- index_tests/constructors/make_functions.cc | 5 +- .../declaration_vs_definition/class.cc | 2 +- .../class_member_static.cc | 2 +- index_tests/declaration_vs_definition/func.cc | 2 +- .../func_associated_function_params.cc | 2 +- .../declaration_vs_definition/method.cc | 2 +- index_tests/enums/enum_class_decl.cc | 1 - index_tests/enums/enum_decl.cc | 1 - index_tests/enums/enum_inherit.cc | 2 - index_tests/enums/enum_usage.cc | 1 - .../function_declaration_definition.cc | 2 +- index_tests/method_definition.cc | 2 +- index_tests/multi_file/funky_enum.cc | 5 +- index_tests/multi_file/impl.cc | 5 +- index_tests/multi_file/simple_impl.cc | 5 +- index_tests/multi_file/static.cc | 7 +- index_tests/namespaces/method_definition.cc | 2 +- .../outline/static_function_in_type.cc | 7 +- .../func_specialized_template_param.cc | 2 +- .../implicit_variable_instantiation.cc | 4 +- .../templates/specialized_func_definition.cc | 4 +- .../usage/func_called_from_constructor.cc | 2 +- ...ype_usage_as_template_parameter_complex.cc | 2 +- .../type_usage_declare_param_prototype.cc | 2 +- .../usage/type_usage_on_return_type.cc | 8 +- index_tests/usage/type_usage_various.cc | 2 +- index_tests/usage/usage_inside_of_call.cc | 4 +- index_tests/usage/var_usage_cstyle_cast.cc | 2 +- index_tests/vars/class_static_member.cc | 2 +- src/file_consumer.cc | 2 +- src/file_consumer.h | 16 +- src/indexer.cc | 139 ++++++++++++------ src/indexer.h | 23 +-- src/main.cc | 2 +- src/pipeline.cc | 10 +- src/project.cc | 6 +- src/project.h | 1 + src/test.cc | 3 +- 40 files changed, 170 insertions(+), 125 deletions(-) diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index a90ce1259..fd80cefb5 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -17,7 +17,7 @@ class Foo; "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "1:1-1:10|0|1|0", + "extent": "3:1-3:13|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index c68bc86ef..7f17706cb 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -20,7 +20,7 @@ Foo::Foo() {} "kind": 9, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|514", + "spell": "4:6-4:9|15041163540773201510|2|514", "extent": "4:1-4:11|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index 5a74373a9..ecce8489c 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -132,7 +132,10 @@ OUTPUT: make_functions.h } OUTPUT: make_functions.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&make_functions.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 2532818908869373467, diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index e8aa0e94f..42a44a882 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -19,7 +19,7 @@ class Foo; "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "1:1-1:10|0|1|0", + "extent": "3:1-3:13|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 5c522d445..24570fcb8 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -64,7 +64,7 @@ int Foo::foo; "short_name": "foo", "declarations": ["2:14-2:17|15041163540773201510|2|513"], "spell": "5:10-5:13|15041163540773201510|2|514", - "extent": "2:3-2:17|15041163540773201510|2|0", + "extent": "5:1-5:13|0|1|0", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index eb24139ce..10f53f1ec 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -18,7 +18,7 @@ void foo(); "storage": 0, "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "1:1-1:11|0|1|0", + "extent": "3:1-3:14|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index 74ddc5938..eb8071c0f 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -18,7 +18,7 @@ int foo(int a, int b) { return 0; } "storage": 0, "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], "spell": "5:5-5:8|0|1|2", - "extent": "1:1-1:18|0|1|0", + "extent": "5:1-5:36|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 940112844..3b323d76e 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -48,7 +48,7 @@ void Foo::def() {} "storage": 0, "declarations": ["4:8-4:11|15041163540773201510|2|513"], "spell": "7:11-7:14|15041163540773201510|2|514", - "extent": "4:3-4:13|15041163540773201510|2|0", + "extent": "7:1-7:19|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 3518fbeeb..b417eb0b4 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -77,7 +77,6 @@ enum class Foo : uint8_t { "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20 = 20", "declarations": [], "spell": "4:3-4:4|16985894625255407295|2|514", "extent": "4:3-4:9|16985894625255407295|2|0", diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index ae283d350..5719a2618 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -59,7 +59,6 @@ enum Foo { "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index fab7c3d35..d0535609d 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -114,7 +114,6 @@ enum class E : int32_t { "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", @@ -140,7 +139,6 @@ enum class E : int32_t { "detailed_name": "E::E20 = 20", "qual_name_offset": 0, "short_name": "E20", - "hover": "E::E20 = 20 = 20", "declarations": [], "spell": "10:3-10:6|2986879766914123941|2|514", "extent": "10:3-10:11|2986879766914123941|2|0", diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index b3c24b4a8..1ea1d3bde 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -74,7 +74,6 @@ Foo x = Foo::A; "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index 8a934caee..67bbfe771 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -16,7 +16,7 @@ void foo() {} "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "1:1-1:11|0|1|0", + "extent": "3:1-3:14|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 28caf615a..8fb481a6b 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -18,7 +18,7 @@ void Foo::foo() const {} "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|513"], "spell": "5:11-5:14|15041163540773201510|2|514", - "extent": "2:3-2:19|15041163540773201510|2|0", + "extent": "5:1-5:25|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index ea2914680..29963edfc 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -87,7 +87,10 @@ OUTPUT: funky_enum.h } OUTPUT: funky_enum.cc { - "includes": [], + "includes": [{ + "line": 1, + "resolved_path": "&funky_enum.h" + }], "skipped_ranges": [], "usr2func": [], "usr2type": [{ diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index a978e97e4..48cbb17a3 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -208,7 +208,10 @@ OUTPUT: header.h } OUTPUT: impl.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&header.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 5817708529036841195, diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 639d0f69c..1e6e95195 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -29,7 +29,10 @@ OUTPUT: simple_header.h } OUTPUT: simple_impl.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&simple_header.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 3373269392705484958, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 5a607e6a9..c7dcd941b 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -44,7 +44,10 @@ OUTPUT: static.h } OUTPUT: static.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&static.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, @@ -55,7 +58,7 @@ OUTPUT: static.cc "storage": 0, "declarations": [], "spell": "3:14-3:32|9411323049603567600|2|514", - "extent": "4:3-4:35|9411323049603567600|2|0", + "extent": "3:1-3:37|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 12efc78bb..ed61dfe28 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -20,7 +20,7 @@ void Foo::foo() {} "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|513"], "spell": "6:11-6:14|4508214972876735896|2|514", - "extent": "3:3-3:13|4508214972876735896|2|0", + "extent": "6:1-6:19|2029211996748007610|2|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index f17ccd169..74a75735e 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -78,7 +78,10 @@ OUTPUT: static_function_in_type.h } OUTPUT: static_function_in_type.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&static_function_in_type.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, @@ -89,7 +92,7 @@ OUTPUT: static_function_in_type.cc "storage": 0, "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|514", - "extent": "6:3-6:33|17262466801709381811|2|0", + "extent": "5:1-6:2|11072669167287398027|2|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index ab8af6b31..400b610f2 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -21,7 +21,7 @@ void Foo::Bar(Template&) {} "storage": 0, "declarations": ["5:8-5:11|15041163540773201510|2|513"], "spell": "8:11-8:14|15041163540773201510|2|514", - "extent": "5:3-5:30|15041163540773201510|2|0", + "extent": "8:1-8:36|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 7ec48af76..0c356b628 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -121,9 +121,9 @@ namespace ns { "hover": "static constexpr ns::VarType ns::Holder::static_var = (ns::VarType)0", "declarations": ["6:30-6:40|12688716854043726585|2|513"], "spell": "10:37-10:47|12688716854043726585|2|514", - "extent": "6:5-6:55|12688716854043726585|2|0", + "extent": "9:3-10:47|11072669167287398027|2|0", "type": 1532099849728741556, - "uses": ["13:26-13:36|12688716854043726585|2|12", "14:27-14:37|12688716854043726585|2|12"], + "uses": ["13:26-13:36|11072669167287398027|2|12", "14:27-14:37|11072669167287398027|2|12"], "kind": 13, "storage": 2 }, { diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 9e0fe0cb4..94b336536 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -31,7 +31,7 @@ void Template::Foo() {} "storage": 0, "declarations": [], "spell": "10:22-10:25|17649312483543982122|2|514", - "extent": "3:3-3:13|17649312483543982122|2|0", + "extent": "9:1-10:30|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ void Template::Foo() {} "storage": 0, "declarations": ["3:8-3:11|17107291254533526269|2|513"], "spell": "7:19-7:22|17107291254533526269|2|514", - "extent": "3:3-3:13|17107291254533526269|2|0", + "extent": "6:1-7:24|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index d109e087b..9757455b5 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -38,7 +38,7 @@ Foo::Foo() { "storage": 0, "declarations": ["4:3-4:6|15041163540773201510|2|513"], "spell": "7:6-7:9|15041163540773201510|2|514", - "extent": "4:3-4:8|15041163540773201510|2|0", + "extent": "7:1-9:2|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 615d36a28..76c284710 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -124,7 +124,7 @@ unique_ptr* Foo::foo() { return nullptr; } "storage": 0, "declarations": ["65:23-65:26|15041163540773201510|2|513"], "spell": "79:26-79:29|15041163540773201510|2|514", - "extent": "65:3-65:28|15041163540773201510|2|0", + "extent": "79:1-79:51|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 36e88a1a6..3326f28e0 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -22,7 +22,7 @@ void foo(Foo* f, Foo*) {} "storage": 0, "declarations": ["3:6-3:9|0|1|1"], "spell": "4:6-4:9|0|1|2", - "extent": "3:1-3:23|0|1|0", + "extent": "4:1-4:26|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 3669d942d..353777794 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -31,7 +31,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["9:8-9:13|15041163540773201510|2|513"], "spell": "13:11-13:16|15041163540773201510|2|514", - "extent": "9:3-9:15|15041163540773201510|2|0", + "extent": "13:1-13:21|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "5:7-5:10|0|1|2", - "extent": "3:1-3:12|0|1|0", + "extent": "5:1-5:32|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -77,7 +77,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["8:9-8:12|15041163540773201510|2|513"], "spell": "12:12-12:15|15041163540773201510|2|514", - "extent": "8:3-8:17|15041163540773201510|2|0", + "extent": "12:1-12:40|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -93,7 +93,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["17:14-17:17|0|1|1"], "spell": "18:14-18:17|0|1|2", - "extent": "17:1-17:19|0|1|0", + "extent": "18:1-18:39|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index 933027432..5e6e6ac27 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -23,7 +23,7 @@ extern Foo foo; "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|513"], "spell": "5:11-5:15|15041163540773201510|2|514", - "extent": "2:3-2:14|15041163540773201510|2|0", + "extent": "5:1-8:2|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 412d94c13..15c45125b 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -147,9 +147,9 @@ void foo() { "hover": "int Foo::static_var = 0", "declarations": ["6:14-6:24|15041163540773201510|2|513"], "spell": "10:10-10:20|15041163540773201510|2|514", - "extent": "6:3-6:24|15041163540773201510|2|0", + "extent": "10:1-10:24|0|1|0", "type": 53, - "uses": ["14:45-14:55|15041163540773201510|2|12"], + "uses": ["14:45-14:55|0|1|12"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 18372325e..912996747 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -70,7 +70,7 @@ const VarType Holder::static_var; "hover": "static constexpr VarType Holder::static_var = (VarType)0", "declarations": ["4:28-4:38|10028537921178202800|2|513"], "spell": "7:23-7:33|10028537921178202800|2|514", - "extent": "4:3-4:53|10028537921178202800|2|0", + "extent": "7:1-7:33|0|1|0", "type": 5792006888140599735, "uses": [], "kind": 13, diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 3e6689ce4..0c94d4a7f 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -49,7 +49,7 @@ Foo* Foo::member = nullptr; "hover": "Foo *Foo::member = nullptr", "declarations": ["2:15-2:21|15041163540773201510|2|513"], "spell": "4:11-4:17|15041163540773201510|2|514", - "extent": "2:3-2:21|15041163540773201510|2|0", + "extent": "4:1-4:27|0|1|0", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 928d36b52..4f2726069 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -80,7 +80,7 @@ bool VFS::Stamp(const std::string& file, int64_t ts) { void VFS::ResetLocked(const std::string& file) { State& st = state[file]; - if (st.owner == g_thread_id) + if (st.owner == 0 || st.owner == g_thread_id) st.stage = 0; } diff --git a/src/file_consumer.h b/src/file_consumer.h index 5fb8e2601..a2ec01294 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -7,9 +7,8 @@ #include #include -#include -#include #include +#include #include struct IndexFile; @@ -43,6 +42,17 @@ struct VFS { void Reset(const std::string& file); }; +namespace std { +template <> +struct hash { + std::size_t operator()(llvm::sys::fs::UniqueID ID) const { + size_t ret = ID.getDevice(); + hash_combine(ret, ID.getFile()); + return ret; + } +}; +} + // FileConsumer is used by the indexer. When it encouters a file, it tries to // take ownership over it. If the indexer has ownership over a file, it will // produce an index, otherwise, it will emit nothing for that declarations @@ -66,7 +76,7 @@ struct FileConsumer { std::vector> TakeLocalState(); private: - std::map> local_; + std::unordered_map> local_; VFS* vfs_; std::string parse_file_; int thread_id_; diff --git a/src/indexer.cc b/src/indexer.cc index 5bb2056a9..5911cef3a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -14,8 +14,8 @@ using ccls::Intern; #include #include #include -#include #include +#include using namespace clang; using llvm::Timer; @@ -35,19 +35,10 @@ struct IndexParam { std::unordered_map file2write_time; llvm::DenseMap Decl2usr; - // Only use this when strictly needed (ie, primary translation unit is - // needed). Most logic should get the IndexFile instance via - // |file_consumer|. - // - // This can be null if we're not generating an index for the primary - // translation unit. - IndexFile* primary_file = nullptr; - ASTUnit& Unit; ASTContext* Ctx; FileConsumer* file_consumer = nullptr; - NamespaceHelper ns; IndexParam(ASTUnit& Unit, FileConsumer* file_consumer) : Unit(Unit), file_consumer(file_consumer) {} @@ -458,7 +449,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { #endif SourceLocation Spell = SM.getSpellingLoc(Loc); Loc = SM.getFileLoc(Loc); - Range loc = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Loc, Loc)); + Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc)); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc)); if (!FE) { // TODO @@ -468,7 +459,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { FE = SM.getFileEntryForID(SM.getFileID(P.first)); #else auto R = SM.getExpansionRange(Loc); - loc = FromTokenRange(SM, Ctx->getLangOpts(), R.getAsRange()); + loc = FromTokenRange(SM, Lang, R.getAsRange()); FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); #endif if (!FE) @@ -478,11 +469,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!db) return true; - const DeclContext *SemDC = D->getDeclContext(); - const DeclContext *LexDC = D->getLexicalDeclContext(); - (void)SemDC; - (void)LexDC; - Range extent = FromTokenRange(SM, Lang, D->getSourceRange()); + const Decl* OrigD = ASTNode.OrigD; + const DeclContext *SemDC = OrigD->getDeclContext(); + const DeclContext *LexDC = OrigD->getLexicalDeclContext(); Role role = static_cast(Roles); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); @@ -504,13 +493,14 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto do_def_decl = [&](auto *entity) { if (!entity->def.detailed_name[0]) { SetName(D, short_name, qualified, entity->def); - if (g_config->index.comments) + if (entity->def.comments[0] == '\0' && g_config->index.comments) entity->def.comments = Intern(GetComment(D)); } if (is_def) { - entity->def.spell = GetUse(db, loc, LexDC, role); - // extent may come from a declaration. - entity->def.extent = GetUse(db, extent, LexDC, Role::None); + entity->def.spell = GetUse(db, loc, SemDC, role); + entity->def.extent = + GetUse(db, FromTokenRange(SM, Lang, OrigD->getSourceRange()), LexDC, + Role::None); } else if (is_decl) { entity->declarations.push_back(GetUse(db, loc, LexDC, role)); } else { @@ -737,7 +727,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::EnumConstant: var->def.kind = lsSymbolKind::EnumMember; - if (is_def) { + // TODO Pretty printer may print = + if (is_def && strchr(var->def.detailed_name, '=') == nullptr) { auto *ECD = cast(D); const auto &Val = ECD->getInitVal(); std::string init = @@ -767,6 +758,26 @@ class IndexPPCallbacks : public PPCallbacks { public: IndexPPCallbacks(SourceManager& SM, IndexParam& param) : SM(SM), param(param) {} + void InclusionDirective(SourceLocation HashLoc, const Token &Tok, + StringRef Included, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { + if (!File) + return; + llvm::sys::fs::UniqueID UniqueID; + SourceRange R = FilenameRange.getAsRange(); + auto spell = FromCharRange(SM, param.Ctx->getLangOpts(), R, &UniqueID); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + if (!FE) + return; + if (IndexFile *db = param.ConsumeFile(*FE)) { + std::string file_name = FileName(*File); + if (file_name.size()) + db->includes.push_back({spell.start.line, std::move(file_name)}); + } + } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { llvm::sys::fs::UniqueID UniqueID; SourceLocation L = MD->getLocation(); @@ -806,8 +817,10 @@ class IndexPPCallbacks : public PPCallbacks { } void MacroUndefined(const Token &Tok, const MacroDefinition &MD, const MacroDirective *UD) override { - SourceLocation L = UD->getLocation(); - MacroExpands(Tok, MD, {L, L}, nullptr); + if (UD) { + SourceLocation L = UD->getLocation(); + MacroExpands(Tok, MD, {L, L}, nullptr); + } } void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { llvm::sys::fs::UniqueID UniqueID; @@ -882,20 +895,27 @@ void Uniquify(std::vector& uses) { uses.resize(n); } -std::vector> ClangIndexer::Index( + +namespace ccls::idx { +void IndexInit() { + // This calls llvm::InitializeAllTargets() ... for us, we would otherwise link + // all target libraries. + CXIndex CXIdx = clang_createIndex(0, 0); + clang_disposeIndex(CXIdx); +} + +std::vector> Index( VFS* vfs, - std::string file, + const std::string& opt_wdir, + const std::string& file, const std::vector& args, const std::vector& file_contents) { if (!g_config->index.enabled) return {}; - file = NormalizePath(file); - std::vector Args; for (auto& arg: args) Args.push_back(arg.c_str()); - Args.push_back("-fno-spell-checking"); auto PCHCO = std::make_shared(); IntrusiveRefCntPtr Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); @@ -903,7 +923,22 @@ std::vector> ClangIndexer::Index( createInvocationFromCommandLine(Args, Diags); if (!CI) return {}; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; + // -fparse-all-comments enables documentation in the indexer and in + // code completion. + if (g_config->index.comments > 1) + CI->getLangOpts()->CommentOpts.ParseAllComments = true; + CI->getLangOpts()->SpellChecking = false; + { + // FileSystemOptions& FSOpts = CI->getFileSystemOpts(); + // if (FSOpts.WorkingDir.empty()) + // FSOpts.WorkingDir = opt_wdir; + // HeaderSearchOptions &HSOpts = CI->getHeaderSearchOpts(); + // llvm::errs() << HSOpts.ResourceDir << "\n"; + // // lib/clang/7.0.0 is incorrect + // if (HSOpts.ResourceDir.compare(0, 3, "lib") == 0 && + // HSOpts.UseBuiltinIncludes) + // HSOpts.ResourceDir = g_config->clang.resourceDir; + } std::vector> BufOwner; for (auto &c : file_contents) { @@ -929,31 +964,42 @@ std::vector> ClangIndexer::Index( std::unique_ptr IndexAction = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); - llvm::CrashRecoveryContextCleanupRegistrar IndexActionCleanup( - IndexAction.get()); DiagnosticErrorTrap DiagTrap(*Diags); - bool Success = ASTUnit::LoadFromCompilerInvocationAction( - std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), - /*Persistent=*/true, "/home/maskray/Dev/llvm/release/lib/clang/7.0.0", - /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, true); + bool success = false; + llvm::CrashRecoveryContext CRC; + { + auto compile = [&]() { + success = ASTUnit::LoadFromCompilerInvocationAction( + std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), + /*Persistent=*/true, /*ResourceDir=*/"", + /*OnlyLocalDecls=*/true, + /*CaptureDiagnostics=*/true, 0, false, false, true); + }; + const char *env = getenv("CCLS_CRASH_RECOVERY"); + if (env && strcmp(env, "0") == 0) + compile(); + else + CRC.RunSafely(compile); + } + if (!Unit) { LOG_S(ERROR) << "failed to index " << file; return {}; } - if (!Success) + if (!success) { + LOG_S(ERROR) << "clang crashed for " << file; return {}; + } // ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) // .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); const SourceManager& SM = Unit->getSourceManager(); const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); - param.primary_file = param.ConsumeFile(*FE); + IndexFile* main_file = param.ConsumeFile(*FE); std::unordered_map inc_to_line; - // TODO - if (param.primary_file) - for (auto& inc : param.primary_file->includes) + if (main_file) + for (auto& inc : main_file->includes) inc_to_line[inc.resolved_path] = inc.line; auto result = param.file_consumer->TakeLocalState(); @@ -974,7 +1020,7 @@ std::vector> ClangIndexer::Index( for (auto& it : entry->usr2var) Uniquify(it.second.uses); - if (param.primary_file) { + if (main_file) { // If there are errors, show at least one at the include position. auto it = inc_to_line.find(entry->path); if (it != inc_to_line.end()) { @@ -984,7 +1030,7 @@ std::vector> ClangIndexer::Index( continue; ls_diagnostic.range = lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; - param.primary_file->diagnostics_.push_back(ls_diagnostic); + main_file->diagnostics_.push_back(ls_diagnostic); break; } } @@ -1002,11 +1048,6 @@ std::vector> ClangIndexer::Index( return result; } - -void IndexInit() { - // InitLLVM - CXIndex CXIdx = clang_createIndex(0, 0); - clang_disposeIndex(CXIdx); } // |SymbolRef| is serialized this way. diff --git a/src/indexer.h b/src/indexer.h index 9deae62d3..681d2436e 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -285,22 +285,11 @@ struct IndexFile { std::string ToString(); }; -struct NamespaceHelper { - std::unordered_map usr2qualified_name; - - std::tuple QualifiedName( - const CXIdxContainerInfo* container, - std::string_view unqualified_name); -}; - -bool ConcatTypeAndName(std::string& type, const std::string& name); - +namespace ccls::idx { void IndexInit(); -struct ClangIndexer { - std::vector> Index( - VFS* vfs, - std::string file, - const std::vector& args, - const std::vector& file_contents); -}; +std::vector> +Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, + const std::vector &args, + const std::vector &file_contents); +} diff --git a/src/main.cc b/src/main.cc index 6f85f6304..495f8c477 100644 --- a/src/main.cc +++ b/src/main.cc @@ -59,7 +59,7 @@ int main(int argc, char** argv) { } pipeline::Init(); - IndexInit(); + idx::IndexInit(); bool language_server = true; diff --git a/src/pipeline.cc b/src/pipeline.cc index 3d960b9e9..2105bc1d9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -152,8 +152,7 @@ std::unique_ptr RawCacheLoad( bool Indexer_Parse(DiagnosticsPublisher* diag_pub, WorkingFiles* working_files, Project* project, - VFS* vfs, - ClangIndexer* indexer) { + VFS* vfs) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -235,7 +234,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, LOG_S(INFO) << "parse " << path_to_index; - auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}); + auto indexes = idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -309,11 +308,8 @@ void Indexer_Main(DiagnosticsPublisher* diag_pub, VFS* vfs, Project* project, WorkingFiles* working_files) { - // Build one index per-indexer, as building the index acquires a global lock. - ClangIndexer indexer; - while (true) - if (!Indexer_Parse(diag_pub, working_files, project, vfs, &indexer)) + if (!Indexer_Parse(diag_pub, working_files, project, vfs)) indexer_waiter->Wait(index_request); } diff --git a/src/project.cc b/src/project.cc index db65eb684..202e7510c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -186,11 +186,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // what ccls uses. Make sure we do not emit warnings for mismatched options. args.push_back("-Wno-unknown-warning-option"); - // Using -fparse-all-comments enables documentation in the indexer and in - // code completion. - if (g_config->index.comments > 1) - args.push_back("-fparse-all-comments"); - + result.directory = entry.directory; result.args = std::move(args); return result; } diff --git a/src/project.h b/src/project.h index f56f4b55b..acb55495f 100644 --- a/src/project.h +++ b/src/project.h @@ -13,6 +13,7 @@ struct WorkingFiles; struct Project { struct Entry { + std::string directory; std::string filename; std::vector args; // If true, this entry is inferred and was not read from disk. diff --git a/src/test.cc b/src/test.cc index c5c940a37..0c89f6884 100644 --- a/src/test.cc +++ b/src/test.cc @@ -246,7 +246,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); - ClangIndexer index; GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string& path) { @@ -290,7 +289,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // Run test. g_config = new Config; VFS vfs; - auto dbs = index.Index(&vfs, path, flags, {}); + auto dbs = ccls::idx::Index(&vfs, "", path, flags, {}); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first; From eb8acf9cdb50df60cb5b5d55d7a4ef2c2021bdbc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 11:51:07 -0700 Subject: [PATCH 131/378] pipeline --- src/indexer.cc | 2 +- src/pipeline.cc | 40 ++++++++++++---------------------------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 5911cef3a..6aee246ab 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -30,7 +30,7 @@ using llvm::Timer; namespace { struct IndexParam { - std::map SeenUniqueID; + std::unordered_map SeenUniqueID; std::unordered_map file_contents; std::unordered_map file2write_time; llvm::DenseMap Decl2usr; diff --git a/src/pipeline.cc b/src/pipeline.cc index 2105bc1d9..3b7f0cd6b 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -79,34 +79,21 @@ ThreadedQueue* index_request; ThreadedQueue* on_indexed; ThreadedQueue* for_stdout; -// Checks if |path| needs to be reparsed. This will modify cached state -// such that calling this function twice with the same path may return true -// the first time but will return false the second. -// -// |from|: The file which generated the parse request for this file. -bool FileNeedsParse(int64_t write_time, - VFS* vfs, - bool is_interactive, - IndexFile* opt_previous_index, - const std::string& path, - const std::vector& args, - const std::optional& from) { +bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, + const std::vector &args, + const std::optional &from) { { std::lock_guard lock(vfs->mutex); - if (vfs->state[path].timestamp < write_time) { + if (prev->last_write_time < vfs->state[path].timestamp) { LOG_S(INFO) << "timestamp changed for " << path << (from ? " (via " + *from + ")" : std::string()); return true; } } - // Command-line arguments changed. - if (opt_previous_index) { - auto& prev_args = opt_previous_index->args; - if (prev_args != args) { - LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); - return true; - } + if (prev->args != args) { + LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); + return true; } return false; @@ -184,18 +171,15 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, std::optional write_time = LastWriteTime(path_to_index); if (!write_time) return true; - // FIXME Don't drop - if (!vfs->Mark(path_to_index, g_thread_id, 1)) + int reparse = vfs->Stamp(path_to_index, *write_time); + if (!vfs->Mark(path_to_index, g_thread_id, 1) && !reparse) return true; - int reparse; // request.is_interactive; prev = RawCacheLoad(path_to_index); if (!prev) reparse = 2; else { - reparse = vfs->Stamp(path_to_index, prev->last_write_time); - if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev, - path_to_index, entry.args, std::nullopt)) + if (CacheInvalid(vfs, prev.get(), path_to_index, entry.args, std::nullopt)) reparse = 2; int reparseForDep = g_config->index.reparseForDependency; if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded)) @@ -218,7 +202,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.is_interactive); } - for (const auto& dep : dependencies) + for (const auto &dep : dependencies) if (vfs->Mark(dep.first().str(), 0, 2) && (prev = RawCacheLoad(dep.first().str()))) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); @@ -273,7 +257,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, timer.stopTimer(); } - vfs->Reset(path_to_index); + vfs->Reset(path); if (entry.id >= 0) { std::lock_guard lock(project->mutex_); for (auto& dep : curr->dependencies) From ed1b221fab9841a66b0314988d7c138f19e8b265 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 17:13:41 -0700 Subject: [PATCH 132/378] Remove submodule doctest --- .gitmodules | 3 - CMakeLists.txt | 5 +- src/fuzzy_match.cc | 4 +- src/main.cc | 20 +--- src/match.cc | 14 --- src/project.cc | 251 ---------------------------------------- src/query.cc | 2 - src/test.cc | 1 - src/third_party_impl.cc | 2 - src/working_files.cc | 2 - third_party/doctest | 1 - 11 files changed, 4 insertions(+), 301 deletions(-) delete mode 100644 src/third_party_impl.cc delete mode 160000 third_party/doctest diff --git a/.gitmodules b/.gitmodules index fbe945c5f..b8c34ed07 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "third_party/rapidjson"] path = third_party/rapidjson url = https://github.com/miloyip/rapidjson -[submodule "third_party/doctest"] - path = third_party/doctest - url = https://github.com/onqtam/doctest diff --git a/CMakeLists.txt b/CMakeLists.txt index cfabeb329..614306188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,9 +143,7 @@ target_compile_definitions(ccls PRIVATE target_include_directories(ccls PRIVATE src third_party - third_party/rapidjson/include - third_party/loguru - third_party/doctest) + third_party/rapidjson/include) ### Install @@ -214,7 +212,6 @@ target_sources(ccls PRIVATE src/query.cc src/serializer.cc src/test.cc - src/third_party_impl.cc src/utils.cc src/working_files.cc) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 1d5d60581..187d91c4a 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -1,7 +1,5 @@ #include "fuzzy_match.h" -#include - #include #include #include @@ -133,6 +131,7 @@ int FuzzyMatcher::Match(std::string_view text) { return ret; } +#if 0 TEST_SUITE("fuzzy_match") { bool Ranks(std::string_view pat, std::vector texts) { FuzzyMatcher fuzzy(pat, 0); @@ -180,3 +179,4 @@ TEST_SUITE("fuzzy_match") { CHECK(Ranks("Int", {"int", "INT", "PRINT"})); } } +#endif diff --git a/src/main.cc b/src/main.cc index 495f8c477..11c7bb243 100644 --- a/src/main.cc +++ b/src/main.cc @@ -14,7 +14,6 @@ using namespace ccls; using namespace llvm; using namespace llvm::cl; -#include #include #include @@ -29,7 +28,6 @@ namespace { opt opt_help("h", desc("Alias for -help")); opt opt_verbose("v", desc("verbosity"), init(0)); opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests")); -opt opt_test_unit("test-unit", desc("run unit tests")); opt opt_init("init", desc("extra initialization options")); opt opt_log_file("log-file", desc("log"), value_desc("filename")); @@ -53,9 +51,7 @@ int main(int argc, char** argv) { if (opt_help) { PrintHelpMessage(); - // Also emit doctest help if --test-unit is passed. - if (!opt_test_unit) - return 0; + return 0; } pipeline::Init(); @@ -77,20 +73,6 @@ int main(int argc, char** argv) { atexit(CloseLog); } - if (opt_test_unit) { - language_server = false; - doctest::Context context; - std::vector args{argv[0]}; - if (opt_help) - args.push_back("-h"); - for (auto& arg : opt_extra) - args.push_back(arg.c_str()); - context.applyCommandLine(args.size(), args.data()); - int res = context.run(); - if (res != 0 || context.shouldExit()) - return res; - } - if (opt_test_index != "!") { language_server = false; if (!RunIndexTests(opt_test_index, sys::Process::StandardInIsUserInput())) diff --git a/src/match.cc b/src/match.cc index 178095d61..58a6f73d0 100644 --- a/src/match.cc +++ b/src/match.cc @@ -4,8 +4,6 @@ #include "pipeline.hh" using namespace ccls; -#include - // static std::optional Matcher::Create(const std::string& search) { /* @@ -75,15 +73,3 @@ bool GroupMatch::IsMatch(const std::string& value, return true; } - -TEST_SUITE("Matcher") { - TEST_CASE("sanity") { - // Matcher m("abc"); - // TODO: check case - // CHECK(m.IsMatch("abc")); - // CHECK(m.IsMatch("fooabc")); - // CHECK(m.IsMatch("abc")); - // CHECK(m.IsMatch("abcfoo")); - // CHECK(m.IsMatch("11a11b11c11")); - } -} diff --git a/src/project.cc b/src/project.cc index 202e7510c..dc729ad08 100644 --- a/src/project.cc +++ b/src/project.cc @@ -26,7 +26,6 @@ using namespace llvm; using namespace llvm::opt; #include -#include #include #if defined(__unix__) || defined(__APPLE__) @@ -493,253 +492,3 @@ void Project::Index(WorkingFiles* wfiles, // trigger refreshing semantic highlight for all working files. pipeline::Index("", {}, false); } - -TEST_SUITE("Project") { - void CheckFlags(const std::string& directory, const std::string& file, - std::vector raw, - std::vector expected) { - if (g_config) - delete g_config; - g_config = new Config; - g_config->clang.resourceDir = "/w/resource_dir/"; - ProjectConfig project; - project.project_dir = "/w/c/s/"; - - CompileCommandsEntry entry; - entry.directory = directory; - entry.args = raw; - entry.file = file; - Project::Entry result = - GetCompilationEntryFromCompileCommandEntry(&project, entry); - - if (result.args != expected) { - fprintf(stderr, "Raw: %s\n", StringJoin(raw).c_str()); - fprintf(stderr, "Expected: %s\n", StringJoin(expected).c_str()); - fprintf(stderr, "Actual: %s\n", StringJoin(result.args).c_str()); - } - REQUIRE(result.args == expected); - } - - void CheckFlags(std::vector raw, - std::vector expected) { - CheckFlags("/dir/", "file.cc", raw, expected); - } - - TEST_CASE("strip meta-compiler invocations") { - CheckFlags( - /* raw */ {"clang", "-lstdc++", "myfile.cc"}, - /* expected */ - {"clang", "-lstdc++", "/dir/myfile.cc", - "-resource-dir=/w/resource_dir/", "-working-directory=/dir/", - "-Wno-unknown-warning-option", "-fparse-all-comments"}); - - CheckFlags( - /* raw */ {"clang.exe"}, - /* expected */ - {"clang.exe", "-resource-dir=/w/resource_dir/", - "-working-directory=/dir/", "-Wno-unknown-warning-option", - "-fparse-all-comments"}); - } - -#ifdef _WIN32 - 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", "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-cl.exe", "/I./test", "E:/workdir/bar.cc"}, - /* expected */ - {"clang-cl.exe", "-working-directory=E:/workdir", - "/I&E:/workdir/./test", "E:/workdir/bar.cc", - "-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option", - "-fparse-all-comments"}); - - CheckFlags("E:/workdir", "E:/workdir/bar.cc", - /* raw */ - {"cl.exe", "/I../third_party/test/include", "E:/workdir/bar.cc"}, - /* expected */ - {"cl.exe", "-working-directory=E:/workdir", - "/I&E:/workdir/../third_party/test/include", - "E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/", - "-Wno-unknown-warning-option", "-fparse-all-comments"}); - } -#endif - - TEST_CASE("Path in args") { - CheckFlags( - "/home/user", "/home/user/foo/bar.c", - /* raw */ {"cc", "-O0", "foo/bar.c"}, - /* expected */ - {"cc", "-O0", "/home/user/foo/bar.c", "-resource-dir=/w/resource_dir/", - "-working-directory=/home/user", "-Wno-unknown-warning-option", - "-fparse-all-comments"}); - } - - TEST_CASE("Directory extraction") { - if (g_config) - delete g_config; - g_config = new Config; - ProjectConfig config; - config.project_dir = "/w/c/s/"; - - CompileCommandsEntry entry; - entry.directory = "/base"; - entry.args = {"clang", - "-I/a_absolute1", - "--foobar", - "-I", - "/a_absolute2", - "--foobar", - "-Ia_relative1", - "--foobar", - "-isystem", - "a_relative2", - "--foobar", - "-iquote/q_absolute1", - "--foobar", - "-iquote", - "/q_absolute2", - "--foobar", - "-iquoteq_relative1", - "--foobar", - "-iquote", - "q_relative2", - "--foobar", - "foo.cc"}; - entry.file = "foo.cc"; - Project::Entry result = - GetCompilationEntryFromCompileCommandEntry(&config, entry); - - std::unordered_set angle_expected{ - "/a_absolute1", "/a_absolute2", "/base/a_relative1", - "/base/a_relative2"}; - std::unordered_set quote_expected{ - "/a_absolute1", "/a_absolute2", "/base/a_relative1", - "/q_absolute1", "/q_absolute2", "/base/q_relative1", - "/base/q_relative2"}; - REQUIRE(config.angle_dirs == angle_expected); - REQUIRE(config.quote_dirs == quote_expected); - } - - TEST_CASE("Entry inference") { - Project p; - { - Project::Entry e; - e.args = {"arg1"}; - e.filename = "/a/b/c/d/bar.cc"; - p.entries.push_back(e); - } - { - Project::Entry e; - e.args = {"arg2"}; - e.filename = "/a/b/c/baz.cc"; - p.entries.push_back(e); - } - - // Guess at same directory level, when there are parent directories. - { - std::optional entry = - p.FindCompilationEntryForFile("/a/b/c/d/new.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg1"}); - } - - // Guess at same directory level, when there are child directories. - { - std::optional entry = - p.FindCompilationEntryForFile("/a/b/c/new.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg2"}); - } - - // Guess at new directory (use the closest parent directory). - { - std::optional entry = - p.FindCompilationEntryForFile("/a/b/c/new/new.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg2"}); - } - } - - TEST_CASE("Entry inference remaps file names") { - Project p; - { - Project::Entry e; - e.args = {"a", "b", "aaaa.cc", "d"}; - e.filename = "absolute/aaaa.cc"; - p.entries.push_back(e); - } - - { - std::optional entry = p.FindCompilationEntryForFile("ee.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"a", "b", "ee.cc", "d"}); - } - } - - TEST_CASE("Entry inference prefers same file endings") { - Project p; - { - Project::Entry e; - e.args = {"arg1"}; - e.filename = "common/simple_browsertest.cc"; - p.entries.push_back(e); - } - { - Project::Entry e; - e.args = {"arg2"}; - e.filename = "common/simple_unittest.cc"; - p.entries.push_back(e); - } - { - Project::Entry e; - e.args = {"arg3"}; - e.filename = "common/a/simple_unittest.cc"; - p.entries.push_back(e); - } - - // Prefer files with the same ending. - { - std::optional entry = - p.FindCompilationEntryForFile("my_browsertest.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg1"}); - } - { - std::optional entry = - p.FindCompilationEntryForFile("my_unittest.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg2"}); - } - { - std::optional entry = - p.FindCompilationEntryForFile("common/my_browsertest.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg1"}); - } - { - std::optional entry = - p.FindCompilationEntryForFile("common/my_unittest.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg2"}); - } - - // Prefer the same directory over matching file-ending. - { - std::optional entry = - p.FindCompilationEntryForFile("common/a/foo.cc"); - REQUIRE(entry.has_value()); - REQUIRE(entry->args == std::vector{"arg3"}); - } - } -} diff --git a/src/query.cc b/src/query.cc index b4f8c6136..d70140655 100644 --- a/src/query.cc +++ b/src/query.cc @@ -4,8 +4,6 @@ #include "serializer.h" #include "serializers/json.h" -#include - #include #include #include diff --git a/src/test.cc b/src/test.cc index 0c89f6884..cade7314b 100644 --- a/src/test.cc +++ b/src/test.cc @@ -6,7 +6,6 @@ #include "serializer.h" #include "utils.h" -#include #include #include #include diff --git a/src/third_party_impl.cc b/src/third_party_impl.cc deleted file mode 100644 index 572a07d31..000000000 --- a/src/third_party_impl.cc +++ /dev/null @@ -1,2 +0,0 @@ -#define DOCTEST_CONFIG_IMPLEMENT -#include diff --git a/src/working_files.cc b/src/working_files.cc index d2448daf9..1ad076c2b 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -3,8 +3,6 @@ #include "log.hh" #include "position.h" -#include - #include #include #include diff --git a/third_party/doctest b/third_party/doctest deleted file mode 160000 index b40b7e799..000000000 --- a/third_party/doctest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b40b7e799deabac916d631d181a7f19f3060acc5 From c6553c79ab9e4933e9566e1d508142fa966a16df Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 12:49:27 -0700 Subject: [PATCH 133/378] clangIndex --- index_tests/constructors/constructor.cc | 2 +- index_tests/constructors/destructor.cc | 2 +- .../constructors/implicit_constructor.cc | 6 +- index_tests/constructors/make_functions.cc | 4 +- .../declaration_vs_definition/class_member.cc | 16 +- .../class_member_static.cc | 16 +- .../func_associated_function_params.cc | 2 +- index_tests/enums/enum_class_decl.cc | 16 +- index_tests/enums/enum_decl.cc | 16 +- index_tests/enums/enum_inherit.cc | 30 +- index_tests/enums/enum_usage.cc | 16 +- index_tests/foobar.cc | 42 +- index_tests/lambdas/lambda.cc | 18 +- index_tests/macros/complex.cc | 4 +- index_tests/macros/foo.cc | 10 +- index_tests/multi_file/funky_enum.cc | 16 +- index_tests/multi_file/impl.cc | 14 - index_tests/multi_file/static.cc | 4 +- index_tests/namespaces/namespace_alias.cc | 21 +- index_tests/namespaces/namespace_reference.cc | 21 +- .../outline/static_function_in_type.cc | 7 +- index_tests/preprocessor/include_guard.cc | 2 +- .../implicit_variable_instantiation.cc | 40 +- .../templates/member_ref_in_template.cc | 33 +- ...ass_template_func_usage_folded_into_one.cc | 22 +- ...ace_template_type_usage_folded_into_one.cc | 58 ++- index_tests/templates/specialization.cc | 153 ++++++-- .../templates/specialized_func_definition.cc | 4 +- ...mplate_class_type_usage_folded_into_one.cc | 40 +- ...emplate_class_var_usage_folded_into_one.cc | 16 +- .../template_type_usage_folded_into_one.cc | 40 +- .../template_var_usage_folded_into_one.cc | 19 +- index_tests/types/anonymous_struct.cc | 30 +- index_tests/unions/union_decl.cc | 16 +- index_tests/unions/union_usage.cc | 14 - .../usage/func_called_from_macro_argument.cc | 4 +- index_tests/usage/func_usage_addr_func.cc | 2 +- index_tests/usage/func_usage_addr_method.cc | 8 +- index_tests/usage/func_usage_call_method.cc | 2 +- .../usage/func_usage_class_inline_var_def.cc | 14 - .../usage/func_usage_forward_decl_method.cc | 2 +- .../usage/type_usage_as_template_parameter.cc | 44 ++- ...ype_usage_as_template_parameter_complex.cc | 25 +- ...type_usage_as_template_parameter_simple.cc | 21 +- index_tests/usage/type_usage_declare_field.cc | 16 +- index_tests/usage/type_usage_declare_local.cc | 2 +- index_tests/usage/type_usage_declare_param.cc | 2 +- .../type_usage_declare_param_prototype.cc | 2 +- .../usage/type_usage_declare_qualifiers.cc | 2 +- index_tests/usage/type_usage_various.cc | 2 +- index_tests/usage/usage_inside_of_call.cc | 17 +- index_tests/usage/var_usage_call_function.cc | 2 +- index_tests/usage/var_usage_class_member.cc | 16 +- .../usage/var_usage_class_member_static.cc | 14 - index_tests/usage/var_usage_cstyle_cast.cc | 18 +- index_tests/usage/var_usage_func_parameter.cc | 2 +- index_tests/usage/var_usage_local.cc | 2 +- index_tests/usage/var_usage_shadowed_local.cc | 2 +- .../usage/var_usage_shadowed_parameter.cc | 2 +- index_tests/vars/class_member.cc | 16 +- index_tests/vars/class_static_member.cc | 17 +- .../vars/class_static_member_decl_only.cc | 16 +- index_tests/vars/deduce_auto_type.cc | 12 +- index_tests/vars/function_local.cc | 2 +- index_tests/vars/function_param.cc | 2 +- index_tests/vars/function_shadow_local.cc | 2 +- index_tests/vars/function_shadow_param.cc | 2 +- .../vars/type_instance_on_using_type.cc | 2 +- src/indexer.cc | 366 ++++++++++++------ src/message_handler.cc | 18 +- src/method.cc | 4 +- src/method.h | 2 +- src/pipeline.cc | 2 +- 73 files changed, 765 insertions(+), 691 deletions(-) diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index 46f44dbec..b444e162d 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -42,7 +42,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [10983126130596230582, 17165811951126099095], "uses": [], "callees": [] }], diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index c722bab0e..32bfd0d8a 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -47,7 +47,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [1893354193220338759], "uses": [], "callees": [] }, { diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index abcbd9a5d..e84ae3ffe 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -25,7 +25,7 @@ void Make() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [449111627548814328, 17097499197730163115], "uses": [], "callees": [] }, { @@ -77,10 +77,10 @@ void Make() { "storage": 0 }, { "usr": 17097499197730163115, - "detailed_name": "auto foo1", + "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", - "hover": "auto foo1 = Type()", + "hover": "Type foo1 = Type()", "declarations": [], "spell": "7:8-7:12|3957104924306079513|3|2", "extent": "7:3-7:21|3957104924306079513|3|0", diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index ecce8489c..c5fc57889 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -150,7 +150,7 @@ OUTPUT: make_functions.cc "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [3908732770590594660], "uses": ["17:3-17:14|0|1|8228"], "callees": [] }, { @@ -182,7 +182,7 @@ OUTPUT: make_functions.cc "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [8463700030555379526], "uses": ["14:3-14:13|0|1|8228", "15:3-15:13|0|1|8228", "16:3-16:13|0|1|8228"], "callees": [] }], diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index 37649b698..3478c5e83 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -7,21 +7,7 @@ class Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [9736582033442720743], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 53, "detailed_name": "", diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 24570fcb8..5434f6cbc 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -9,21 +9,7 @@ int Foo::foo; { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [8942920329766232482, 8942920329766232482], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 53, "detailed_name": "", diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index eb8071c0f..a399d5d95 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -22,7 +22,7 @@ int foo(int a, int b) { return 0; } "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [14555488990109936920, 10963664335057337329], "uses": [], "callees": [] }], diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index b417eb0b4..5e2ad16c5 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -9,21 +9,7 @@ enum class Foo : uint8_t { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [439339022761937396, 15962370213938840720], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 2010430204259339553, "detailed_name": "typedef unsigned char uint8_t", diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 5719a2618..da4cfc64c 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -8,21 +8,7 @@ enum Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [439339022761937396, 15962370213938840720], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "enum Foo {\n}", diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index d0535609d..fd36cf565 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -15,35 +15,7 @@ enum class E : int32_t { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 2986879766914123941, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [16614320383091394267, 16847439761518576294], - "uses": [], - "callees": [] - }, { - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [439339022761937396, 15962370213938840720], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 2986879766914123941, "detailed_name": "enum class E : int32_t {\n}", diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index 1ea1d3bde..b086892bc 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -10,21 +10,7 @@ Foo x = Foo::A; { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [439339022761937396, 15962370213938840720], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "enum class Foo : int {\n}", diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index bb21a22a7..24ca7afb2 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -31,6 +31,23 @@ Foo b; "vars": [], "instances": [], "uses": ["9:5-9:6|0|1|4"] + }, { + "usr": 7074603899792463171, + "detailed_name": "Inner", + "qual_name_offset": 0, + "short_name": "Inner", + "kind": 26, + "declarations": [], + "spell": "6:3-6:18|0|1|2", + "extent": "6:3-6:18|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [16721564935990383768], + "uses": [] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", @@ -46,8 +63,25 @@ Foo b; "types": [13938528237873543349], "funcs": [], "vars": [], - "instances": [12028309045033782423], + "instances": [], "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] + }, { + "usr": 11976530632376795217, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 26, + "declarations": [], + "spell": "4:1-7:2|0|1|2", + "extent": "4:1-7:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [12028309045033782423], + "uses": [] }, { "usr": 13892793056005362145, "detailed_name": "enum B {\n}", @@ -80,7 +114,7 @@ Foo b; "types": [], "funcs": [], "vars": [], - "instances": [16721564935990383768], + "instances": [], "uses": ["9:9-9:14|10528472276654770367|2|4"] }], "usr2var": [{ @@ -91,7 +125,7 @@ Foo b; "declarations": [], "spell": "10:8-10:9|0|1|2", "extent": "10:1-10:9|0|1|0", - "type": 10528472276654770367, + "type": 11976530632376795217, "uses": [], "kind": 13, "storage": 0 @@ -103,7 +137,7 @@ Foo b; "declarations": [], "spell": "9:15-9:16|0|1|2", "extent": "9:1-9:16|0|1|0", - "type": 13938528237873543349, + "type": 7074603899792463171, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index d37380102..a6284a4bf 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -29,7 +29,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [12666114896600231317, 2981279427664991319], "uses": [], "callees": [] }, { @@ -67,27 +67,29 @@ void foo() { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, + "kind": 26, "declarations": [], + "spell": "4:22-4:23|4259594751088586730|3|2", + "extent": "4:22-4:23|4259594751088586730|3|0", "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [2981279427664991319], "uses": [] }], "usr2var": [{ "usr": 2981279427664991319, - "detailed_name": "auto dosomething", - "qual_name_offset": 5, + "detailed_name": "(lambda) dosomething", + "qual_name_offset": 9, "short_name": "dosomething", - "hover": "auto dosomething = [&x] (int y) {\n ++x;\n ++y;\n }\n", + "hover": "(lambda) dosomething = [&x](int y) {\n ++x;\n ++y;\n }", "declarations": [], "spell": "4:8-4:19|4259594751088586730|3|2", "extent": "4:3-7:4|4259594751088586730|3|0", - "type": 0, + "type": 14635009347499519042, "uses": ["9:3-9:14|4259594751088586730|3|4", "10:3-10:14|4259594751088586730|3|4", "11:3-11:14|4259594751088586730|3|4"], "kind": 13, "storage": 0 @@ -109,6 +111,8 @@ void foo() { "qual_name_offset": 4, "short_name": "y", "declarations": [], + "spell": "4:31-4:32|17926497908620168464|3|2", + "extent": "4:27-4:32|17926497908620168464|3|0", "type": 0, "uses": ["6:7-6:8|17926497908620168464|3|28"], "kind": 253, diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index f014946e3..38c8e22bd 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -83,10 +83,10 @@ FOO(make1(), make2); "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", - "hover": "#define FOO", + "hover": "#define FOO(aaa, bbb) \\\n int a();\\\n int a() { return aaa + bbb; }", "declarations": [], "spell": "1:9-1:12|0|1|2", - "extent": "1:9-1:12|0|1|2", + "extent": "1:9-3:32|0|1|0", "type": 0, "uses": ["12:1-12:20|0|1|4"], "kind": 255, diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 50f38b941..c2e05248c 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -67,10 +67,10 @@ int x = A; "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", - "hover": "#define A", + "hover": "#define A 5", "declarations": [], "spell": "1:9-1:10|0|1|2", - "extent": "1:9-1:10|0|1|2", + "extent": "1:9-1:12|0|1|0", "type": 0, "uses": ["8:9-8:10|0|1|4"], "kind": 255, @@ -80,10 +80,10 @@ int x = A; "detailed_name": "DISALLOW", "qual_name_offset": 0, "short_name": "DISALLOW", - "hover": "#define DISALLOW", + "hover": "#define DISALLOW(type) type(type&&) = delete;", "declarations": [], "spell": "2:9-2:17|0|1|2", - "extent": "2:9-2:17|0|1|2", + "extent": "2:9-2:46|0|1|0", "type": 0, "uses": ["5:3-5:16|0|1|4"], "kind": 255, @@ -93,7 +93,7 @@ int x = A; "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", - "hover": "int x = 5", + "hover": "int x = ", "declarations": [], "spell": "8:5-8:6|0|1|2", "extent": "8:1-1:1|0|1|0", diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 29963edfc..f49c62977 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -10,21 +10,7 @@ OUTPUT: funky_enum.h { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [439339022761937396, 15962370213938840720, 8524995777615948802], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, "detailed_name": "", diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 48cbb17a3..8501799bc 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -10,20 +10,6 @@ OUTPUT: header.h "includes": [], "skipped_ranges": [], "usr2func": [{ - "usr": 4481210672785600703, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [6141718166919284735, 17716334512218775320, 7285646116511901840], - "uses": [], - "callees": [] - }, { "usr": 11650481237659640387, "detailed_name": "void Foo1()", "qual_name_offset": 5, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index c7dcd941b..bc5e50a40 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -51,8 +51,8 @@ OUTPUT: static.cc "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, - "detailed_name": "static void Buffer::CreateSharedBuffer()", - "qual_name_offset": 12, + "detailed_name": "void Buffer::CreateSharedBuffer()", + "qual_name_offset": 5, "short_name": "CreateSharedBuffer", "kind": 6, "storage": 0, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 88f1adf34..32c420fa0 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -31,21 +31,7 @@ void func() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] - }, { - "usr": 14450849931009540802, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [15042442838933090518], + "vars": [6030927277961448585, 7657277353101371136], "uses": [], "callees": [] }], @@ -106,7 +92,10 @@ void func() { "derived": [], "types": [], "funcs": [], - "vars": [], + "vars": [{ + "L": 15042442838933090518, + "R": -1 + }], "instances": [], "uses": ["9:27-9:30|17805385787823406700|2|4", "12:21-12:24|17805385787823406700|2|4"] }, { diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index c412f7c08..323c6d918 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -30,20 +30,6 @@ void Runner() { "vars": [], "uses": [], "callees": [] - }, { - "usr": 11072669167287398027, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [12898699035586282159], - "uses": [], - "callees": [] }, { "usr": 17328473273923617489, "detailed_name": "void ns::Accept(int a)", @@ -57,7 +43,7 @@ void Runner() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [3649375698083002347], "uses": ["7:7-7:13|11072669167287398027|2|8228", "9:3-9:9|11072669167287398027|2|8228"], "callees": [] }], @@ -88,7 +74,10 @@ void Runner() { "derived": [], "types": [], "funcs": [17328473273923617489], - "vars": [], + "vars": [{ + "L": 12898699035586282159, + "R": -1 + }], "instances": [], "uses": ["7:3-7:5|0|1|4", "7:14-7:16|0|1|4", "8:19-8:21|0|1|4"] }], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 74a75735e..6f6818e0a 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -85,18 +85,19 @@ OUTPUT: static_function_in_type.cc "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "static void ns::Foo::Register(ns::Manager *)", - "qual_name_offset": 12, + "detailed_name": "void Foo::Register(ns::Manager *m)", + "qual_name_offset": 5, "short_name": "Register", "kind": 6, "storage": 0, + "comments": "static", "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|514", "extent": "5:1-6:2|11072669167287398027|2|0", "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [13569879755236306838], "uses": [], "callees": [] }], diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 9a2edd7d8..5b4ef8076 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -18,7 +18,7 @@ "hover": "#define FOO", "declarations": [], "spell": "2:9-2:12|0|1|2", - "extent": "2:9-2:12|0|1|2", + "extent": "2:9-2:12|0|1|0", "type": 0, "uses": [], "kind": 255, diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 0c356b628..e4a75de56 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -19,35 +19,7 @@ namespace ns { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 11072669167287398027, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [12898699035586282159, 9008550860229740818], - "uses": [], - "callees": [] - }, { - "usr": 12688716854043726585, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [4731849186641714451, 4731849186641714451], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 53, "detailed_name": "", @@ -92,7 +64,13 @@ namespace ns { "derived": [], "types": [1532099849728741556, 12688716854043726585], "funcs": [], - "vars": [], + "vars": [{ + "L": 12898699035586282159, + "R": -1 + }, { + "L": 9008550860229740818, + "R": -1 + }], "instances": [], "uses": [] }, { @@ -118,7 +96,7 @@ namespace ns { "detailed_name": "static constexpr ns::VarType ns::Holder::static_var", "qual_name_offset": 29, "short_name": "static_var", - "hover": "static constexpr ns::VarType ns::Holder::static_var = (ns::VarType)0", + "hover": "static constexpr ns::VarType ns::Holder::static_var = (VarType)0x0", "declarations": ["6:30-6:40|12688716854043726585|2|513"], "spell": "10:37-10:47|12688716854043726585|2|514", "extent": "9:3-10:47|11072669167287398027|2|0", diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index f136e2539..a9d7f9e20 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -41,20 +41,6 @@ void foo() { "vars": [], "uses": [], "callees": [] - }, { - "usr": 8402783583255987702, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [5866801090710377175], - "uses": [], - "callees": [] }, { "usr": 8905286151237717330, "detailed_name": "void C::bar()", @@ -90,6 +76,23 @@ void foo() { }], "instances": [], "uses": [] + }, { + "usr": 14750650276757822712, + "detailed_name": "T", + "qual_name_offset": 0, + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "1:11-1:18|8402783583255987702|2|2", + "extent": "1:11-1:18|8402783583255987702|2|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [5866801090710377175], + "uses": [] }], "usr2var": [{ "usr": 5866801090710377175, @@ -99,7 +102,7 @@ void foo() { "declarations": [], "spell": "3:5-3:6|8402783583255987702|2|514", "extent": "3:3-3:6|8402783583255987702|2|0", - "type": 0, + "type": 14750650276757822712, "uses": [], "kind": 8, "storage": 0 diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 426d5be3f..909cce9e3 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -32,20 +32,6 @@ namespace ns { "vars": [], "uses": ["10:21-10:24|14042997404480181958|2|36", "11:22-11:25|14042997404480181958|2|36"], "callees": [] - }, { - "usr": 11072669167287398027, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [15768138241775955040, 3182917058194750998], - "uses": [], - "callees": [] }], "usr2type": [{ "usr": 53, @@ -74,7 +60,13 @@ namespace ns { "derived": [], "types": [14042997404480181958], "funcs": [], - "vars": [], + "vars": [{ + "L": 15768138241775955040, + "R": -1 + }, { + "L": 3182917058194750998, + "R": -1 + }], "instances": [], "uses": [] }, { diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index fada88f9b..aeb397deb 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -11,22 +11,42 @@ namespace ns { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 11072669167287398027, - "detailed_name": "", + "usr2func": [], + "usr2type": [{ + "usr": 3948666349864691553, + "detailed_name": "Foo", "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, + "short_name": "Foo", + "kind": 26, "declarations": [], - "declaring_type": 0, + "spell": "2:3-3:15|11072669167287398027|2|2", + "extent": "2:3-3:15|11072669167287398027|2|0", + "alias_of": 0, "bases": [], "derived": [], - "vars": [15768138241775955040, 3182917058194750998], - "uses": [], - "callees": [] - }], - "usr2type": [{ + "types": [], + "funcs": [], + "vars": [], + "instances": [3182917058194750998], + "uses": [] + }, { + "usr": 8224244241460152567, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 26, + "declarations": [], + "spell": "2:3-3:15|11072669167287398027|2|2", + "extent": "2:3-3:15|11072669167287398027|2|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [15768138241775955040], + "uses": [] + }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {\n}", "qual_name_offset": 10, @@ -38,7 +58,13 @@ namespace ns { "derived": [], "types": [14042997404480181958], "funcs": [], - "vars": [], + "vars": [{ + "L": 15768138241775955040, + "R": -1 + }, { + "L": 3182917058194750998, + "R": -1 + }], "instances": [], "uses": [] }, { @@ -56,7 +82,7 @@ namespace ns { "types": [], "funcs": [], "vars": [], - "instances": [15768138241775955040, 3182917058194750998], + "instances": [], "uses": ["5:3-5:6|11072669167287398027|2|4", "6:3-6:6|11072669167287398027|2|4"] }], "usr2var": [{ @@ -67,7 +93,7 @@ namespace ns { "declarations": [], "spell": "6:13-6:14|11072669167287398027|2|514", "extent": "6:3-6:14|11072669167287398027|2|0", - "type": 14042997404480181958, + "type": 3948666349864691553, "uses": [], "kind": 13, "storage": 0 @@ -79,7 +105,7 @@ namespace ns { "declarations": [], "spell": "5:12-5:13|11072669167287398027|2|514", "extent": "5:3-5:13|11072669167287398027|2|0", - "type": 14042997404480181958, + "type": 8224244241460152567, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index deca63d96..2acb713fb 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -75,20 +75,6 @@ void foo(float Value); "vars": [], "uses": [], "callees": [] - }, { - "usr": 9201299975592934124, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [15477793821005285152, 4917621020431490070], - "uses": [], - "callees": [] }, { "usr": 17498190318698490707, "detailed_name": "void foo(T Value)", @@ -102,7 +88,7 @@ void foo(float Value); "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [17826688417349629938], "uses": [], "callees": [] }, { @@ -135,6 +121,23 @@ void foo(float Value); "vars": [], "instances": [13914496963221806870], "uses": [] + }, { + "usr": 218068462278884837, + "detailed_name": "template class function {}", + "qual_name_offset": 46, + "short_name": "function", + "kind": 5, + "declarations": [], + "spell": "5:7-5:15|0|1|2", + "extent": "4:1-5:30|0|1|0", + "alias_of": 0, + "bases": [15019211479263750068], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] }, { "usr": 1663022413889915338, "detailed_name": "template<> class vector> {}", @@ -152,6 +155,23 @@ void foo(float Value); "vars": [], "instances": [15931696253641284761], "uses": [] + }, { + "usr": 3231449734830406187, + "detailed_name": "function", + "qual_name_offset": 0, + "short_name": "function", + "kind": 26, + "declarations": [], + "spell": "4:1-5:30|0|1|2", + "extent": "4:1-5:30|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2933643612409209903], + "uses": [] }, { "usr": 5760043510674081814, "detailed_name": "struct Z1 {}", @@ -180,11 +200,11 @@ void foo(float Value); "extent": "12:1-14:2|0|1|0", "alias_of": 0, "bases": [], - "derived": [1663022413889915338], + "derived": [16155717907537731864, 1663022413889915338], "types": [], "funcs": [18107614608385228556], "vars": [], - "instances": [5792869548777559988, 86949563628772958, 3566687051827176322], + "instances": [], "uses": ["17:7-17:13|0|1|4", "26:7-26:13|0|1|4", "30:1-30:7|0|1|4", "31:1-31:7|0|1|4", "32:1-32:7|0|1|4", "33:1-33:7|0|1|4"] }, { "usr": 9201299975592934124, @@ -220,6 +240,57 @@ void foo(float Value); "vars": [], "instances": [], "uses": ["26:14-26:16|0|1|4", "33:8-33:10|0|1|4"] + }, { + "usr": 11153492883079050853, + "detailed_name": "vector", + "qual_name_offset": 0, + "short_name": "vector", + "kind": 26, + "declarations": [], + "spell": "16:1-17:20|0|1|2", + "extent": "16:1-17:20|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [86949563628772958], + "uses": [] + }, { + "usr": 13322943937025195708, + "detailed_name": "vector", + "qual_name_offset": 0, + "short_name": "vector", + "kind": 26, + "declarations": [], + "spell": "11:1-14:2|0|1|2", + "extent": "11:1-14:2|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [5792869548777559988], + "uses": [] + }, { + "usr": 14111105212951082474, + "detailed_name": "T", + "qual_name_offset": 0, + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "38:11-38:21|17498190318698490707|3|2", + "extent": "38:11-38:21|17498190318698490707|3|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [17826688417349629938], + "uses": [] }, { "usr": 15019211479263750068, "detailed_name": "class function", @@ -229,12 +300,29 @@ void foo(float Value); "declarations": ["2:7-2:15|0|1|1"], "alias_of": 0, "bases": [], - "derived": [], + "derived": [218068462278884837], "types": [], "funcs": [], "vars": [], - "instances": [2933643612409209903], + "instances": [], "uses": ["5:7-5:15|0|1|4", "7:1-7:9|0|1|4"] + }, { + "usr": 15440970074034693939, + "detailed_name": "vector", + "qual_name_offset": 0, + "short_name": "vector", + "kind": 26, + "declarations": [], + "spell": "21:1-21:26|0|1|2", + "extent": "21:1-21:26|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [3566687051827176322], + "uses": [] }, { "usr": 15695704394170757108, "detailed_name": "class allocator", @@ -250,6 +338,23 @@ void foo(float Value); "vars": [], "instances": [], "uses": ["11:39-11:48|0|1|4"] + }, { + "usr": 16155717907537731864, + "detailed_name": "template class vector> {}", + "qual_name_offset": 28, + "short_name": "vector", + "kind": 5, + "declarations": [], + "spell": "17:7-17:13|0|1|2", + "extent": "16:1-17:20|0|1|0", + "alias_of": 0, + "bases": [7440942986741176606], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": [] }], "usr2var": [{ "usr": 86949563628772958, @@ -259,7 +364,7 @@ void foo(float Value); "declarations": [], "spell": "31:14-31:17|0|1|2", "extent": "31:1-31:17|0|1|0", - "type": 7440942986741176606, + "type": 11153492883079050853, "uses": [], "kind": 13, "storage": 0 @@ -271,7 +376,7 @@ void foo(float Value); "declarations": [], "spell": "7:21-7:22|0|1|2", "extent": "7:1-7:22|0|1|0", - "type": 15019211479263750068, + "type": 3231449734830406187, "uses": [], "kind": 13, "storage": 0 @@ -283,7 +388,7 @@ void foo(float Value); "declarations": [], "spell": "32:12-32:15|0|1|2", "extent": "32:1-32:15|0|1|0", - "type": 7440942986741176606, + "type": 15440970074034693939, "uses": [], "kind": 13, "storage": 0 @@ -308,7 +413,7 @@ void foo(float Value); "declarations": [], "spell": "30:14-30:16|0|1|2", "extent": "30:1-30:16|0|1|0", - "type": 7440942986741176606, + "type": 13322943937025195708, "uses": [], "kind": 13, "storage": 0 @@ -358,7 +463,7 @@ void foo(float Value); "declarations": [], "spell": "39:12-39:17|17498190318698490707|3|514", "extent": "39:10-39:17|17498190318698490707|3|0", - "type": 0, + "type": 14111105212951082474, "uses": [], "kind": 253, "storage": 0 diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 94b336536..d23cf26a6 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -24,8 +24,8 @@ void Template::Foo() {} "skipped_ranges": [], "usr2func": [{ "usr": 6995843774014807426, - "detailed_name": "void Template::Foo()", - "qual_name_offset": 5, + "detailed_name": "template <> void Template::Foo()", + "qual_name_offset": 31, "short_name": "Foo", "kind": 6, "storage": 0, diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index ddc6495ee..37377cbc7 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -50,6 +50,23 @@ VarDecl b "vars": [], "instances": [], "uses": ["9:5-9:6|0|1|4"] + }, { + "usr": 7074603899792463171, + "detailed_name": "Inner", + "qual_name_offset": 0, + "short_name": "Inner", + "kind": 26, + "declarations": [], + "spell": "6:3-6:18|0|1|2", + "extent": "6:3-6:18|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [16721564935990383768], + "uses": [] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", @@ -99,8 +116,25 @@ VarDecl b "types": [], "funcs": [], "vars": [], - "instances": [16721564935990383768, 12028309045033782423], + "instances": [], "uses": ["9:9-9:14|10528472276654770367|2|4", "10:9-10:14|10528472276654770367|2|4"] + }, { + "usr": 15961308565836244174, + "detailed_name": "Inner", + "qual_name_offset": 0, + "short_name": "Inner", + "kind": 26, + "declarations": [], + "spell": "6:3-6:18|0|1|2", + "extent": "6:3-6:18|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [12028309045033782423], + "uses": [] }], "usr2var": [{ "usr": 12028309045033782423, @@ -110,7 +144,7 @@ VarDecl b "declarations": [], "spell": "10:15-10:16|0|1|2", "extent": "10:1-10:16|0|1|0", - "type": 13938528237873543349, + "type": 15961308565836244174, "uses": [], "kind": 13, "storage": 0 @@ -122,7 +156,7 @@ VarDecl b "declarations": [], "spell": "9:15-9:16|0|1|2", "extent": "9:1-9:16|0|1|0", - "type": 13938528237873543349, + "type": 7074603899792463171, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index e6b7b4a6e..a6a84ad86 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -11,21 +11,7 @@ int b = Foo::var; { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 10528472276654770367, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [13545144895171991916], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 53, "detailed_name": "", diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index c4dbcd5b4..0ecebac89 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -11,6 +11,23 @@ Foo b; "skipped_ranges": [], "usr2func": [], "usr2type": [{ + "usr": 5123806965838456033, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 26, + "declarations": [], + "spell": "1:1-2:13|0|1|2", + "extent": "1:1-2:13|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [16721564935990383768], + "uses": [] + }, { "usr": 10528472276654770367, "detailed_name": "class Foo {}", "qual_name_offset": 6, @@ -25,8 +42,25 @@ Foo b; "types": [], "funcs": [], "vars": [], - "instances": [16721564935990383768, 12028309045033782423], + "instances": [], "uses": ["4:1-4:4|0|1|4", "5:1-5:4|0|1|4"] + }, { + "usr": 14134940367505932005, + "detailed_name": "Foo", + "qual_name_offset": 0, + "short_name": "Foo", + "kind": 26, + "declarations": [], + "spell": "1:1-2:13|0|1|2", + "extent": "1:1-2:13|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [12028309045033782423], + "uses": [] }], "usr2var": [{ "usr": 12028309045033782423, @@ -36,7 +70,7 @@ Foo b; "declarations": [], "spell": "5:11-5:12|0|1|2", "extent": "5:1-5:12|0|1|0", - "type": 10528472276654770367, + "type": 14134940367505932005, "uses": [], "kind": 13, "storage": 0 @@ -48,7 +82,7 @@ Foo b; "declarations": [], "spell": "4:10-4:11|0|1|2", "extent": "4:1-4:11|0|1|0", - "type": 10528472276654770367, + "type": 5123806965838456033, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index f64125be3..b4ef49773 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -53,6 +53,23 @@ UnexposedDecl var "vars": [], "instances": [16721564935990383768], "uses": ["7:1-7:2|0|1|4", "7:11-7:12|0|1|4"] + }, { + "usr": 11919899838872947844, + "detailed_name": "T", + "qual_name_offset": 0, + "short_name": "T", + "kind": 26, + "declarations": [], + "spell": "4:10-4:20|0|1|2", + "extent": "4:10-4:20|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [8096973118640070624], + "uses": [] }, { "usr": 13892793056005362145, "detailed_name": "enum B {\n}", @@ -80,7 +97,7 @@ UnexposedDecl var "declarations": [], "spell": "5:3-5:6|0|1|2", "extent": "5:1-5:12|0|1|0", - "type": 0, + "type": 11919899838872947844, "uses": ["7:7-7:10|0|1|12", "8:7-8:10|0|1|12"], "kind": 13, "storage": 0 diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 56f38ebf2..370d30e54 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -8,35 +8,7 @@ union vector3 { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 1428566502523368801, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [3348817847649945564, 4821094820988543895, 15292551660437765731], - "uses": [], - "callees": [] - }, { - "usr": 17937907487590875128, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [1963212417280098348], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 82, "detailed_name": "", diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 3745475b2..b7500dbc8 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -8,21 +8,7 @@ union Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 8501689086387244262, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [9529311430721959843, 8804696910588009104], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 37, "detailed_name": "", diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 4b36fa873..148bf27b5 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -17,20 +17,6 @@ void act(Foo*) { "includes": [], "skipped_ranges": [], "usr2func": [{ - "usr": 8501689086387244262, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [9529311430721959843, 8804696910588009104], - "uses": [], - "callees": [] - }, { "usr": 13982179977217945200, "detailed_name": "void act(Foo *)", "qual_name_offset": 5, diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 45e3af74d..3215fa23d 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -48,10 +48,10 @@ void caller() { "detailed_name": "MACRO_CALL", "qual_name_offset": 0, "short_name": "MACRO_CALL", - "hover": "#define MACRO_CALL", + "hover": "#define MACRO_CALL(e) e", "declarations": [], "spell": "1:9-1:19|0|1|2", - "extent": "1:9-1:19|0|1|2", + "extent": "1:9-1:24|0|1|0", "type": 0, "uses": ["6:3-6:33|0|1|4"], "kind": 255, diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 68dd2c212..49afc9ac3 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -41,7 +41,7 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [16088407831770615719], "uses": [], "callees": [] }, { diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 9c435a9a8..27508d544 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -25,7 +25,7 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [4636142131003982569], "uses": [], "callees": [] }, { @@ -63,10 +63,10 @@ void user() { }], "usr2var": [{ "usr": 4636142131003982569, - "detailed_name": "auto x", - "qual_name_offset": 5, + "detailed_name": "void (Foo::*)() x", + "qual_name_offset": 16, "short_name": "x", - "hover": "auto x = &Foo::Used", + "hover": "void (Foo::*)() x = &Foo::Used", "declarations": [], "spell": "6:8-6:9|9376923949268137283|3|2", "extent": "6:3-6:22|9376923949268137283|3|0", diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index db90d666b..3a78b2fd0 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -25,7 +25,7 @@ void user() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [14045150712868309451], "uses": [], "callees": [] }, { diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 45c77afce..0a94d6e6c 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -27,20 +27,6 @@ class Foo { "vars": [], "uses": ["6:11-6:17|0|1|36"], "callees": [] - }, { - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [4220150017963593039], - "uses": [], - "callees": [] }], "usr2type": [{ "usr": 53, diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index b00ff4fa8..e1ee4d453 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -24,7 +24,7 @@ void usage() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [16229832321010999607], "uses": [], "callees": [] }, { diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 56da2161c..c8a5e6c37 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -28,7 +28,7 @@ unique_ptr* return_type() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [3364438781074774169], "uses": [], "callees": [] }], @@ -47,8 +47,25 @@ unique_ptr* return_type() { "types": [], "funcs": [], "vars": [], - "instances": [12857919739649552168, 18075066956054788088, 3364438781074774169], + "instances": [], "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|0|1|4"] + }, { + "usr": 4186953406371619898, + "detailed_name": "unique_ptr", + "qual_name_offset": 0, + "short_name": "unique_ptr", + "kind": 26, + "declarations": [], + "spell": "1:1-2:20|0|1|2", + "extent": "1:1-2:20|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [18075066956054788088, 3364438781074774169], + "uses": [] }, { "usr": 4750332761459066907, "detailed_name": "struct S {}", @@ -66,6 +83,23 @@ unique_ptr* return_type() { "vars": [], "instances": [], "uses": ["7:19-7:20|0|1|4", "9:12-9:13|0|1|4", "10:14-10:15|0|1|4"] + }, { + "usr": 16848604152578034754, + "detailed_name": "unique_ptr", + "qual_name_offset": 0, + "short_name": "unique_ptr", + "kind": 26, + "declarations": [], + "spell": "1:1-2:20|0|1|2", + "extent": "1:1-2:20|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [12857919739649552168], + "uses": [] }], "usr2var": [{ "usr": 3364438781074774169, @@ -75,7 +109,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "10:18-10:23|16359708726068806331|3|2", "extent": "10:3-10:23|16359708726068806331|3|0", - "type": 3286534761799572592, + "type": 4186953406371619898, "uses": [], "kind": 13, "storage": 0 @@ -87,7 +121,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "6:25-6:27|0|1|2", "extent": "6:1-6:27|0|1|0", - "type": 3286534761799572592, + "type": 16848604152578034754, "uses": [], "kind": 13, "storage": 2 @@ -99,7 +133,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "7:22-7:24|0|1|2", "extent": "7:1-7:24|0|1|0", - "type": 3286534761799572592, + "type": 4186953406371619898, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 76c284710..1af6dbdfa 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -144,7 +144,7 @@ unique_ptr* Foo::foo() { return nullptr; } "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [500112618220246], "uses": [], "callees": [] }], @@ -191,7 +191,7 @@ unique_ptr* Foo::foo() { return nullptr; } "types": [], "funcs": [], "vars": [], - "instances": [2933643612409209903, 500112618220246], + "instances": [], "uses": ["15:8-15:18|0|1|4", "15:19-15:29|0|1|4", "33:1-33:11|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:3-54:13|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] }, { "usr": 15041163540773201510, @@ -210,6 +210,23 @@ unique_ptr* Foo::foo() { return nullptr; } "vars": [], "instances": [], "uses": ["79:21-79:24|0|1|4"] + }, { + "usr": 18153735331422331128, + "detailed_name": "unique_ptr", + "qual_name_offset": 0, + "short_name": "unique_ptr", + "kind": 26, + "declarations": [], + "spell": "1:1-2:17|0|1|2", + "extent": "1:1-2:17|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [2933643612409209903, 500112618220246], + "uses": [] }], "usr2var": [{ "usr": 500112618220246, @@ -219,7 +236,7 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": [], "spell": "54:39-54:44|18320186404467436976|3|2", "extent": "54:3-54:44|18320186404467436976|3|0", - "type": 14209198335088845323, + "type": 18153735331422331128, "uses": [], "kind": 13, "storage": 0 @@ -229,7 +246,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 42, "short_name": "f", "declarations": ["15:43-15:44|0|1|1"], - "type": 14209198335088845323, + "type": 18153735331422331128, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 75aed976a..84ebefe24 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -26,8 +26,25 @@ static unique_ptr foo; "types": [], "funcs": [], "vars": [], - "instances": [3398408600781120939], + "instances": [], "uses": ["6:8-6:18|0|1|4"] + }, { + "usr": 4186953406371619898, + "detailed_name": "unique_ptr", + "qual_name_offset": 0, + "short_name": "unique_ptr", + "kind": 26, + "declarations": [], + "spell": "1:1-2:20|0|1|2", + "extent": "1:1-2:20|0|1|0", + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [3398408600781120939], + "uses": [] }, { "usr": 4750332761459066907, "detailed_name": "struct S", @@ -52,7 +69,7 @@ static unique_ptr foo; "declarations": [], "spell": "6:22-6:25|0|1|2", "extent": "6:1-6:25|0|1|0", - "type": 3286534761799572592, + "type": 4186953406371619898, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 87e2514df..1d8fcb26e 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -11,21 +11,7 @@ struct Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [14314859014962085433, 14727441168849658842], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 8508299082070213750, "detailed_name": "struct ImplementedType {}", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index b4462a95e..09af0afe9 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -24,7 +24,7 @@ void Foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [16374832544037266261, 2580122838476012357], "uses": [], "callees": [] }], diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 7ccd5eef8..583c1c08d 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -21,7 +21,7 @@ void foo(ForwardType* f, ImplementedType a) {} "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [13058491096576226774, 11055777568039014776], "uses": [], "callees": [] }], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 3326f28e0..0d84a6449 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -26,7 +26,7 @@ void foo(Foo* f, Foo*) {} "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [13823260660189154978], "uses": [], "callees": [] }], diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index df3b9b42a..ec88c76f2 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -24,7 +24,7 @@ void foo(Type& a0, const Type& a1) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], "uses": [], "callees": [] }], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index 5e6e6ac27..c03e37ca1 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -27,7 +27,7 @@ extern Foo foo; "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [16380484338511689669], "uses": [], "callees": [] }], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 15c45125b..4417645ba 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -32,7 +32,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [8039186520399841081], "uses": [], "callees": [] }, { @@ -49,20 +49,6 @@ void foo() { "vars": [], "uses": ["14:14-14:17|0|1|8228"], "callees": [] - }, { - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [11489549839875479478, 9648311402855509901, 11489549839875479478], - "uses": [], - "callees": [] }, { "usr": 18319417758892371313, "detailed_name": "void called(int a)", @@ -144,7 +130,6 @@ void foo() { "detailed_name": "static int Foo::static_var", "qual_name_offset": 11, "short_name": "static_var", - "hover": "int Foo::static_var = 0", "declarations": ["6:14-6:24|15041163540773201510|2|513"], "spell": "10:10-10:20|15041163540773201510|2|514", "extent": "10:1-10:24|0|1|0", diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 10bb73fec..d9cbb63f7 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -41,7 +41,7 @@ void caller() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [9121974011454213596], "uses": [], "callees": [] }], diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index fae2ad3d0..81a61d37b 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -35,7 +35,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [14669930844300034456], "uses": [], "callees": [] }, { @@ -52,20 +52,6 @@ void foo() { "vars": [], "uses": ["16:3-16:9|0|1|8228"], "callees": [] - }, { - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [4220150017963593039, 3873837747174060388], - "uses": [], - "callees": [] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 4dad3dd95..3f939310a 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -29,20 +29,6 @@ void foo() { "vars": [], "uses": [], "callees": [] - }, { - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [8599782646965457351], - "uses": [], - "callees": [] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 912996747..a4d7e720c 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -12,21 +12,7 @@ const VarType Holder::static_var; { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 10028537921178202800, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [7057400933868440116, 7057400933868440116], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 5792006888140599735, "detailed_name": "enum VarType {\n}", @@ -67,7 +53,7 @@ const VarType Holder::static_var; "detailed_name": "static constexpr VarType Holder::static_var", "qual_name_offset": 25, "short_name": "static_var", - "hover": "static constexpr VarType Holder::static_var = (VarType)0", + "hover": "static constexpr VarType Holder::static_var = (VarType)0x0", "declarations": ["4:28-4:38|10028537921178202800|2|513"], "spell": "7:23-7:33|10028537921178202800|2|514", "extent": "7:1-7:33|0|1|0", diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 0a97cd9b1..8938f552b 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -19,7 +19,7 @@ void foo(int a) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [10063793875496522529], "uses": [], "callees": [] }], diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 4eb8c8039..7adc7df43 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -20,7 +20,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [14014650769929566957], "uses": [], "callees": [] }], diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 23e465f0b..8c8dc547c 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -25,7 +25,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [13311055950748663970, 14036425367303419504], "uses": [], "callees": [] }], diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index d94f26e56..9d926c285 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -25,7 +25,7 @@ void foo(int a) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [11608231465452906059, 6997229590862003559], "uses": [], "callees": [] }], diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 408ed5664..b20a65bd9 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -6,21 +6,7 @@ class Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [13799811842374292251], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 0c94d4a7f..84f65ba52 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -8,21 +8,7 @@ Foo* Foo::member = nullptr; { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [5844987037615239736, 5844987037615239736], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", @@ -46,7 +32,6 @@ Foo* Foo::member = nullptr; "detailed_name": "static Foo *Foo::member", "qual_name_offset": 12, "short_name": "member", - "hover": "Foo *Foo::member = nullptr", "declarations": ["2:15-2:21|15041163540773201510|2|513"], "spell": "4:11-4:17|15041163540773201510|2|514", "extent": "4:1-4:27|0|1|0", diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index 694d8bc9c..9689afe16 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -6,21 +6,7 @@ class Foo { { "includes": [], "skipped_ranges": [], - "usr2func": [{ - "usr": 15041163540773201510, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "storage": 0, - "declarations": [], - "declaring_type": 0, - "bases": [], - "derived": [], - "vars": [5844987037615239736], - "uses": [], - "callees": [] - }], + "usr2func": [], "usr2type": [{ "usr": 53, "detailed_name": "", diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 9848e6e2c..8c9460a55 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -22,7 +22,7 @@ void f() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [10601729374837386290, 18422884837902130475], "uses": [], "callees": [] }], @@ -41,7 +41,7 @@ void f() { "types": [], "funcs": [], "vars": [], - "instances": [18422884837902130475], + "instances": [10601729374837386290, 18422884837902130475], "uses": ["3:16-3:19|0|1|4", "4:17-4:20|0|1|4"] }], "usr2var": [{ @@ -53,16 +53,16 @@ void f() { "declarations": [], "spell": "3:8-3:9|880549676430489861|3|2", "extent": "3:3-3:21|880549676430489861|3|0", - "type": 0, + "type": 15041163540773201510, "uses": [], "kind": 13, "storage": 0 }, { "usr": 18422884837902130475, - "detailed_name": "auto *y", - "qual_name_offset": 6, + "detailed_name": "Foo *y", + "qual_name_offset": 5, "short_name": "y", - "hover": "auto *y = new Foo()", + "hover": "Foo *y = new Foo()", "declarations": [], "spell": "4:9-4:10|880549676430489861|3|2", "extent": "4:3-4:22|880549676430489861|3|0", diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index dd9b4cf9b..3cca9f453 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -22,7 +22,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [13198746475679542317], "uses": [], "callees": [] }], diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 2e27fe010..06617a224 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -20,7 +20,7 @@ void foo(Foo* p0, Foo* p1) {} "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [8730439006497971620, 2525014371090380500], "uses": [], "callees": [] }], diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 38e22362f..5cb9abecd 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -25,7 +25,7 @@ void foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [1894874819807168345, 4508045017817092115], "uses": [], "callees": [] }], diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index ecfdec495..a28583f39 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -19,7 +19,7 @@ void foo(int p) { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [5875271969926422921, 11404600766177939811], "uses": [], "callees": [] }], diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 50004c7f3..d35c568df 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -24,7 +24,7 @@ void Foo() { "declaring_type": 0, "bases": [], "derived": [], - "vars": [], + "vars": [6975456769752895964], "uses": [], "callees": [] }], diff --git a/src/indexer.cc b/src/indexer.cc index 6aee246ab..7eae1e743 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -33,7 +33,12 @@ struct IndexParam { std::unordered_map SeenUniqueID; std::unordered_map file_contents; std::unordered_map file2write_time; - llvm::DenseMap Decl2usr; + struct DeclInfo { + Usr usr; + std::string short_name; + std::string qualified; + }; + std::unordered_map Decl2Info; ASTUnit& Unit; ASTContext* Ctx; @@ -68,6 +73,20 @@ struct IndexParam { } }; +StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R) { + SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); + std::pair BInfo = SM.getDecomposedLoc(BLoc), + EInfo = SM.getDecomposedLoc(ELoc); + bool invalid = false; + StringRef Buf = SM.getBufferData(BInfo.first, &invalid); + if (invalid) + return ""; + return Buf.substr(BInfo.second, EInfo.second + Lexer::MeasureTokenLength( + ELoc, SM, LangOpts) - + BInfo.second); +} + Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, SourceRange R, llvm::sys::fs::UniqueID *UniqueID, bool token) { @@ -120,56 +139,65 @@ SymbolKind GetSymbolKind(const Decl* D) { case Decl::NamespaceAlias: case Decl::ClassTemplate: case Decl::TypeAliasTemplate: + case Decl::TemplateTemplateParm: case Decl::Enum: case Decl::Record: case Decl::CXXRecord: case Decl::ClassTemplateSpecialization: + case Decl::ClassTemplatePartialSpecialization: case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: return SymbolKind::Type; + case Decl::VarTemplate: + case Decl::Binding: case Decl::Field: case Decl::Var: case Decl::ParmVar: case Decl::ImplicitParam: case Decl::Decomposition: case Decl::EnumConstant: + case Decl::UnresolvedUsingValue: return SymbolKind::Var; default: return SymbolKind::Invalid; } } -const Decl* GetTypeDecl(QualType T) { - Decl *D = nullptr; - const Type *TP; - for(;;) { - T = T.getUnqualifiedType(); - TP = T.getTypePtrOrNull(); - if (!TP) - return D; - switch (TP->getTypeClass()) { - case Type::Pointer: - T = cast(TP)->getPointeeType(); - continue; - case Type::BlockPointer: - T = cast(TP)->getPointeeType(); - continue; - case Type::LValueReference: - case Type::RValueReference: - T = cast(TP)->getPointeeType(); - continue; - case Type::ObjCObjectPointer: - T = cast(TP)->getPointeeType(); - continue; - case Type::MemberPointer: - T = cast(TP)->getPointeeType(); - continue; - default: - break; +// clang/lib/AST/DeclPrinter.cpp +QualType GetBaseType(QualType T, bool deduce_auto) { + QualType BaseType = T; + while (!BaseType.isNull() && !BaseType->isSpecifierType()) { + if (const PointerType *PTy = BaseType->getAs()) + BaseType = PTy->getPointeeType(); + else if (const BlockPointerType *BPy = BaseType->getAs()) + BaseType = BPy->getPointeeType(); + else if (const ArrayType* ATy = dyn_cast(BaseType)) + BaseType = ATy->getElementType(); + else if (const VectorType *VTy = BaseType->getAs()) + BaseType = VTy->getElementType(); + else if (const ReferenceType *RTy = BaseType->getAs()) + BaseType = RTy->getPointeeType(); + else if (const ParenType *PTy = BaseType->getAs()) + BaseType = PTy->desugar(); + else if (deduce_auto) { + if (const AutoType *ATy = BaseType->getAs()) + BaseType = ATy->getDeducedType(); + else + break; } - break; + else + break; } + return BaseType; +} + +const Decl* GetTypeDecl(QualType T) { + Decl *D = nullptr; + T = GetBaseType(T.getUnqualifiedType(), true); + const Type* TP = T.getTypePtrOrNull(); + if (!TP) + return nullptr; try_again: switch (TP->getTypeClass()) { @@ -186,6 +214,9 @@ const Decl* GetTypeDecl(QualType T) { case Type::Enum: D = cast(TP)->getDecl(); break; + case Type::TemplateTypeParm: + D = cast(TP)->getDecl(); + break; case Type::TemplateSpecialization: if (const RecordType *Record = TP->getAs()) D = Record->getDecl(); @@ -313,15 +344,23 @@ class IndexDataConsumer : public index::IndexDataConsumer { return ret; } - Usr GetUsr(const Decl* D) const { + Usr GetUsr(const Decl *D, IndexParam::DeclInfo **info = nullptr) const { D = D->getCanonicalDecl(); - auto R = param.Decl2usr.try_emplace(D); + auto R = param.Decl2Info.try_emplace(D); if (R.second) { SmallString<256> USR; index::generateUSRForDecl(D, USR); - R.first->second = HashUsr(USR); + auto &info = R.first->second; + info.usr = HashUsr(USR); + if (auto *ND = dyn_cast(D)) { + info.short_name = ND->getNameAsString(); + info.qualified = ND->getQualifiedNameAsString(); + SimplifyAnonymous(info.qualified); + } } - return R.first->second; + if (info) + *info = &R.first->second; + return R.first->second.usr; } Use GetUse(IndexFile *db, Range range, const DeclContext *DC, @@ -367,13 +406,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { template void SetName(const Decl *D, std::string_view short_name, - std::string_view qualified, Def &def, bool hover = false) { + std::string_view qualified, Def &def) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); - PrintingPolicy PP = GetDefaultPolicy(); - if (hover) - PP.SuppressInitializers = false; - D->print(OS, PP); + D->print(OS, GetDefaultPolicy()); std::string name = OS.str(); SimplifyAnonymous(name); @@ -381,44 +417,96 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (i == std::string::npos) { // e.g. operator type-parameter-1 i = 0; - if (!hover) - def.short_name_offset = 0; - } else if (short_name.size()) { + def.short_name_offset = 0; + } else if (short_name.size() && (!i || name[i - 1] != ':')) { name.replace(i, short_name.size(), qualified); - if (!hover) - def.short_name_offset = i + qualified.size() - short_name.size(); + def.short_name_offset = i + qualified.size() - short_name.size(); } else { - if (!hover) - def.short_name_offset = i; + def.short_name_offset = i; } - if (hover) { - if (name != def.detailed_name) - def.hover = Intern(name); - } else { + def.short_name_size = short_name.size(); + for (int paren = 0; i; i--) { + // Skip parentheses in "(anon struct)::name" + if (name[i - 1] == ')') + paren++; + else if (name[i - 1] == '(') + paren--; + else if (!(paren > 0 || isalnum(name[i - 1]) || name[i - 1] == '_' || + name[i - 1] == ':')) + break; + } + def.qual_name_offset = i; + def.detailed_name = Intern(name); + } + + void SetVarName(const Decl *D, std::string_view short_name, + std::string_view qualified, IndexVar::Def &def) { + QualType T; + const Expr* init = nullptr; + if (auto *VD = dyn_cast(D)) { + T = VD->getType(); + init = VD->getAnyInitializer(); + def.storage = VD->getStorageClass(); + } else if (auto *FD = dyn_cast(D)) { + T = FD->getType(); + init = FD->getInClassInitializer(); + } + auto BT = GetBaseType(T, false); + if (!BT.isNull() && BT->getAs()) { + SmallString<256> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP = GetDefaultPolicy(); + T.print(OS, PP); + if (Str.size() && + (Str.back() != ' ' && Str.back() != '*' && Str.back() != '&')) + Str += ' '; + def.qual_name_offset = Str.size(); + def.short_name_offset = Str.size() + qualified.size() - short_name.size(); def.short_name_size = short_name.size(); - for (int paren = 0; i; i--) { - // Skip parentheses in "(anon struct)::name" - if (name[i - 1] == ')') - paren++; - else if (name[i - 1] == '(') - paren--; - else if (!(paren > 0 || isalnum(name[i - 1]) || name[i - 1] == '_' || - name[i - 1] == ':')) - break; - } - def.qual_name_offset = i; - def.detailed_name = Intern(name); + Str += StringRef(qualified.data(), qualified.size()); + def.detailed_name = Intern(Str.str()); + } else { + SetName(D, short_name, qualified, def); + } + if (init) { + SourceManager &SM = Ctx->getSourceManager(); + const LangOptions& Lang = Ctx->getLangOpts(); + SourceRange R = init->getSourceRange(); + SourceLocation L = D->getLocation(); + if (!SM.isBeforeInTranslationUnit(L, R.getBegin())) + return; + StringRef Buf = GetSourceInRange(SM, Lang, R); + Twine T = + def.detailed_name + + (Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) : Twine(" = ", Buf)); + def.hover = + def.storage == SC_Static && strncmp(def.detailed_name, "static ", 7) + ? Intern(("static " + T).str()) + : Intern(T.str()); } } - void AddMacroUse(SourceManager &SM, std::vector &uses, + void AddMacroUse(SourceManager &SM, Usr usr, SymbolKind kind, SourceLocation Spell) const { const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); - if (FE) { - IndexFile *db = param.ConsumeFile(*FE); - Range spell = - FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); - uses.push_back(GetUse(db, spell, nullptr, Role::Dynamic)); + if (!FE) return; + IndexFile *db = param.ConsumeFile(*FE); + if (!db) return; + Range spell = + FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); + Use use = GetUse(db, spell, nullptr, Role::Dynamic); + switch (kind) { + case SymbolKind::Func: + db->ToFunc(usr).uses.push_back(use); + break; + case SymbolKind::Type: + db->ToType(usr).uses.push_back(use); + break; + case SymbolKind::Var: + db->ToVar(usr).uses.push_back(use); + break; + default: + llvm_unreachable(""); } } @@ -450,17 +538,20 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceLocation Spell = SM.getSpellingLoc(Loc); Loc = SM.getFileLoc(Loc); Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc)); - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc)); + FileID LocFID = SM.getFileID(Loc); + const FileEntry *FE = SM.getFileEntryForID(LocFID); if (!FE) { // TODO #if LLVM_VERSION_MAJOR < 7 auto P = SM.getExpansionRange(Loc); loc = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); - FE = SM.getFileEntryForID(SM.getFileID(P.first)); + LocFID = SM.getFileID(P.first); + FE = SM.getFileEntryForID(LocFID); #else auto R = SM.getExpansionRange(Loc); loc = FromTokenRange(SM, Lang, R.getAsRange()); - FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + LocFID = SM.getFileID(R.getBegin()); + FE = SM.getFileEntryForID(LocFID); #endif if (!FE) return true; @@ -476,26 +567,14 @@ class IndexDataConsumer : public index::IndexDataConsumer { bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); - std::string short_name, qualified; - - if (auto* ND = dyn_cast(D)) { - short_name = ND->getNameAsString(); - qualified = ND->getQualifiedNameAsString(); - SimplifyAnonymous(qualified); - } - IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; SymbolKind kind = GetSymbolKind(D); - Usr usr = GetUsr(D); + IndexParam::DeclInfo* info; + Usr usr = GetUsr(D, &info); auto do_def_decl = [&](auto *entity) { - if (!entity->def.detailed_name[0]) { - SetName(D, short_name, qualified, entity->def); - if (entity->def.comments[0] == '\0' && g_config->index.comments) - entity->def.comments = Intern(GetComment(D)); - } if (is_def) { entity->def.spell = GetUse(db, loc, SemDC, role); entity->def.extent = @@ -505,19 +584,25 @@ class IndexDataConsumer : public index::IndexDataConsumer { entity->declarations.push_back(GetUse(db, loc, LexDC, role)); } else { entity->uses.push_back(GetUse(db, loc, LexDC, role)); + return; } - if (Spell != Loc) - AddMacroUse(SM, entity->uses, Spell); + if (entity->def.comments[0] == '\0' && g_config->index.comments) + entity->def.comments = Intern(GetComment(OrigD)); }; switch (kind) { case SymbolKind::Invalid: - LOG_S(INFO) << "Unhandled " << int(D->getKind()); + LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " << info->qualified + << " in " << db->path << ":" << loc.start.line; return true; case SymbolKind::File: return true; case SymbolKind::Func: func = &db->ToFunc(usr); do_def_decl(func); + if (Spell != Loc) + AddMacroUse(SM, usr, SymbolKind::Func, Spell); + if (func->def.detailed_name[0] == '\0') + SetName(OrigD, info->short_name, info->qualified, func->def); if (is_def || is_decl) { const Decl* DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -527,6 +612,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { case SymbolKind::Type: type = &db->ToType(usr); do_def_decl(type); + if (Spell != Loc) + AddMacroUse(SM, usr, SymbolKind::Type, Spell); + if (type->def.detailed_name[0] == '\0') + SetName(OrigD, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl* DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -536,28 +625,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { case SymbolKind::Var: var = &db->ToVar(usr); do_def_decl(var); + if (Spell != Loc) + AddMacroUse(SM, usr, SymbolKind::Var, Spell); + if (var->def.detailed_name[0] == '\0') + SetVarName(OrigD, info->short_name, info->qualified, var->def); + QualType T; + if (auto *VD = dyn_cast(D)) + T = VD->getType(); + else if (auto *FD = dyn_cast(D)) + T = FD->getType(); if (is_def || is_decl) { const Decl* DC = cast(SemDC); - if (GetSymbolKind(DC) == SymbolKind::Type) + if (GetSymbolKind(DC) == SymbolKind::Func) db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); else if (auto *ND = dyn_cast(SemDC)) db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); - QualType T; - if (auto *VD = dyn_cast(D)) { - var->def.storage = VD->getStorageClass(); - T = VD->getType(); - // O(n^2) - for (auto I : VD->redecls()) - if (I->hasInit()) { - // TODO missing "static" in definition - SetName(I, short_name, qualified, var->def, true); - break; - } - } else if (auto *FD = dyn_cast(D)) { - T = FD->getType(); - if (FD->hasInClassInitializer()) - SetName(D, short_name, qualified, var->def, true); - } if (!T.isNull()) { if (auto *BT = T->getAs()) { Usr usr1 = static_cast(BT->getKind()); @@ -565,16 +647,41 @@ class IndexDataConsumer : public index::IndexDataConsumer { db->ToType(usr1).instances.push_back(usr); } else { for (const Decl *D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { - Usr usr1 = GetUsr(D1); + IndexParam::DeclInfo* info1; + Usr usr1 = GetUsr(D1, &info1); auto it = db->usr2type.find(usr1); if (it != db->usr2type.end()) { var->def.type = usr1; it->second.instances.push_back(usr); break; } + // e.g. TemplateTypeParmDecl is not handled by handleDeclOccurence. + SourceRange R1 = D1->getSourceRange(); + if (SM.getFileID(R1.getBegin()) == LocFID) { + IndexType& type1 = db->ToType(usr1); + Range loc1 = FromTokenRange(SM, Lang, R1); + type1.def.spell = GetUse(db, loc1, SemDC, Role::Definition); + type1.def.extent = GetUse(db, loc1, LexDC, Role::None); + type1.def.detailed_name = Intern(info1->short_name); + type1.def.short_name_size = int16_t(info1->short_name.size()); + type1.def.kind = lsSymbolKind::TypeParameter; + var->def.type = usr1; + type1.instances.push_back(usr); + break; + } } } } + } else if (!var->def.spell && var->declarations.empty()) { + // e.g. lambda parameter + SourceLocation L = OrigD->getLocation(); + if (SM.getFileID(L) == LocFID) { + var->def.spell = GetUse(db, FromTokenRange(SM, Lang, {L, L}), SemDC, + Role::Definition); + var->def.extent = + GetUse(db, FromTokenRange(SM, Lang, OrigD->getSourceRange()), + LexDC, Role::None); + } } break; } @@ -643,8 +750,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::TypeAliasTemplate: type->def.kind = lsSymbolKind::TypeAlias; + case Decl::VarTemplate: + type->def.kind = lsSymbolKind::Variable; + case Decl::TemplateTemplateParm: + type->def.kind = lsSymbolKind::TypeParameter; break; case Decl::ClassTemplateSpecialization: + case Decl::ClassTemplatePartialSpecialization: type->def.kind = lsSymbolKind::Class; if (is_def || is_decl) { if (auto *RD = dyn_cast(D)) { @@ -686,6 +798,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } break; + case Decl::Binding: + var->def.kind = lsSymbolKind::Variable; + case Decl::Field: + var->def.kind = lsSymbolKind::Field; + break; case Decl::Function: func->def.kind = lsSymbolKind::Function; break; @@ -713,9 +830,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::CXXDestructor: func->def.kind = lsSymbolKind::Method; break; - case Decl::Field: - var->def.kind = lsSymbolKind::Field; - break; case Decl::Var: case Decl::Decomposition: var->def.kind = lsSymbolKind::Variable; @@ -737,6 +851,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { var->def.hover = Intern(var->def.detailed_name + init); } break; + case Decl::UnresolvedUsingValue: + var->def.kind = lsSymbolKind::Variable; + break; default: LOG_S(INFO) << "Unhandled " << int(D->getKind()); break; @@ -757,13 +874,18 @@ class IndexPPCallbacks : public PPCallbacks { } public: - IndexPPCallbacks(SourceManager& SM, IndexParam& param) : SM(SM), param(param) {} + IndexPPCallbacks(SourceManager &SM, IndexParam ¶m) + : SM(SM), param(param) {} void InclusionDirective(SourceLocation HashLoc, const Token &Tok, StringRef Included, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported, - SrcMgr::CharacteristicKind FileType) override { + const Module *Imported +#if LLVM_VERSION_MAJOR >= 7 + , + SrcMgr::CharacteristicKind FileType +#endif + ) override { if (!File) return; llvm::sys::fs::UniqueID UniqueID; @@ -780,25 +902,27 @@ class IndexPPCallbacks : public PPCallbacks { } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { llvm::sys::fs::UniqueID UniqueID; + const LangOptions& Lang = param.Ctx->getLangOpts(); SourceLocation L = MD->getLocation(); - auto range = - FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { auto[Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); - if (!var.def.detailed_name[0]) { + auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); + var.def.kind = lsSymbolKind::Macro; + if (var.def.spell) + var.declarations.push_back(*var.def.spell); + var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}}; + const MacroInfo *MI = MD->getMacroInfo(); + SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); + range = FromTokenRange(SM, param.Ctx->getLangOpts(), R); + var.def.extent = Use{{range, 0, SymbolKind::File, Role::None}}; + if (var.def.detailed_name[0] == '\0') { var.def.detailed_name = Intern(Name); var.def.short_name_size = Name.size(); - // TODO defin - var.def.hover = Intern(Twine("#define ", Name).str()); - var.def.kind = lsSymbolKind::Macro; - if (var.def.spell) - var.declarations.push_back(*var.def.spell); - var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}}; - var.def.extent = var.def.spell; + var.def.hover = Intern(Twine("#define ", GetSourceInRange(SM, Lang, R)).str()); } } } diff --git a/src/message_handler.cc b/src/message_handler.cc index 86e7d23c1..a30ef6854 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -14,17 +14,17 @@ MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); namespace { -struct Out_CclsSetInactiveRegion - : public lsOutMessage { +struct Out_CclsSetSkippedRanges + : public lsOutMessage { struct Params { lsDocumentUri uri; - std::vector inactiveRegions; + std::vector skippedRanges; }; - std::string method = "$ccls/setInactiveRegions"; + std::string method = "$ccls/setSkippedRanges"; Params params; }; -MAKE_REFLECT_STRUCT(Out_CclsSetInactiveRegion::Params, uri, inactiveRegions); -MAKE_REFLECT_STRUCT(Out_CclsSetInactiveRegion, jsonrpc, method, params); +MAKE_REFLECT_STRUCT(Out_CclsSetSkippedRanges::Params, uri, skippedRanges); +MAKE_REFLECT_STRUCT(Out_CclsSetSkippedRanges, jsonrpc, method, params); struct ScanLineEvent { lsPosition pos; @@ -177,14 +177,14 @@ bool FindFileOrFail(DB* db, void EmitSkippedRanges(WorkingFile *working_file, const std::vector &skipped_ranges) { - Out_CclsSetInactiveRegion out; + Out_CclsSetSkippedRanges out; out.params.uri = lsDocumentUri::FromPath(working_file->filename); for (Range skipped : skipped_ranges) { std::optional ls_skipped = GetLsRange(working_file, skipped); if (ls_skipped) - out.params.inactiveRegions.push_back(*ls_skipped); + out.params.skippedRanges.push_back(*ls_skipped); } - pipeline::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); + pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out); } void EmitSemanticHighlighting(DB* db, diff --git a/src/method.cc b/src/method.cc index 722d6fb21..914e2d4f7 100644 --- a/src/method.cc +++ b/src/method.cc @@ -4,8 +4,8 @@ MethodType kMethodType_Unknown = "$unknown"; MethodType kMethodType_Exit = "exit"; MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; -MethodType kMethodType_CclsPublishInactiveRegions = - "$ccls/publishInactiveRegions"; +MethodType kMethodType_CclsPublishSkippedRanges = + "$ccls/publishSkippedRanges"; MethodType kMethodType_CclsPublishSemanticHighlighting = "$ccls/publishSemanticHighlighting"; diff --git a/src/method.h b/src/method.h index 525c409ae..a7317b1e7 100644 --- a/src/method.h +++ b/src/method.h @@ -9,7 +9,7 @@ using MethodType = const char*; extern MethodType kMethodType_Unknown; extern MethodType kMethodType_Exit; extern MethodType kMethodType_TextDocumentPublishDiagnostics; -extern MethodType kMethodType_CclsPublishInactiveRegions; +extern MethodType kMethodType_CclsPublishSkippedRanges; extern MethodType kMethodType_CclsPublishSemanticHighlighting; struct lsRequestId { diff --git a/src/pipeline.cc b/src/pipeline.cc index 3b7f0cd6b..bbced1d94 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -320,7 +320,7 @@ void Main_OnIndexed(DB* db, db->ApplyIndexUpdate(update); timer.stopTimer(); - // Update indexed content, inactive lines, and semantic highlighting. + // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { auto& def_u = *update->files_def_update; LOG_S(INFO) << "apply index for " << def_u.first.path; From 0a304096df741355ccaa4ab1983502783dd96768 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 17:44:40 -0700 Subject: [PATCH 134/378] cmake: remove -lc++experimental -ldl -lexecinfo --- CMakeLists.txt | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 614306188..fee47d23a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,21 +113,9 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) -if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - target_link_libraries(ccls PRIVATE -lc++experimental) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - # loguru calls dladdr - target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - # loguru::stacktrace_as_stdstring calls backtrace_symbols +if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) # src/platform_posix.cc uses libthr - find_package(Backtrace REQUIRED) - target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} thr) - if(SYSTEM_CLANG) - target_link_libraries(ccls PRIVATE c++experimental) - endif() + target_link_libraries(ccls PRIVATE thr) endif() ### Definitions From 7d1d4b410b616f8e6105dab5d58c602c0c4e1594 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 19:56:33 -0700 Subject: [PATCH 135/378] $ccls/publishSemanticHighlighting: use pair in place of lsRange --- src/indexer.cc | 4 +- src/message_handler.cc | 264 +++++++++++++++++++++++------------------ src/message_handler.h | 5 +- 3 files changed, 153 insertions(+), 120 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 7eae1e743..40af68c83 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -534,11 +534,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { off |= 1u << 31; Loc = SourceLocation::getFromRawEncoding(off); } +#else + FileID LocFID; #endif SourceLocation Spell = SM.getSpellingLoc(Loc); Loc = SM.getFileLoc(Loc); Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc)); - FileID LocFID = SM.getFileID(Loc); + LocFID = SM.getFileID(Loc); const FileEntry *FE = SM.getFileEntryForID(LocFID); if (!FE) { // TODO diff --git a/src/message_handler.cc b/src/message_handler.cc index a30ef6854..60e74b593 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -1,9 +1,9 @@ #include "message_handler.h" #include "log.hh" +#include "pipeline.hh" #include "project.h" #include "query_utils.h" -#include "pipeline.hh" using namespace ccls; using namespace clang; @@ -28,10 +28,10 @@ MAKE_REFLECT_STRUCT(Out_CclsSetSkippedRanges, jsonrpc, method, params); struct ScanLineEvent { lsPosition pos; - lsPosition end_pos; // Second key when there is a tie for insertion events. + lsPosition end_pos; // Second key when there is a tie for insertion events. int id; - Out_CclsPublishSemanticHighlighting::Symbol* symbol; - bool operator<(const ScanLineEvent& other) const { + Out_CclsPublishSemanticHighlighting::Symbol *symbol; + bool operator<(const ScanLineEvent &other) const { // See the comments below when insertion/deletion events are inserted. if (!(pos == other.pos)) return pos < other.pos; @@ -42,17 +42,15 @@ struct ScanLineEvent { return symbol->kind < other.symbol->kind; } }; -} // namespace +} // namespace SemanticHighlightSymbolCache::Entry::Entry( - SemanticHighlightSymbolCache* all_caches, - const std::string& path) + SemanticHighlightSymbolCache *all_caches, const std::string &path) : all_caches_(all_caches), path(path) {} std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( - SymbolKind kind, - const std::string& detailed_name) { - TNameToId* map = GetMapForSymbol_(kind); + SymbolKind kind, const std::string &detailed_name) { + TNameToId *map = GetMapForSymbol_(kind); auto it = map->find(detailed_name); if (it != map->end()) return it->second; @@ -61,14 +59,13 @@ std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( } int SemanticHighlightSymbolCache::Entry::GetStableId( - SymbolKind kind, - const std::string& detailed_name) { + SymbolKind kind, const std::string &detailed_name) { std::optional id = TryGetStableId(kind, detailed_name); if (id) return *id; // Create a new id. First try to find a key in another map. - all_caches_->cache_.IterateValues([&](const std::shared_ptr& entry) { + all_caches_->cache_.IterateValues([&](const std::shared_ptr &entry) { std::optional other_id = entry->TryGetStableId(kind, detailed_name); if (other_id) { id = other_id; @@ -78,24 +75,24 @@ int SemanticHighlightSymbolCache::Entry::GetStableId( }); // Create a new id. - TNameToId* map = GetMapForSymbol_(kind); + TNameToId *map = GetMapForSymbol_(kind); if (!id) id = all_caches_->next_stable_id_++; return (*map)[detailed_name] = *id; } -SemanticHighlightSymbolCache::Entry::TNameToId* +SemanticHighlightSymbolCache::Entry::TNameToId * SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) { switch (kind) { - case SymbolKind::Type: - return &detailed_type_name_to_stable_id; - case SymbolKind::Func: - return &detailed_func_name_to_stable_id; - case SymbolKind::Var: - return &detailed_var_name_to_stable_id; - case SymbolKind::File: - case SymbolKind::Invalid: - break; + case SymbolKind::Type: + return &detailed_type_name_to_stable_id; + case SymbolKind::Func: + return &detailed_func_name_to_stable_id; + case SymbolKind::Var: + return &detailed_var_name_to_stable_id; + case SymbolKind::File: + case SymbolKind::Invalid: + break; } assert(false); return nullptr; @@ -110,7 +107,7 @@ void SemanticHighlightSymbolCache::Init() { } std::shared_ptr -SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) { +SemanticHighlightSymbolCache::GetCacheForFile(const std::string &path) { return cache_.Get( path, [&, this]() { return std::make_shared(this, path); }); } @@ -119,24 +116,21 @@ MessageHandler::MessageHandler() { // Dynamically allocate |message_handlers|, otherwise there will be static // initialization order races. if (!message_handlers) - message_handlers = new std::vector(); + message_handlers = new std::vector(); message_handlers->push_back(this); } // static -std::vector* MessageHandler::message_handlers = nullptr; - -bool FindFileOrFail(DB* db, - Project* project, - std::optional id, - const std::string& absolute_path, - QueryFile** out_query_file, - int* out_file_id) { +std::vector *MessageHandler::message_handlers = nullptr; + +bool FindFileOrFail(DB *db, Project *project, std::optional id, + const std::string &absolute_path, + QueryFile **out_query_file, int *out_file_id) { *out_query_file = nullptr; auto it = db->name2file_id.find(LowerPathIfInsensitive(absolute_path)); if (it != db->name2file_id.end()) { - QueryFile& file = db->files[it->second]; + QueryFile &file = db->files[it->second]; if (file.def) { *out_query_file = &file; if (out_file_id) @@ -152,7 +146,7 @@ bool FindFileOrFail(DB* db, { std::lock_guard lock(project->mutex_); indexing = project->absolute_path_to_entry_index_.find(absolute_path) != - project->absolute_path_to_entry_index_.end(); + project->absolute_path_to_entry_index_.end(); } if (indexing) LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; @@ -187,10 +181,9 @@ void EmitSkippedRanges(WorkingFile *working_file, pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out); } -void EmitSemanticHighlighting(DB* db, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFile* wfile, - QueryFile* file) { +void EmitSemanticHighlighting(DB *db, + SemanticHighlightSymbolCache *semantic_cache, + WorkingFile *wfile, QueryFile *file) { assert(file->def); if (wfile->buffer_content.size() > g_config->largeFileSize || !semantic_cache->match_->IsMatch(file->def->path)) @@ -208,86 +201,86 @@ void EmitSemanticHighlighting(DB* db, StorageClass storage = SC_None; // This switch statement also filters out symbols that are not highlighted. switch (sym.kind) { - case SymbolKind::Func: { - const QueryFunc& func = db->GetFunc(sym); - const QueryFunc::Def* def = func.AnyDef(); - if (!def) - continue; // applies to for loop - if (def->spell) - parent_kind = GetSymbolKind(db, *def->spell); - if (parent_kind == lsSymbolKind::Unknown) { - for (Use use : func.declarations) { - parent_kind = GetSymbolKind(db, use); - break; - } + case SymbolKind::Func: { + const QueryFunc &func = db->GetFunc(sym); + const QueryFunc::Def *def = func.AnyDef(); + if (!def) + continue; // applies to for loop + if (def->spell) + parent_kind = GetSymbolKind(db, *def->spell); + if (parent_kind == lsSymbolKind::Unknown) { + for (Use use : func.declarations) { + parent_kind = GetSymbolKind(db, use); + break; } - // Don't highlight overloadable operators or implicit lambda -> - // std::function constructor. - std::string_view short_name = def->Name(false); - if (short_name.compare(0, 8, "operator") == 0) - continue; // applies to for loop - if (def->spell) - parent_kind = GetSymbolKind(db, *def->spell); - kind = def->kind; - storage = def->storage; - detailed_name = short_name; - - // Check whether the function name is actually there. - // If not, do not publish the semantic highlight. - // E.g. copy-initialization of constructors should not be highlighted - // but we still want to keep the range for jumping to definition. - std::string_view concise_name = - detailed_name.substr(0, detailed_name.find('<')); - int16_t start_line = sym.range.start.line; - int16_t start_col = sym.range.start.column; - if (start_line < 0 || start_line >= wfile->index_lines.size()) - continue; - std::string_view line = wfile->index_lines[start_line]; - sym.range.end.line = start_line; - if (!(start_col + concise_name.size() <= line.size() && - line.compare(start_col, concise_name.size(), concise_name) == 0)) - continue; - sym.range.end.column = start_col + concise_name.size(); - break; } - case SymbolKind::Type: - for (auto& def : db->GetType(sym).def) { - kind = def.kind; - detailed_name = def.detailed_name; - if (def.spell) { - parent_kind = GetSymbolKind(db, *def.spell); - break; - } + // Don't highlight overloadable operators or implicit lambda -> + // std::function constructor. + std::string_view short_name = def->Name(false); + if (short_name.compare(0, 8, "operator") == 0) + continue; // applies to for loop + if (def->spell) + parent_kind = GetSymbolKind(db, *def->spell); + kind = def->kind; + storage = def->storage; + detailed_name = short_name; + + // Check whether the function name is actually there. + // If not, do not publish the semantic highlight. + // E.g. copy-initialization of constructors should not be highlighted + // but we still want to keep the range for jumping to definition. + std::string_view concise_name = + detailed_name.substr(0, detailed_name.find('<')); + int16_t start_line = sym.range.start.line; + int16_t start_col = sym.range.start.column; + if (start_line < 0 || start_line >= wfile->index_lines.size()) + continue; + std::string_view line = wfile->index_lines[start_line]; + sym.range.end.line = start_line; + if (!(start_col + concise_name.size() <= line.size() && + line.compare(start_col, concise_name.size(), concise_name) == 0)) + continue; + sym.range.end.column = start_col + concise_name.size(); + break; + } + case SymbolKind::Type: + for (auto &def : db->GetType(sym).def) { + kind = def.kind; + detailed_name = def.detailed_name; + if (def.spell) { + parent_kind = GetSymbolKind(db, *def.spell); + break; } - break; - case SymbolKind::Var: { - const QueryVar& var = db->GetVar(sym); - for (auto& def : var.def) { - kind = def.kind; - storage = def.storage; - detailed_name = def.detailed_name; - if (def.spell) { - parent_kind = GetSymbolKind(db, *def.spell); - break; - } + } + break; + case SymbolKind::Var: { + const QueryVar &var = db->GetVar(sym); + for (auto &def : var.def) { + kind = def.kind; + storage = def.storage; + detailed_name = def.detailed_name; + if (def.spell) { + parent_kind = GetSymbolKind(db, *def.spell); + break; } - if (parent_kind == lsSymbolKind::Unknown) { - for (Use use : var.declarations) { - parent_kind = GetSymbolKind(db, use); - break; - } + } + if (parent_kind == lsSymbolKind::Unknown) { + for (Use use : var.declarations) { + parent_kind = GetSymbolKind(db, use); + break; } - break; } - default: - continue; // applies to for loop + break; + } + default: + continue; // applies to for loop } std::optional loc = GetLsRange(wfile, sym.range); if (loc) { auto it = grouped_symbols.find(sym); if (it != grouped_symbols.end()) { - it->second.ranges.push_back(*loc); + it->second.lsRanges.push_back(*loc); } else { Out_CclsPublishSemanticHighlighting::Symbol symbol; symbol.stableId = semantic_cache_for_file->GetStableId( @@ -295,7 +288,7 @@ void EmitSemanticHighlighting(DB* db, symbol.parentKind = parent_kind; symbol.kind = kind; symbol.storage = storage; - symbol.ranges.push_back(*loc); + symbol.lsRanges.push_back(*loc); grouped_symbols[sym] = symbol; } } @@ -304,9 +297,9 @@ void EmitSemanticHighlighting(DB* db, // Make ranges non-overlapping using a scan line algorithm. std::vector events; int id = 0; - for (auto& entry : grouped_symbols) { - Out_CclsPublishSemanticHighlighting::Symbol& symbol = entry.second; - for (auto& loc : symbol.ranges) { + for (auto &entry : grouped_symbols) { + Out_CclsPublishSemanticHighlighting::Symbol &symbol = entry.second; + for (auto &loc : symbol.lsRanges) { // For ranges sharing the same start point, the one with leftmost end // point comes first. events.push_back({loc.start, loc.end, id, &symbol}); @@ -316,7 +309,7 @@ void EmitSemanticHighlighting(DB* db, events.push_back({loc.end, loc.end, ~id, &symbol}); id++; } - symbol.ranges.clear(); + symbol.lsRanges.clear(); } std::sort(events.begin(), events.end()); @@ -332,19 +325,54 @@ void EmitSemanticHighlighting(DB* db, // Attribute range [events[i-1].pos, events[i].pos) to events[top-1].symbol // . if (top && !(events[i - 1].pos == events[i].pos)) - events[top - 1].symbol->ranges.push_back( - lsRange{events[i - 1].pos, events[i].pos}); + events[top - 1].symbol->lsRanges.push_back( + {events[i - 1].pos, events[i].pos}); if (events[i].id >= 0) events[top++] = events[i]; else deleted[~events[i].id] = 1; } - // Publish. Out_CclsPublishSemanticHighlighting out; out.params.uri = lsDocumentUri::FromPath(wfile->filename); - for (auto& entry : grouped_symbols) + // Transform lsRange into pair (offset pairs) + { + std::vector> + scratch; + for (auto &entry : grouped_symbols) + for (auto &range : entry.second.lsRanges) + scratch.emplace_back(range, &entry.second); + std::sort(scratch.begin(), scratch.end(), + [](auto &l, auto &r) { return l.first.start < r.first.start; }); + const auto &buf = wfile->buffer_content; + int l = 0, c = 0, i = 0; + auto mov = [&](int line, int col) { + if (l < line) + c = 0; + for (; l < line && i < buf.size(); i++) + if (buf[i] == '\n') + l++; + if (l < line) return true; + for (; c < col && i < buf.size(); c++) + if (uint8_t(buf[i++]) >= 128) + // Skip 0b10xxxxxx + while (i < buf.size() && uint8_t(buf[i]) >= 128 && uint8_t(buf[i]) < 192) + i++; + return c < col; + }; + for (auto &entry : scratch) { + lsRange &r = entry.first; + if (mov(r.start.line, r.start.character)) + continue; + int beg = i; + if (mov(r.end.line, r.end.character)) + continue; + entry.second->ranges.emplace_back(beg, i); + } + } + + for (auto &entry : grouped_symbols) if (entry.second.ranges.size()) - out.params.symbols.push_back(entry.second); + out.params.symbols.push_back(std::move(entry.second)); pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } diff --git a/src/message_handler.h b/src/message_handler.h index 6b6daa6c9..425a134d9 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -64,7 +64,10 @@ struct Out_CclsPublishSemanticHighlighting lsSymbolKind parentKind; lsSymbolKind kind; clang::StorageClass storage; - std::vector ranges; + std::vector> ranges; + + // `lsRanges` is used to compute `ranges`. + std::vector lsRanges; }; struct Params { lsDocumentUri uri; From 7c1ff07dc9ad447c237d24162c984eb6a961d7c0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 8 Jul 2018 23:31:40 -0700 Subject: [PATCH 136/378] Fix memberHierarchy --- src/messages/ccls_memberHierarchy.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index 0f2132d89..653b773de 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -3,6 +3,9 @@ #include "query_utils.h" using namespace ccls; +#include +using namespace clang; + #include namespace { @@ -121,7 +124,7 @@ bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, bool qualified, int levels) { - if (CXType_FirstBuiltin <= entry->usr && entry->usr <= CXType_LastBuiltin) { + if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(CXTypeKind(entry->usr)); return true; } From c04d0620c0c3e71f29d234e3de13cd116c68d73d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 9 Jul 2018 00:05:56 -0700 Subject: [PATCH 137/378] Add some ObjC kinds --- src/indexer.cc | 96 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 15 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 40af68c83..8b006a0c3 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -128,6 +128,7 @@ SymbolKind GetSymbolKind(const Decl* D) { switch (D->getKind()) { case Decl::TranslationUnit: return SymbolKind::File; + case Decl::ObjCMethod: case Decl::FunctionTemplate: case Decl::Function: case Decl::CXXMethod: @@ -137,6 +138,9 @@ SymbolKind GetSymbolKind(const Decl* D) { return SymbolKind::Func; case Decl::Namespace: case Decl::NamespaceAlias: + case Decl::ObjCCategory: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: case Decl::ClassTemplate: case Decl::TypeAliasTemplate: case Decl::TemplateTemplateParm: @@ -149,9 +153,11 @@ SymbolKind GetSymbolKind(const Decl* D) { case Decl::Typedef: case Decl::UnresolvedUsingTypename: return SymbolKind::Type; + case Decl::ObjCProperty: case Decl::VarTemplate: case Decl::Binding: case Decl::Field: + case Decl::ObjCIvar: case Decl::Var: case Decl::ParmVar: case Decl::ImplicitParam: @@ -164,6 +170,51 @@ SymbolKind GetSymbolKind(const Decl* D) { } } +LanguageId GetDeclLanguage(const Decl *D) { + switch (D->getKind()) { + default: + return LanguageId::C; + case Decl::ImplicitParam: + case Decl::ObjCAtDefsField: + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCCompatibleAlias: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCIvar: + case Decl::ObjCMethod: + case Decl::ObjCProperty: + case Decl::ObjCPropertyImpl: + case Decl::ObjCProtocol: + case Decl::ObjCTypeParam: + return LanguageId::ObjC; + case Decl::CXXConstructor: + case Decl::CXXConversion: + case Decl::CXXDestructor: + case Decl::CXXMethod: + case Decl::CXXRecord: + case Decl::ClassTemplate: + case Decl::ClassTemplatePartialSpecialization: + case Decl::ClassTemplateSpecialization: + case Decl::Friend: + case Decl::FriendTemplate: + case Decl::FunctionTemplate: + case Decl::LinkageSpec: + case Decl::Namespace: + case Decl::NamespaceAlias: + case Decl::NonTypeTemplateParm: + case Decl::StaticAssert: + case Decl::TemplateTemplateParm: + case Decl::TemplateTypeParm: + case Decl::UnresolvedUsingTypename: + case Decl::UnresolvedUsingValue: + case Decl::Using: + case Decl::UsingDirective: + case Decl::UsingShadow: + return LanguageId::Cpp; + } +} + // clang/lib/AST/DeclPrinter.cpp QualType GetBaseType(QualType T, bool deduce_auto) { QualType BaseType = T; @@ -566,6 +617,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *LexDC = OrigD->getLexicalDeclContext(); Role role = static_cast(Roles); + db->language = std::max(db->language, GetDeclLanguage(OrigD)); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); @@ -702,6 +754,33 @@ class IndexDataConsumer : public index::IndexDataConsumer { } break; } + case Decl::ObjCCategory: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + type->def.kind = lsSymbolKind::Interface; + break; + case Decl::ObjCMethod: + func->def.kind = lsSymbolKind::Method; + break; + case Decl::ObjCProperty: + var->def.kind = lsSymbolKind::Property; + break; + case Decl::ClassTemplate: + type->def.kind = lsSymbolKind::Class; + break; + case Decl::FunctionTemplate: + func->def.kind = lsSymbolKind::Function; + break; + case Decl::TypeAliasTemplate: + type->def.kind = lsSymbolKind::TypeAlias; + break; + case Decl::VarTemplate: + var->def.kind = lsSymbolKind::Variable; + break; + case Decl::TemplateTemplateParm: + type->def.kind = lsSymbolKind::TypeParameter; + break; case Decl::Enum: type->def.kind = lsSymbolKind::Enum; break; @@ -744,19 +823,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { } break; } - case Decl::ClassTemplate: - type->def.kind = lsSymbolKind::Class; - break; - case Decl::FunctionTemplate: - type->def.kind = lsSymbolKind::Function; - break; - case Decl::TypeAliasTemplate: - type->def.kind = lsSymbolKind::TypeAlias; - case Decl::VarTemplate: - type->def.kind = lsSymbolKind::Variable; - case Decl::TemplateTemplateParm: - type->def.kind = lsSymbolKind::TypeParameter; - break; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: type->def.kind = lsSymbolKind::Class; @@ -802,7 +868,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::Binding: var->def.kind = lsSymbolKind::Variable; + break; case Decl::Field: + case Decl::ObjCIvar: var->def.kind = lsSymbolKind::Field; break; case Decl::Function: @@ -1118,8 +1186,6 @@ std::vector> Index( return {}; } - // ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) - // .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); const SourceManager& SM = Unit->getSourceManager(); const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); IndexFile* main_file = param.ConsumeFile(*FE); From 0c50ee79f2f85544dda8bfd17d507685959c0524 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 9 Jul 2018 23:40:26 -0700 Subject: [PATCH 138/378] Cleanup --- README.md | 20 +-- index_tests/constructors/constructor.cc | 4 +- index_tests/constructors/destructor.cc | 6 +- .../constructors/implicit_constructor.cc | 4 +- index_tests/constructors/invalid_reference.cc | 2 +- index_tests/constructors/make_functions.cc | 124 ++++++++++++++++-- .../declaration_vs_definition/class_member.cc | 2 +- .../class_member_static.cc | 4 +- .../func_associated_function_params.cc | 4 +- .../declaration_vs_definition/method.cc | 8 +- index_tests/enums/enum_class_decl.cc | 4 +- index_tests/enums/enum_decl.cc | 4 +- index_tests/enums/enum_inherit.cc | 8 +- index_tests/enums/enum_usage.cc | 4 +- index_tests/foobar.cc | 6 +- index_tests/inheritance/class_inherit.cc | 2 +- .../class_inherit_templated_parent.cc | 10 +- .../inheritance/class_multiple_inherit.cc | 6 +- index_tests/inheritance/function_override.cc | 6 +- .../inheritance/interface_pure_virtual.cc | 2 +- .../inheritance/multiple_base_functions.cc | 10 +- index_tests/lambdas/lambda.cc | 2 +- index_tests/macros/complex.cc | 2 +- index_tests/macros/foo.cc | 2 +- index_tests/method_declaration.cc | 2 +- index_tests/method_definition.cc | 4 +- index_tests/method_inline_declaration.cc | 2 +- index_tests/multi_file/funky_enum.cc | 12 +- index_tests/multi_file/impl.cc | 10 +- index_tests/multi_file/simple_impl.cc | 2 +- index_tests/multi_file/static.cc | 4 +- .../namespaces/function_declaration.cc | 2 +- index_tests/namespaces/function_definition.cc | 2 +- index_tests/namespaces/method_declaration.cc | 4 +- index_tests/namespaces/method_definition.cc | 6 +- .../namespaces/method_inline_declaration.cc | 4 +- index_tests/namespaces/namespace_alias.cc | 6 +- index_tests/namespaces/namespace_reference.cc | 8 +- index_tests/operators/operator.cc | 6 +- .../outline/static_function_in_type.cc | 10 +- .../func_specialized_template_param.cc | 21 ++- .../implicit_variable_instantiation.cc | 12 +- .../templates/member_ref_in_template.cc | 6 +- ...ass_template_func_usage_folded_into_one.cc | 8 +- ...ace_template_type_usage_folded_into_one.cc | 10 +- index_tests/templates/specialization.cc | 34 ++--- .../templates/specialized_func_definition.cc | 6 +- ...mplate_class_func_usage_folded_into_one.cc | 2 +- ...ass_template_func_usage_folded_into_one.cc | 2 +- ...mplate_class_type_usage_folded_into_one.cc | 6 +- ...emplate_class_var_usage_folded_into_one.cc | 2 +- .../template_type_usage_folded_into_one.cc | 4 +- .../template_var_usage_folded_into_one.cc | 2 +- index_tests/types/anonymous_struct.cc | 10 +- index_tests/unions/union_decl.cc | 4 +- index_tests/unions/union_usage.cc | 4 +- .../usage/func_called_from_constructor.cc | 6 +- .../usage/func_called_from_macro_argument.cc | 2 +- .../usage/func_called_from_template.cc | 4 +- .../usage/func_called_implicit_ctor.cc | 6 +- index_tests/usage/func_usage_addr_func.cc | 2 +- index_tests/usage/func_usage_addr_method.cc | 2 +- index_tests/usage/func_usage_call_func.cc | 2 +- index_tests/usage/func_usage_call_method.cc | 4 +- .../usage/func_usage_class_inline_var_def.cc | 2 +- .../usage/func_usage_forward_decl_func.cc | 2 +- .../usage/func_usage_forward_decl_method.cc | 4 +- index_tests/usage/func_usage_template_func.cc | 2 +- .../usage/type_usage_as_template_parameter.cc | 4 +- ...ype_usage_as_template_parameter_complex.cc | 27 +++- ...type_usage_as_template_parameter_simple.cc | 2 +- index_tests/usage/type_usage_declare_field.cc | 4 +- index_tests/usage/type_usage_declare_param.cc | 4 +- .../type_usage_declare_param_prototype.cc | 2 +- .../usage/type_usage_declare_qualifiers.cc | 4 +- .../usage/type_usage_on_return_type.cc | 8 +- .../type_usage_typedef_and_using_template.cc | 34 ++++- index_tests/usage/type_usage_various.cc | 4 +- index_tests/usage/usage_inside_of_call.cc | 10 +- .../usage/usage_inside_of_call_simple.cc | 4 +- index_tests/usage/var_usage_call_function.cc | 4 +- index_tests/usage/var_usage_class_member.cc | 8 +- .../usage/var_usage_class_member_static.cc | 4 +- index_tests/usage/var_usage_cstyle_cast.cc | 4 +- index_tests/usage/var_usage_func_parameter.cc | 2 +- .../usage/var_usage_shadowed_parameter.cc | 2 +- index_tests/vars/class_member.cc | 2 +- index_tests/vars/class_static_member.cc | 4 +- .../vars/class_static_member_decl_only.cc | 2 +- index_tests/vars/function_param.cc | 4 +- index_tests/vars/function_shadow_param.cc | 2 +- src/indexer.cc | 56 ++++---- src/message_handler.cc | 15 ++- src/query.h | 9 -- 94 files changed, 444 insertions(+), 282 deletions(-) diff --git a/README.md b/README.md index 0da7b661c..7075260dd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ccls -ccls is a fork of cquery (originally written by Jacob Dufault), +ccls is a rewrite of cquery (originally written by Jacob Dufault), a C/C++/Objective-C language server. * code completion (with both signature help and snippets) @@ -16,16 +16,16 @@ a C/C++/Objective-C language server. It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ](../../wiki/FAQ). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. -The comparison with cquery as noted on 2018-05-17: +The comparison with cquery as noted on 2018-07-09: -| | cquery | ccls | -|------------ |--------------------------------|---------------------------| -| third_party | more | fewer | -| C++ | C++14 | C++17 | -| clang API | libclang (C) | libclang + clang/llvm C++ | -| Filesystem | AbsolutePath + custom routines | llvm/Support | -| index | | slight enhancement | -| pipeline | index merge+id remapping | simpler and more robust | +| | cquery | ccls | +|------------ |--------------------------------|------------------------------| +| third_party | more | fewer | +| C++ | C++14 | C++17 | +| clang API | libclang (C) | libclang + clang/llvm C++ | +| Filesystem | AbsolutePath + custom routines | llvm/Support | +| index | libclang | clangIndex, some enhancement | +| pipeline | index merge+id remapping | simpler and more robust | cquery has system include path detection (through running the compiler driver) while ccls does not. diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index b444e162d..fac49ff86 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -21,13 +21,13 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|514", + "spell": "3:3-3:6|15041163540773201510|2|1026", "extent": "3:3-3:11|15041163540773201510|2|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|15041163540773201510|2|8228", "8:17-8:20|15041163540773201510|2|8228"], + "uses": ["7:7-7:8|15041163540773201510|2|16420", "8:17-8:20|15041163540773201510|2|16420"], "callees": [] }, { "usr": 4259594751088586730, diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 32bfd0d8a..c144373d1 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -26,13 +26,13 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|514", + "spell": "3:3-3:6|15041163540773201510|2|1026", "extent": "3:3-3:11|15041163540773201510|2|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|15041163540773201510|2|8228"], + "uses": ["8:7-8:8|15041163540773201510|2|16420"], "callees": [] }, { "usr": 4259594751088586730, @@ -58,7 +58,7 @@ void foo() { "kind": 6, "storage": 0, "declarations": [], - "spell": "4:3-4:4|15041163540773201510|2|514", + "spell": "4:3-4:4|15041163540773201510|2|1026", "extent": "4:3-4:12|15041163540773201510|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index e84ae3ffe..3b81b4778 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -36,13 +36,13 @@ void Make() { "kind": 9, "storage": 0, "declarations": [], - "spell": "2:3-2:7|13487927231218873822|2|514", + "spell": "2:3-2:7|13487927231218873822|2|1026", "extent": "2:3-2:12|13487927231218873822|2|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|13487927231218873822|2|8228", "7:15-7:19|13487927231218873822|2|8228"], + "uses": ["6:8-6:12|13487927231218873822|2|16420", "7:15-7:19|13487927231218873822|2|16420"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 7f17706cb..283104433 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -20,7 +20,7 @@ Foo::Foo() {} "kind": 9, "storage": 0, "declarations": [], - "spell": "4:6-4:9|15041163540773201510|2|514", + "spell": "4:6-4:9|15041163540773201510|2|1026", "extent": "4:1-4:11|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index c5fc57889..e5631096f 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -36,7 +36,7 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "7:3-7:9|14935975554338052500|2|514", + "spell": "7:3-7:9|14935975554338052500|2|1026", "extent": "7:3-7:32|14935975554338052500|2|0", "declaring_type": 0, "bases": [], @@ -52,7 +52,7 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "6:3-6:9|14935975554338052500|2|514", + "spell": "6:3-6:9|14935975554338052500|2|1026", "extent": "6:3-6:17|14935975554338052500|2|0", "declaring_type": 0, "bases": [], @@ -68,7 +68,7 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "5:3-5:9|14935975554338052500|2|514", + "spell": "5:3-5:9|14935975554338052500|2|1026", "extent": "5:3-5:14|14935975554338052500|2|0", "declaring_type": 0, "bases": [], @@ -84,7 +84,7 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "8:3-8:9|14935975554338052500|2|514", + "spell": "8:3-8:9|14935975554338052500|2|1026", "extent": "8:3-8:30|14935975554338052500|2|0", "declaring_type": 0, "bases": [], @@ -138,6 +138,20 @@ OUTPUT: make_functions.cc }], "skipped_ranges": [], "usr2func": [{ + "usr": 768523651983844320, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [2555873744476712860, 2555873744476712860, 2555873744476712860], + "uses": [], + "callees": [] + }, { "usr": 2532818908869373467, "detailed_name": "T *maKE_NoRefs(Args ...args)", "qual_name_offset": 3, @@ -151,7 +165,7 @@ OUTPUT: make_functions.cc "bases": [], "derived": [], "vars": [3908732770590594660], - "uses": ["17:3-17:14|0|1|8228"], + "uses": ["17:3-17:14|0|1|16420"], "callees": [] }, { "usr": 2816883305867289955, @@ -169,6 +183,34 @@ OUTPUT: make_functions.cc "vars": [], "uses": [], "callees": [] + }, { + "usr": 11138976705878544996, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [16395392342608151399], + "uses": [], + "callees": [] + }, { + "usr": 11363675606380070883, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "declaring_type": 0, + "bases": [], + "derived": [], + "vars": [180270746871803062, 180270746871803062, 180270746871803062], + "uses": [], + "callees": [] }, { "usr": 15793662558620604611, "detailed_name": "T *MakeUnique(Args &&...args)", @@ -183,10 +225,40 @@ OUTPUT: make_functions.cc "bases": [], "derived": [], "vars": [8463700030555379526], - "uses": ["14:3-14:13|0|1|8228", "15:3-15:13|0|1|8228", "16:3-16:13|0|1|8228"], + "uses": ["14:3-14:13|0|1|16420", "15:3-15:13|0|1|16420", "16:3-16:13|0|1|16420"], "callees": [] }], "usr2type": [{ + "usr": 53, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [180270746871803062], + "uses": [] + }, { + "usr": 87, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [180270746871803062], + "uses": [] + }, { "usr": 12993848456528750350, "detailed_name": "struct Bar {}", "qual_name_offset": 7, @@ -218,12 +290,36 @@ OUTPUT: make_functions.cc "uses": ["14:14-14:20|0|1|4", "15:14-15:20|0|1|4", "16:14-16:20|0|1|4", "17:15-17:21|0|1|4"] }], "usr2var": [{ + "usr": 180270746871803062, + "detailed_name": "int args", + "qual_name_offset": 4, + "short_name": "args", + "declarations": [], + "spell": "9:24-9:28|11363675606380070883|3|1026", + "extent": "9:16-9:28|11363675606380070883|3|0", + "type": 87, + "uses": [], + "kind": 253, + "storage": 0 + }, { + "usr": 2555873744476712860, + "detailed_name": "int &&args", + "qual_name_offset": 6, + "short_name": "args", + "declarations": [], + "spell": "4:25-4:29|768523651983844320|3|1026", + "extent": "4:15-4:29|768523651983844320|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 0 + }, { "usr": 3908732770590594660, "detailed_name": "Args ...args", "qual_name_offset": 8, "short_name": "args", "declarations": [], - "spell": "9:24-9:28|2532818908869373467|3|514", + "spell": "9:24-9:28|2532818908869373467|3|1026", "extent": "9:16-9:28|2532818908869373467|3|0", "type": 0, "uses": [], @@ -235,12 +331,24 @@ OUTPUT: make_functions.cc "qual_name_offset": 10, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|15793662558620604611|3|514", + "spell": "4:25-4:29|15793662558620604611|3|1026", "extent": "4:15-4:29|15793662558620604611|3|0", "type": 0, "uses": [], "kind": 253, "storage": 0 + }, { + "usr": 16395392342608151399, + "detailed_name": "int &&args", + "qual_name_offset": 6, + "short_name": "args", + "declarations": [], + "spell": "4:25-4:29|11138976705878544996|3|1026", + "extent": "4:15-4:29|11138976705878544996|3|0", + "type": 0, + "uses": [], + "kind": 253, + "storage": 0 }] } */ diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index 3478c5e83..a4333abcf 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -50,7 +50,7 @@ class Foo { "qual_name_offset": 4, "short_name": "foo", "declarations": [], - "spell": "2:7-2:10|15041163540773201510|2|514", + "spell": "2:7-2:10|15041163540773201510|2|1026", "extent": "2:3-2:10|15041163540773201510|2|0", "type": 53, "uses": [], diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 5434f6cbc..0e5b32227 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -48,8 +48,8 @@ int Foo::foo; "detailed_name": "static int Foo::foo", "qual_name_offset": 11, "short_name": "foo", - "declarations": ["2:14-2:17|15041163540773201510|2|513"], - "spell": "5:10-5:13|15041163540773201510|2|514", + "declarations": ["2:14-2:17|15041163540773201510|2|1025"], + "spell": "5:10-5:13|15041163540773201510|2|1026", "extent": "5:1-5:13|0|1|0", "type": 53, "uses": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index a399d5d95..bbc66a25f 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -48,7 +48,7 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "b", "declarations": [], - "spell": "5:20-5:21|2747674671862363334|3|514", + "spell": "5:20-5:21|2747674671862363334|3|1026", "extent": "5:16-5:21|2747674671862363334|3|0", "type": 53, "uses": [], @@ -60,7 +60,7 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:13-5:14|2747674671862363334|3|514", + "spell": "5:13-5:14|2747674671862363334|3|1026", "extent": "5:9-5:14|2747674671862363334|3|0", "type": 53, "uses": [], diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 3b323d76e..92edeb9be 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -18,7 +18,7 @@ void Foo::def() {} "short_name": "declonly", "kind": 6, "storage": 0, - "declarations": ["2:8-2:16|15041163540773201510|2|513"], + "declarations": ["2:8-2:16|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -32,7 +32,7 @@ void Foo::def() {} "short_name": "purevirtual", "kind": 6, "storage": 0, - "declarations": ["3:16-3:27|15041163540773201510|2|577"], + "declarations": ["3:16-3:27|15041163540773201510|2|1089"], "declaring_type": 0, "bases": [], "derived": [], @@ -46,8 +46,8 @@ void Foo::def() {} "short_name": "def", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|15041163540773201510|2|513"], - "spell": "7:11-7:14|15041163540773201510|2|514", + "declarations": ["4:8-4:11|15041163540773201510|2|1025"], + "spell": "7:11-7:14|15041163540773201510|2|1026", "extent": "7:1-7:19|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 5e2ad16c5..34a1c978e 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -52,7 +52,7 @@ enum class Foo : uint8_t { "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|514", + "spell": "3:3-3:4|16985894625255407295|2|1026", "extent": "3:3-3:4|16985894625255407295|2|0", "type": 0, "uses": [], @@ -64,7 +64,7 @@ enum class Foo : uint8_t { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "4:3-4:4|16985894625255407295|2|514", + "spell": "4:3-4:4|16985894625255407295|2|1026", "extent": "4:3-4:9|16985894625255407295|2|0", "type": 0, "uses": [], diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index da4cfc64c..3b28d1aaf 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -34,7 +34,7 @@ enum Foo { "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|514", + "spell": "2:3-2:4|16985894625255407295|2|1026", "extent": "2:3-2:4|16985894625255407295|2|0", "type": 0, "uses": [], @@ -46,7 +46,7 @@ enum Foo { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|514", + "spell": "3:3-3:4|16985894625255407295|2|1026", "extent": "3:3-3:9|16985894625255407295|2|0", "type": 0, "uses": [], diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index fd36cf565..195b93d96 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -75,7 +75,7 @@ enum class E : int32_t { "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|514", + "spell": "2:3-2:4|16985894625255407295|2|1026", "extent": "2:3-2:4|16985894625255407295|2|0", "type": 0, "uses": [], @@ -87,7 +87,7 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|514", + "spell": "3:3-3:4|16985894625255407295|2|1026", "extent": "3:3-3:9|16985894625255407295|2|0", "type": 0, "uses": [], @@ -100,7 +100,7 @@ enum class E : int32_t { "short_name": "E0", "hover": "E::E0 = 0", "declarations": [], - "spell": "9:3-9:5|2986879766914123941|2|514", + "spell": "9:3-9:5|2986879766914123941|2|1026", "extent": "9:3-9:5|2986879766914123941|2|0", "type": 0, "uses": [], @@ -112,7 +112,7 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "E20", "declarations": [], - "spell": "10:3-10:6|2986879766914123941|2|514", + "spell": "10:3-10:6|2986879766914123941|2|1026", "extent": "10:3-10:11|2986879766914123941|2|0", "type": 0, "uses": [], diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index b086892bc..d7c94e44a 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -36,7 +36,7 @@ Foo x = Foo::A; "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|514", + "spell": "2:3-2:4|16985894625255407295|2|1026", "extent": "2:3-2:4|16985894625255407295|2|0", "type": 0, "uses": ["6:14-6:15|16985894625255407295|2|4"], @@ -61,7 +61,7 @@ Foo x = Foo::A; "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|514", + "spell": "3:3-3:4|16985894625255407295|2|1026", "extent": "3:3-3:9|16985894625255407295|2|0", "type": 0, "uses": [], diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 24ca7afb2..cdbe2762d 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -38,7 +38,7 @@ Foo b; "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:3-6:18|0|1|2", + "spell": "6:10-6:15|0|1|2", "extent": "6:3-6:18|0|1|0", "alias_of": 0, "bases": [], @@ -72,7 +72,7 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "4:1-7:2|0|1|2", + "spell": "5:8-5:11|0|1|2", "extent": "4:1-7:2|0|1|0", "alias_of": 0, "bases": [], @@ -106,7 +106,7 @@ Foo b; "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|514", + "spell": "6:10-6:15|10528472276654770367|2|1026", "extent": "6:3-6:18|10528472276654770367|2|0", "alias_of": 0, "bases": [], diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index 681498522..3f797bc1f 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -23,7 +23,7 @@ class Derived : public Parent {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:30|0|1|1028"] + "uses": ["2:24-2:30|0|1|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Parent {}", diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 1c9f1b9c0..14bedb593 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -34,7 +34,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:43-13:51|0|1|1028"] + "uses": ["13:43-13:51|0|1|2052"] }, { "usr": 10651399730831737929, "detailed_name": "class Derived2 : Base2 {}", @@ -51,7 +51,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:56-13:64|0|1|1028"] + "uses": ["13:56-13:64|0|1|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}", @@ -68,7 +68,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:33-13:40|0|1|1028", "13:65-13:72|0|1|1028"] + "uses": ["13:33-13:40|0|1|2052", "13:65-13:72|0|1|2052"] }, { "usr": 11118288764693061434, "detailed_name": "class Base2 {}", @@ -85,7 +85,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["11:18-11:23|0|1|1028", "13:27-13:32|0|1|1028"] + "uses": ["13:27-13:32|0|1|2052"] }, { "usr": 11930058224338108382, "detailed_name": "class Base1 {}", @@ -102,7 +102,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["8:18-8:23|0|1|1028", "13:17-13:22|0|1|1028"] + "uses": ["13:17-13:22|0|1|2052"] }], "usr2var": [] } diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index 377426327..18164c614 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -25,7 +25,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:28|0|1|1028", "3:24-3:28|0|1|1028"] + "uses": ["2:24-2:28|0|1|2052", "3:24-3:28|0|1|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public MiddleA, public MiddleB {}", @@ -59,7 +59,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:24-4:31|0|1|1028"] + "uses": ["4:24-4:31|0|1|2052"] }, { "usr": 14022569716337624303, "detailed_name": "class MiddleB : public Root {}", @@ -76,7 +76,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:40-4:47|0|1|1028"] + "uses": ["4:40-4:47|0|1|2052"] }], "usr2var": [] } diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 446e08167..94348b67b 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -18,7 +18,7 @@ class Derived : public Root { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:8-5:11|10963370434658308541|2|2626", + "spell": "5:8-5:11|10963370434658308541|2|5186", "extent": "5:3-5:25|10963370434658308541|2|0", "declaring_type": 0, "bases": [9948027785633571339], @@ -33,7 +33,7 @@ class Derived : public Root { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:16-2:19|3897841498936210886|2|577"], + "declarations": ["2:16-2:19|3897841498936210886|2|1089"], "declaring_type": 0, "bases": [], "derived": [6666242542855173890], @@ -57,7 +57,7 @@ class Derived : public Root { "funcs": [9948027785633571339], "vars": [], "instances": [], - "uses": ["4:24-4:28|0|1|1028"] + "uses": ["4:24-4:28|0|1|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Root {}", diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index 2778e0af7..b68b4d289 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -14,7 +14,7 @@ class IFoo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:16-2:19|9949214233977131946|2|577"], + "declarations": ["2:16-2:19|9949214233977131946|2|1089"], "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 1d86907fd..6b128d747 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -21,7 +21,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:12|15826803741381445676|2|578", + "spell": "5:11-5:12|15826803741381445676|2|1090", "extent": "5:3-5:23|15826803741381445676|2|0", "declaring_type": 0, "bases": [], @@ -37,7 +37,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "8:3-8:4|10963370434658308541|2|2626", + "spell": "8:3-8:4|10963370434658308541|2|5186", "extent": "8:3-8:26|10963370434658308541|2|0", "declaring_type": 0, "bases": [], @@ -53,7 +53,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:11-2:12|11628904180681204356|2|578", + "spell": "2:11-2:12|11628904180681204356|2|1090", "extent": "2:3-2:23|11628904180681204356|2|0", "declaring_type": 0, "bases": [], @@ -95,7 +95,7 @@ struct Derived : Base0, Base1 { "funcs": [16347272523198263017], "vars": [], "instances": [], - "uses": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|1028"] + "uses": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|2052"] }, { "usr": 15826803741381445676, "detailed_name": "struct Base1 {}", @@ -112,7 +112,7 @@ struct Derived : Base0, Base1 { "funcs": [8401779086123965305], "vars": [], "instances": [], - "uses": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|1028"] + "uses": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|2052"] }], "usr2var": [] } diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index a6284a4bf..983889e99 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -44,7 +44,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:14-9:15|14635009347499519042|2|8228", "10:14-10:15|14635009347499519042|2|8228", "11:14-11:15|14635009347499519042|2|8228"], + "uses": ["9:14-9:15|14635009347499519042|2|16420", "10:14-10:15|14635009347499519042|2|16420", "11:14-11:15|14635009347499519042|2|16420"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 38c8e22bd..70d813855 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -46,7 +46,7 @@ FOO(make1(), make2); "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|0|1|8228"], + "uses": ["12:5-12:10|0|1|16420"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index c2e05248c..e1c339203 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -20,7 +20,7 @@ int x = A; "kind": 9, "storage": 0, "declarations": [], - "spell": "5:12-5:15|15041163540773201510|2|514", + "spell": "5:12-5:15|15041163540773201510|2|1026", "extent": "1:1-1:1|15041163540773201510|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index c423ccdf1..7d00e90ee 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -18,7 +18,7 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|513"], + "declarations": ["2:8-2:11|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 8fb481a6b..3f129e24c 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -16,8 +16,8 @@ void Foo::foo() const {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|513"], - "spell": "5:11-5:14|15041163540773201510|2|514", + "declarations": ["2:8-2:11|15041163540773201510|2|1025"], + "spell": "5:11-5:14|15041163540773201510|2|1026", "extent": "5:1-5:25|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index e676130fb..601d5d313 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -15,7 +15,7 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:11|15041163540773201510|2|514", + "spell": "2:8-2:11|15041163540773201510|2|1026", "extent": "2:3-2:16|15041163540773201510|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index f49c62977..d3504989f 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -33,9 +33,9 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "A", "hover": "A = 0", - "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", "declarations": [], - "spell": "4:1-4:2|16985894625255407295|2|514", + "spell": "4:1-4:2|16985894625255407295|2|1026", "extent": "4:1-4:2|16985894625255407295|2|0", "type": 0, "uses": [], @@ -47,9 +47,9 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "C", "hover": "C = 2", - "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", "declarations": [], - "spell": "6:1-6:2|16985894625255407295|2|514", + "spell": "6:1-6:2|16985894625255407295|2|1026", "extent": "6:1-6:2|16985894625255407295|2|0", "type": 0, "uses": [], @@ -61,9 +61,9 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "B", "hover": "B = 1", - "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", "declarations": [], - "spell": "5:1-5:2|16985894625255407295|2|514", + "spell": "5:1-5:2|16985894625255407295|2|1026", "extent": "5:1-5:2|16985894625255407295|2|0", "type": 0, "uses": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 8501799bc..369504355 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -108,7 +108,7 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["5:26-5:30|0|1|1028"] + "uses": ["5:26-5:30|0|1|2052"] }, { "usr": 16750616846959666305, "detailed_name": "struct SameFileDerived : Base {}", @@ -146,7 +146,7 @@ OUTPUT: header.h "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "15:13-15:14|4481210672785600703|2|514", + "spell": "15:13-15:14|4481210672785600703|2|1026", "extent": "15:13-15:14|4481210672785600703|2|0", "type": 0, "uses": [], @@ -159,7 +159,7 @@ OUTPUT: header.h "short_name": "C", "hover": "C = 2", "declarations": [], - "spell": "15:19-15:20|4481210672785600703|2|514", + "spell": "15:19-15:20|4481210672785600703|2|1026", "extent": "15:19-15:20|4481210672785600703|2|0", "type": 0, "uses": [], @@ -184,7 +184,7 @@ OUTPUT: header.h "short_name": "B", "hover": "B = 1", "declarations": [], - "spell": "15:16-15:17|4481210672785600703|2|514", + "spell": "15:16-15:17|4481210672785600703|2|1026", "extent": "15:16-15:17|4481210672785600703|2|0", "type": 0, "uses": [], @@ -227,7 +227,7 @@ OUTPUT: impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:7|0|1|8228"], + "uses": ["4:3-4:7|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 1e6e95195..fa2b9fb11 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -62,7 +62,7 @@ OUTPUT: simple_impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:9|0|1|8228"], + "uses": ["4:3-4:9|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index bc5e50a40..9ef71ea26 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -14,7 +14,7 @@ OUTPUT: static.h "short_name": "CreateSharedBuffer", "kind": 6, "storage": 0, - "declarations": ["4:15-4:33|9411323049603567600|2|513"], + "declarations": ["4:15-4:33|9411323049603567600|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -57,7 +57,7 @@ OUTPUT: static.cc "kind": 6, "storage": 0, "declarations": [], - "spell": "3:14-3:32|9411323049603567600|2|514", + "spell": "3:14-3:32|9411323049603567600|2|1026", "extent": "3:1-3:37|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 4a65e65e5..f73d3e180 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -14,7 +14,7 @@ void foo(int a, int b); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["2:6-2:9|2029211996748007610|2|513"], + "declarations": ["2:6-2:9|2029211996748007610|2|1025"], "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index 08bec46ec..a003e49fd 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -15,7 +15,7 @@ void foo() {} "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:9|2029211996748007610|2|514", + "spell": "2:6-2:9|2029211996748007610|2|1026", "extent": "2:1-2:14|2029211996748007610|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index 4e728b302..09a336984 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -16,7 +16,7 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|513"], + "declarations": ["3:8-3:11|4508214972876735896|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -46,7 +46,7 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|514", + "spell": "2:7-2:10|2029211996748007610|2|1026", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index ed61dfe28..e83677296 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -18,8 +18,8 @@ void Foo::foo() {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|513"], - "spell": "6:11-6:14|4508214972876735896|2|514", + "declarations": ["3:8-3:11|4508214972876735896|2|1025"], + "spell": "6:11-6:14|4508214972876735896|2|1026", "extent": "6:1-6:19|2029211996748007610|2|0", "declaring_type": 0, "bases": [], @@ -50,7 +50,7 @@ void Foo::foo() {} "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|514", + "spell": "2:7-2:10|2029211996748007610|2|1026", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index 3890719dc..bd8dda460 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -17,7 +17,7 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "3:8-3:11|4508214972876735896|2|514", + "spell": "3:8-3:11|4508214972876735896|2|1026", "extent": "3:3-3:16|4508214972876735896|2|0", "declaring_type": 0, "bases": [], @@ -48,7 +48,7 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|514", + "spell": "2:7-2:10|2029211996748007610|2|1026", "extent": "2:1-4:2|2029211996748007610|2|0", "alias_of": 0, "bases": [], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 32c420fa0..f42a38b03 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -86,7 +86,7 @@ void func() { "qual_name_offset": 10, "short_name": "baz", "kind": 3, - "declarations": ["3:20-3:23|17805385787823406700|2|513"], + "declarations": ["3:20-3:23|17805385787823406700|2|1025"], "alias_of": 0, "bases": [], "derived": [], @@ -104,7 +104,7 @@ void func() { "qual_name_offset": 10, "short_name": "bar", "kind": 3, - "declarations": ["2:15-2:18|926793467007732869|2|513"], + "declarations": ["2:15-2:18|926793467007732869|2|1025"], "alias_of": 0, "bases": [], "derived": [], @@ -147,7 +147,7 @@ void func() { "short_name": "qux", "hover": "int foo::bar::baz::qux = 42", "declarations": [], - "spell": "4:18-4:21|14450849931009540802|2|514", + "spell": "4:18-4:21|14450849931009540802|2|1026", "extent": "4:14-4:26|14450849931009540802|2|0", "type": 53, "uses": ["12:26-12:29|14450849931009540802|2|12", "13:16-13:19|14450849931009540802|2|12"], diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 323c6d918..815133e20 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -38,13 +38,13 @@ void Runner() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:8-3:14|11072669167287398027|2|514", + "spell": "3:8-3:14|11072669167287398027|2|1026", "extent": "3:3-3:24|11072669167287398027|2|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [3649375698083002347], - "uses": ["7:7-7:13|11072669167287398027|2|8228", "9:3-9:9|11072669167287398027|2|8228"], + "uses": ["7:7-7:13|11072669167287398027|2|16420", "9:3-9:9|11072669167287398027|2|16420"], "callees": [] }], "usr2type": [{ @@ -87,7 +87,7 @@ void Runner() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "3:19-3:20|17328473273923617489|3|514", + "spell": "3:19-3:20|17328473273923617489|3|1026", "extent": "3:15-3:20|17328473273923617489|3|0", "type": 53, "uses": [], @@ -99,7 +99,7 @@ void Runner() { "qual_name_offset": 4, "short_name": "Foo", "declarations": [], - "spell": "2:7-2:10|11072669167287398027|2|514", + "spell": "2:7-2:10|11072669167287398027|2|1026", "extent": "2:3-2:10|11072669167287398027|2|0", "type": 53, "uses": ["7:18-7:21|11072669167287398027|2|12", "9:10-9:13|11072669167287398027|2|12"], diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 2463ce439..2a5d10449 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -18,7 +18,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["3:8-3:16|15041163540773201510|2|513"], + "declarations": ["3:8-3:16|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -32,7 +32,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["4:7-4:15|15041163540773201510|2|513"], + "declarations": ["4:7-4:15|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:16|15041163540773201510|2|514", + "spell": "2:8-2:16|15041163540773201510|2|1026", "extent": "2:3-2:27|15041163540773201510|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 6f6818e0a..9f5f84b67 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -18,7 +18,7 @@ OUTPUT: static_function_in_type.h "short_name": "Register", "kind": 6, "storage": 0, - "declarations": ["6:15-6:23|17262466801709381811|2|513"], + "declarations": ["6:15-6:23|17262466801709381811|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -32,7 +32,7 @@ OUTPUT: static_function_in_type.h "qual_name_offset": 6, "short_name": "Manager", "kind": 5, - "declarations": ["3:7-3:14|11072669167287398027|2|513"], + "declarations": ["3:7-3:14|11072669167287398027|2|1025"], "alias_of": 0, "bases": [], "derived": [], @@ -63,7 +63,7 @@ OUTPUT: static_function_in_type.h "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|11072669167287398027|2|514", + "spell": "5:8-5:11|11072669167287398027|2|1026", "extent": "5:1-7:2|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -92,7 +92,7 @@ OUTPUT: static_function_in_type.cc "storage": 0, "comments": "static", "declarations": [], - "spell": "5:11-5:19|17262466801709381811|2|514", + "spell": "5:11-5:19|17262466801709381811|2|1026", "extent": "5:1-6:2|11072669167287398027|2|0", "declaring_type": 0, "bases": [], @@ -153,7 +153,7 @@ OUTPUT: static_function_in_type.cc "qual_name_offset": 13, "short_name": "m", "declarations": [], - "spell": "5:29-5:30|17019747379608639279|3|514", + "spell": "5:29-5:30|17019747379608639279|3|1026", "extent": "5:20-5:30|17019747379608639279|3|0", "type": 1972401196751872203, "uses": [], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 400b610f2..4945caf43 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -19,8 +19,8 @@ void Foo::Bar(Template&) {} "short_name": "Bar", "kind": 6, "storage": 0, - "declarations": ["5:8-5:11|15041163540773201510|2|513"], - "spell": "8:11-8:14|15041163540773201510|2|514", + "declarations": ["5:8-5:11|15041163540773201510|2|1025"], + "spell": "8:11-8:14|15041163540773201510|2|1026", "extent": "8:1-8:36|0|1|0", "declaring_type": 0, "bases": [], @@ -30,6 +30,21 @@ void Foo::Bar(Template&) {} "callees": [] }], "usr2type": [{ + "usr": 2100211316767379401, + "detailed_name": "template<> class Template", + "qual_name_offset": 17, + "short_name": "Template", + "kind": 5, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:12-5:20|0|1|4", "8:15-8:23|0|1|4"] + }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, @@ -62,7 +77,7 @@ void Foo::Bar(Template&) {} "funcs": [], "vars": [], "instances": [], - "uses": ["5:12-5:20|0|1|4", "8:15-8:23|0|1|4"] + "uses": [] }], "usr2var": [] } diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index e4a75de56..934522e8c 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -42,7 +42,7 @@ namespace ns { "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "2:8-2:15|11072669167287398027|2|514", + "spell": "2:8-2:15|11072669167287398027|2|1026", "extent": "2:3-2:18|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -80,7 +80,7 @@ namespace ns { "short_name": "Holder", "kind": 23, "declarations": [], - "spell": "5:10-5:16|11072669167287398027|2|514", + "spell": "5:10-5:16|11072669167287398027|2|1026", "extent": "5:3-7:4|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -97,8 +97,8 @@ namespace ns { "qual_name_offset": 29, "short_name": "static_var", "hover": "static constexpr ns::VarType ns::Holder::static_var = (VarType)0x0", - "declarations": ["6:30-6:40|12688716854043726585|2|513"], - "spell": "10:37-10:47|12688716854043726585|2|514", + "declarations": ["6:30-6:40|12688716854043726585|2|1025"], + "spell": "10:37-10:47|12688716854043726585|2|1026", "extent": "9:3-10:47|11072669167287398027|2|0", "type": 1532099849728741556, "uses": ["13:26-13:36|11072669167287398027|2|12", "14:27-14:37|11072669167287398027|2|12"], @@ -111,7 +111,7 @@ namespace ns { "short_name": "Foo2", "hover": "int ns::Foo2 = Holder::static_var", "declarations": [], - "spell": "14:7-14:11|11072669167287398027|2|514", + "spell": "14:7-14:11|11072669167287398027|2|1026", "extent": "14:3-14:37|11072669167287398027|2|0", "type": 53, "uses": [], @@ -124,7 +124,7 @@ namespace ns { "short_name": "Foo", "hover": "int ns::Foo = Holder::static_var", "declarations": [], - "spell": "13:7-13:10|11072669167287398027|2|514", + "spell": "13:7-13:10|11072669167287398027|2|1026", "extent": "13:3-13:36|11072669167287398027|2|0", "type": 53, "uses": [], diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index a9d7f9e20..db98e0c0b 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -48,7 +48,7 @@ void foo() { "short_name": "bar", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|8402783583255987702|2|513"], + "declarations": ["4:8-4:11|8402783583255987702|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -83,7 +83,7 @@ void foo() { "short_name": "T", "kind": 26, "declarations": [], - "spell": "1:11-1:18|8402783583255987702|2|2", + "spell": "1:17-1:18|8402783583255987702|2|2", "extent": "1:11-1:18|8402783583255987702|2|0", "alias_of": 0, "bases": [], @@ -100,7 +100,7 @@ void foo() { "qual_name_offset": 2, "short_name": "x", "declarations": [], - "spell": "3:5-3:6|8402783583255987702|2|514", + "spell": "3:5-3:6|8402783583255987702|2|1026", "extent": "3:3-3:6|8402783583255987702|2|0", "type": 14750650276757822712, "uses": [], diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 909cce9e3..55452c0b9 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -24,7 +24,7 @@ namespace ns { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:16-5:19|14042997404480181958|2|514", + "spell": "5:16-5:19|14042997404480181958|2|1026", "extent": "5:5-7:6|14042997404480181958|2|0", "declaring_type": 0, "bases": [], @@ -76,7 +76,7 @@ namespace ns { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "3:10-3:13|11072669167287398027|2|514", + "spell": "3:10-3:13|11072669167287398027|2|1026", "extent": "3:3-8:4|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -94,7 +94,7 @@ namespace ns { "short_name": "b", "hover": "int ns::b = Foo::foo()", "declarations": [], - "spell": "11:7-11:8|11072669167287398027|2|514", + "spell": "11:7-11:8|11072669167287398027|2|1026", "extent": "11:3-11:35|11072669167287398027|2|0", "type": 53, "uses": [], @@ -107,7 +107,7 @@ namespace ns { "short_name": "a", "hover": "int ns::a = Foo::foo()", "declarations": [], - "spell": "10:7-10:8|11072669167287398027|2|514", + "spell": "10:7-10:8|11072669167287398027|2|1026", "extent": "10:3-10:33|11072669167287398027|2|0", "type": 53, "uses": [], diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index aeb397deb..8563a02e7 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -19,7 +19,7 @@ namespace ns { "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "2:3-3:15|11072669167287398027|2|2", + "spell": "3:9-3:12|11072669167287398027|2|2", "extent": "2:3-3:15|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -36,7 +36,7 @@ namespace ns { "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "2:3-3:15|11072669167287398027|2|2", + "spell": "3:9-3:12|11072669167287398027|2|2", "extent": "2:3-3:15|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -74,7 +74,7 @@ namespace ns { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|514", + "spell": "3:9-3:12|11072669167287398027|2|1026", "extent": "3:3-3:15|11072669167287398027|2|0", "alias_of": 0, "bases": [], @@ -91,7 +91,7 @@ namespace ns { "qual_name_offset": 4, "short_name": "b", "declarations": [], - "spell": "6:13-6:14|11072669167287398027|2|514", + "spell": "6:13-6:14|11072669167287398027|2|1026", "extent": "6:3-6:14|11072669167287398027|2|0", "type": 3948666349864691553, "uses": [], @@ -103,7 +103,7 @@ namespace ns { "qual_name_offset": 9, "short_name": "a", "declarations": [], - "spell": "5:12-5:13|11072669167287398027|2|514", + "spell": "5:12-5:13|11072669167287398027|2|1026", "extent": "5:3-5:13|11072669167287398027|2|0", "type": 8224244241460152567, "uses": [], diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 2acb713fb..3c92252d7 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -68,7 +68,7 @@ void foo(float Value); "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["27:8-27:13|1663022413889915338|2|513"], + "declarations": ["27:8-27:13|1663022413889915338|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -98,7 +98,7 @@ void foo(float Value); "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["13:8-13:13|7440942986741176606|2|513"], + "declarations": ["13:8-13:13|7440942986741176606|2|1025"], "declaring_type": 0, "bases": [], "derived": [], @@ -137,7 +137,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["7:1-7:9|0|1|4"] }, { "usr": 1663022413889915338, "detailed_name": "template<> class vector> {}", @@ -154,7 +154,7 @@ void foo(float Value); "funcs": [6113470698424012876], "vars": [], "instances": [15931696253641284761], - "uses": [] + "uses": ["26:7-26:13|0|1|4", "33:1-33:7|0|1|4"] }, { "usr": 3231449734830406187, "detailed_name": "function", @@ -162,7 +162,7 @@ void foo(float Value); "short_name": "function", "kind": 26, "declarations": [], - "spell": "4:1-5:30|0|1|2", + "spell": "5:7-5:15|0|1|2", "extent": "4:1-5:30|0|1|0", "alias_of": 0, "bases": [], @@ -188,7 +188,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["32:8-32:10|0|1|4"] + "uses": ["21:23-21:25|0|1|4", "32:8-32:10|0|1|4"] }, { "usr": 7440942986741176606, "detailed_name": "class vector {}", @@ -205,7 +205,7 @@ void foo(float Value); "funcs": [18107614608385228556], "vars": [], "instances": [], - "uses": ["17:7-17:13|0|1|4", "26:7-26:13|0|1|4", "30:1-30:7|0|1|4", "31:1-31:7|0|1|4", "32:1-32:7|0|1|4", "33:1-33:7|0|1|4"] + "uses": ["21:16-21:22|0|1|4", "30:1-30:7|0|1|4", "32:1-32:7|0|1|4"] }, { "usr": 9201299975592934124, "detailed_name": "enum Enum {\n}", @@ -247,7 +247,7 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "16:1-17:20|0|1|2", + "spell": "17:7-17:13|0|1|2", "extent": "16:1-17:20|0|1|0", "alias_of": 0, "bases": [], @@ -264,7 +264,7 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "11:1-14:2|0|1|2", + "spell": "12:7-12:13|0|1|2", "extent": "11:1-14:2|0|1|0", "alias_of": 0, "bases": [], @@ -281,7 +281,7 @@ void foo(float Value); "short_name": "T", "kind": 26, "declarations": [], - "spell": "38:11-38:21|17498190318698490707|3|2", + "spell": "38:20-38:21|17498190318698490707|3|2", "extent": "38:11-38:21|17498190318698490707|3|0", "alias_of": 0, "bases": [], @@ -305,7 +305,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["5:7-5:15|0|1|4", "7:1-7:9|0|1|4"] + "uses": [] }, { "usr": 15440970074034693939, "detailed_name": "vector", @@ -313,7 +313,7 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "21:1-21:26|0|1|2", + "spell": "21:16-21:22|0|1|2", "extent": "21:1-21:26|0|1|0", "alias_of": 0, "bases": [], @@ -337,7 +337,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["11:39-11:48|0|1|4"] + "uses": [] }, { "usr": 16155717907537731864, "detailed_name": "template class vector> {}", @@ -354,7 +354,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["31:1-31:7|0|1|4"] }], "usr2var": [{ "usr": 86949563628772958, @@ -399,7 +399,7 @@ void foo(float Value); "short_name": "Enum1", "hover": "Enum1 = 1", "declarations": [], - "spell": "36:10-36:15|9201299975592934124|2|514", + "spell": "36:10-36:15|9201299975592934124|2|1026", "extent": "36:10-36:15|9201299975592934124|2|0", "type": 0, "uses": [], @@ -437,7 +437,7 @@ void foo(float Value); "short_name": "Enum0", "hover": "Enum0 = 0", "declarations": [], - "spell": "36:3-36:8|9201299975592934124|2|514", + "spell": "36:3-36:8|9201299975592934124|2|1026", "extent": "36:3-36:8|9201299975592934124|2|0", "type": 0, "uses": ["43:20-43:25|9201299975592934124|2|4"], @@ -461,7 +461,7 @@ void foo(float Value); "qual_name_offset": 2, "short_name": "Value", "declarations": [], - "spell": "39:12-39:17|17498190318698490707|3|514", + "spell": "39:12-39:17|17498190318698490707|3|1026", "extent": "39:10-39:17|17498190318698490707|3|0", "type": 14111105212951082474, "uses": [], diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index d23cf26a6..1add46b70 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -30,7 +30,7 @@ void Template::Foo() {} "kind": 6, "storage": 0, "declarations": [], - "spell": "10:22-10:25|17649312483543982122|2|514", + "spell": "10:22-10:25|17649312483543982122|2|1026", "extent": "9:1-10:30|0|1|0", "declaring_type": 0, "bases": [], @@ -45,8 +45,8 @@ void Template::Foo() {} "short_name": "Foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|17107291254533526269|2|513"], - "spell": "7:19-7:22|17107291254533526269|2|514", + "declarations": ["3:8-3:11|17107291254533526269|2|1025"], + "spell": "7:19-7:22|17107291254533526269|2|1026", "extent": "6:1-7:24|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index ea9f0bf04..741c23562 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -21,7 +21,7 @@ int b = Foo::foo(); "kind": 6, "storage": 0, "declarations": [], - "spell": "3:14-3:17|10528472276654770367|2|514", + "spell": "3:14-3:17|10528472276654770367|2|1026", "extent": "3:3-5:4|10528472276654770367|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 52533cdd0..e969f6500 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -22,7 +22,7 @@ int b = Foo::foo(); "kind": 6, "storage": 0, "declarations": [], - "spell": "4:14-4:17|10528472276654770367|2|514", + "spell": "4:14-4:17|10528472276654770367|2|1026", "extent": "4:3-6:4|10528472276654770367|2|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 37377cbc7..f80e5f0ee 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -57,7 +57,7 @@ VarDecl b "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:3-6:18|0|1|2", + "spell": "6:10-6:15|0|1|2", "extent": "6:3-6:18|0|1|0", "alias_of": 0, "bases": [], @@ -108,7 +108,7 @@ VarDecl b "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|514", + "spell": "6:10-6:15|10528472276654770367|2|1026", "extent": "6:3-6:18|10528472276654770367|2|0", "alias_of": 0, "bases": [], @@ -125,7 +125,7 @@ VarDecl b "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:3-6:18|0|1|2", + "spell": "6:10-6:15|0|1|2", "extent": "6:3-6:18|0|1|0", "alias_of": 0, "bases": [], diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index a6a84ad86..8ab2b8dc0 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -64,7 +64,7 @@ int b = Foo::var; "qual_name_offset": 21, "short_name": "var", "hover": "static constexpr int Foo::var = 3", - "declarations": ["3:24-3:27|10528472276654770367|2|513"], + "declarations": ["3:24-3:27|10528472276654770367|2|1025"], "type": 53, "uses": ["6:19-6:22|10528472276654770367|2|12", "7:20-7:23|10528472276654770367|2|12"], "kind": 13, diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 0ecebac89..863998925 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -17,7 +17,7 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "1:1-2:13|0|1|2", + "spell": "2:7-2:10|0|1|2", "extent": "1:1-2:13|0|1|0", "alias_of": 0, "bases": [], @@ -51,7 +51,7 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "1:1-2:13|0|1|2", + "spell": "2:7-2:10|0|1|2", "extent": "1:1-2:13|0|1|0", "alias_of": 0, "bases": [], diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index b4ef49773..e325205db 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -60,7 +60,7 @@ UnexposedDecl var "short_name": "T", "kind": 26, "declarations": [], - "spell": "4:10-4:20|0|1|2", + "spell": "4:19-4:20|0|1|2", "extent": "4:10-4:20|0|1|0", "alias_of": 0, "bases": [], diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 370d30e54..ef3810131 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -31,7 +31,7 @@ union vector3 { "short_name": "", "kind": 23, "declarations": [], - "spell": "2:3-2:9|17937907487590875128|2|514", + "spell": "2:3-2:9|17937907487590875128|2|1026", "extent": "2:3-2:28|17937907487590875128|2|0", "alias_of": 0, "bases": [], @@ -80,7 +80,7 @@ union vector3 { "qual_name_offset": 6, "short_name": "v", "declarations": [], - "spell": "3:9-3:10|17937907487590875128|2|514", + "spell": "3:9-3:10|17937907487590875128|2|1026", "extent": "3:3-3:13|17937907487590875128|2|0", "type": 0, "uses": [], @@ -92,7 +92,7 @@ union vector3 { "qual_name_offset": 6, "short_name": "x", "declarations": [], - "spell": "2:18-2:19|1428566502523368801|2|514", + "spell": "2:18-2:19|1428566502523368801|2|1026", "extent": "2:12-2:19|1428566502523368801|2|0", "type": 82, "uses": [], @@ -104,7 +104,7 @@ union vector3 { "qual_name_offset": 6, "short_name": "y", "declarations": [], - "spell": "2:21-2:22|1428566502523368801|2|514", + "spell": "2:21-2:22|1428566502523368801|2|1026", "extent": "2:12-2:22|1428566502523368801|2|0", "type": 82, "uses": [], @@ -116,7 +116,7 @@ union vector3 { "qual_name_offset": 6, "short_name": "z", "declarations": [], - "spell": "2:24-2:25|1428566502523368801|2|514", + "spell": "2:24-2:25|1428566502523368801|2|1026", "extent": "2:12-2:25|1428566502523368801|2|0", "type": 82, "uses": [], diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index b7500dbc8..9a3ae5f98 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -69,7 +69,7 @@ union Foo { "qual_name_offset": 0, "short_name": "b", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|514", + "spell": "3:8-3:9|8501689086387244262|2|1026", "extent": "3:3-3:9|8501689086387244262|2|0", "type": 37, "uses": [], @@ -81,7 +81,7 @@ union Foo { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|514", + "spell": "2:7-2:8|8501689086387244262|2|1026", "extent": "2:3-2:8|8501689086387244262|2|0", "type": 53, "uses": [], diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 148bf27b5..ee53d3fb4 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -105,7 +105,7 @@ void act(Foo*) { "qual_name_offset": 0, "short_name": "b", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|514", + "spell": "3:8-3:9|8501689086387244262|2|1026", "extent": "3:3-3:13|8501689086387244262|2|0", "type": 37, "uses": [], @@ -117,7 +117,7 @@ void act(Foo*) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|514", + "spell": "2:7-2:8|8501689086387244262|2|1026", "extent": "2:3-2:12|8501689086387244262|2|0", "type": 53, "uses": ["9:5-9:6|8501689086387244262|2|20"], diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 9757455b5..3a874534f 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -27,7 +27,7 @@ Foo::Foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|0|1|8228"], + "uses": ["8:3-8:9|0|1|16420"], "callees": [] }, { "usr": 3385168158331140247, @@ -36,8 +36,8 @@ Foo::Foo() { "short_name": "Foo", "kind": 9, "storage": 0, - "declarations": ["4:3-4:6|15041163540773201510|2|513"], - "spell": "7:6-7:9|15041163540773201510|2|514", + "declarations": ["4:3-4:6|15041163540773201510|2|1025"], + "spell": "7:6-7:9|15041163540773201510|2|1026", "extent": "7:1-9:2|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 3215fa23d..ce4e865ce 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -23,7 +23,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|0|1|8228"], + "uses": ["6:14-6:20|0|1|16420"], "callees": [] }, { "usr": 11404881820527069090, diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 9ca6b37a6..19a12e696 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -28,7 +28,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|0|1|8228"], + "uses": ["5:3-5:9|0|1|16420"], "callees": [] }, { "usr": 4259594751088586730, @@ -60,7 +60,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:3-9:9|0|1|8228"], + "uses": ["9:3-9:9|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index f4a075192..78ef5d0a1 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -27,7 +27,7 @@ Wrapper caller() { "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|0|1|8228"], + "uses": ["8:10-8:16|0|1|16420"], "callees": [] }, { "usr": 10544127002917214589, @@ -36,12 +36,12 @@ Wrapper caller() { "short_name": "Wrapper", "kind": 9, "storage": 0, - "declarations": ["2:3-2:10|13611487872560323389|2|513"], + "declarations": ["2:3-2:10|13611487872560323389|2|1025"], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|13611487872560323389|2|8228"], + "uses": ["8:10-8:16|13611487872560323389|2|16420"], "callees": [] }, { "usr": 11404881820527069090, diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 49afc9ac3..f6fa7e868 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -58,7 +58,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["7:3-7:10|0|1|8228"], + "uses": ["7:3-7:10|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 27508d544..aec722252 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -35,7 +35,7 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|513"], + "declarations": ["2:8-2:12|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index b2c0e8967..acf35619c 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -22,7 +22,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["3:3-3:9|0|1|8228"], + "uses": ["3:3-3:9|0|1|16420"], "callees": [] }, { "usr": 11404881820527069090, diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 3a78b2fd0..9cd1fa562 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -35,12 +35,12 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|513"], + "declarations": ["2:8-2:12|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:10|15041163540773201510|2|8228"], + "uses": ["7:6-7:10|15041163540773201510|2|16420"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 0a94d6e6c..dbbd7288a 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -71,7 +71,7 @@ class Foo { "short_name": "x", "hover": "int Foo::x = helper()", "declarations": [], - "spell": "6:7-6:8|15041163540773201510|2|514", + "spell": "6:7-6:8|15041163540773201510|2|1026", "extent": "6:3-6:19|15041163540773201510|2|0", "type": 53, "uses": [], diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index bf7c7c5ad..5796e6401 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -20,7 +20,7 @@ void usage() { "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:6|0|1|8228"], + "uses": ["4:3-4:6|0|1|16420"], "callees": [] }, { "usr": 6767773193109753523, diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index e1ee4d453..19fa07184 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -34,12 +34,12 @@ void usage() { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|513"], + "declarations": ["2:8-2:11|15041163540773201510|2|1025"], "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:9|15041163540773201510|2|8228"], + "uses": ["7:6-7:9|15041163540773201510|2|16420"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 9be1e81a0..40952f828 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -39,7 +39,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|0|1|8228", "6:3-6:9|0|1|8228"], + "uses": ["5:3-5:9|0|1|16420", "6:3-6:9|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index c8a5e6c37..129c33f58 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -56,7 +56,7 @@ unique_ptr* return_type() { "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "1:1-2:20|0|1|2", + "spell": "2:7-2:17|0|1|2", "extent": "1:1-2:20|0|1|0", "alias_of": 0, "bases": [], @@ -90,7 +90,7 @@ unique_ptr* return_type() { "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "1:1-2:20|0|1|2", + "spell": "2:7-2:17|0|1|2", "extent": "1:1-2:20|0|1|0", "alias_of": 0, "bases": [], diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 1af6dbdfa..1173d954b 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -122,8 +122,8 @@ unique_ptr* Foo::foo() { return nullptr; } "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["65:23-65:26|15041163540773201510|2|513"], - "spell": "79:26-79:29|15041163540773201510|2|514", + "declarations": ["65:23-65:26|15041163540773201510|2|1025"], + "spell": "79:26-79:29|15041163540773201510|2|1026", "extent": "79:1-79:51|0|1|0", "declaring_type": 0, "bases": [], @@ -163,6 +163,21 @@ unique_ptr* Foo::foo() { return nullptr; } "vars": [], "instances": [], "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|0|1|4", "65:14-65:16|0|1|4", "79:12-79:14|0|1|4"] + }, { + "usr": 7147635971744144194, + "detailed_name": "template<> class unique_ptr", + "qual_name_offset": 17, + "short_name": "unique_ptr", + "kind": 5, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["15:19-15:29|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", @@ -192,7 +207,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:8-15:18|0|1|4", "15:19-15:29|0|1|4", "33:1-33:11|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:3-54:13|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] + "uses": [] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", @@ -215,9 +230,9 @@ unique_ptr* Foo::foo() { return nullptr; } "detailed_name": "unique_ptr", "qual_name_offset": 0, "short_name": "unique_ptr", - "kind": 26, + "kind": 5, "declarations": [], - "spell": "1:1-2:17|0|1|2", + "spell": "2:7-2:17|0|1|2", "extent": "1:1-2:17|0|1|0", "alias_of": 0, "bases": [], @@ -226,7 +241,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [2933643612409209903, 500112618220246], - "uses": [] + "uses": ["15:8-15:18|0|1|4", "33:1-33:11|0|1|4", "54:3-54:13|0|1|4"] }], "usr2var": [{ "usr": 500112618220246, diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 84ebefe24..1b904ef73 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -35,7 +35,7 @@ static unique_ptr foo; "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "1:1-2:20|0|1|2", + "spell": "2:7-2:17|0|1|2", "extent": "1:1-2:20|0|1|0", "alias_of": 0, "bases": [], diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 1d8fcb26e..bd1323e95 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -74,7 +74,7 @@ struct Foo { "qual_name_offset": 0, "short_name": "a", "declarations": [], - "spell": "5:16-5:17|15041163540773201510|2|514", + "spell": "5:16-5:17|15041163540773201510|2|1026", "extent": "5:3-5:17|15041163540773201510|2|0", "type": 13749354388332789217, "uses": [], @@ -86,7 +86,7 @@ struct Foo { "qual_name_offset": 16, "short_name": "b", "declarations": [], - "spell": "6:19-6:20|15041163540773201510|2|514", + "spell": "6:19-6:20|15041163540773201510|2|1026", "extent": "6:3-6:20|15041163540773201510|2|0", "type": 8508299082070213750, "uses": [], diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 583c1c08d..25c07db28 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -64,7 +64,7 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 16, "short_name": "a", "declarations": [], - "spell": "4:42-4:43|1699390678058422036|3|514", + "spell": "4:42-4:43|1699390678058422036|3|1026", "extent": "4:26-4:43|1699390678058422036|3|0", "type": 8508299082070213750, "uses": [], @@ -76,7 +76,7 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 13, "short_name": "f", "declarations": [], - "spell": "4:23-4:24|1699390678058422036|3|514", + "spell": "4:23-4:24|1699390678058422036|3|1026", "extent": "4:10-4:24|1699390678058422036|3|0", "type": 13749354388332789217, "uses": [], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 0d84a6449..1605291d0 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -52,7 +52,7 @@ void foo(Foo* f, Foo*) {} "qual_name_offset": 5, "short_name": "f", "declarations": [], - "spell": "4:15-4:16|8908726657907936744|3|514", + "spell": "4:15-4:16|8908726657907936744|3|1026", "extent": "4:10-4:16|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index ec88c76f2..17ac5ceaf 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -76,7 +76,7 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 6, "short_name": "a0", "declarations": [], - "spell": "3:16-3:18|16858540520096802573|3|514", + "spell": "3:16-3:18|16858540520096802573|3|1026", "extent": "3:10-3:18|16858540520096802573|3|0", "type": 13487927231218873822, "uses": [], @@ -113,7 +113,7 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 12, "short_name": "a1", "declarations": [], - "spell": "3:32-3:34|16858540520096802573|3|514", + "spell": "3:32-3:34|16858540520096802573|3|1026", "extent": "3:20-3:34|16858540520096802573|3|0", "type": 13487927231218873822, "uses": [], diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 353777794..c1b59773e 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -29,8 +29,8 @@ static Type* bar() { return nullptr; } "short_name": "Empty", "kind": 6, "storage": 0, - "declarations": ["9:8-9:13|15041163540773201510|2|513"], - "spell": "13:11-13:16|15041163540773201510|2|514", + "declarations": ["9:8-9:13|15041163540773201510|2|1025"], + "spell": "13:11-13:16|15041163540773201510|2|1026", "extent": "13:1-13:21|0|1|0", "declaring_type": 0, "bases": [], @@ -75,8 +75,8 @@ static Type* bar() { return nullptr; } "short_name": "Get", "kind": 6, "storage": 0, - "declarations": ["8:9-8:12|15041163540773201510|2|513"], - "spell": "12:12-12:15|15041163540773201510|2|514", + "declarations": ["8:9-8:12|15041163540773201510|2|1025"], + "spell": "12:12-12:15|15041163540773201510|2|1026", "extent": "12:1-12:40|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index 457ed5874..5e958e455 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -19,7 +19,7 @@ typedef Foo Foo2; "declarations": [], "spell": "4:7-4:11|0|1|2", "extent": "4:1-4:22|0|1|0", - "alias_of": 0, + "alias_of": 5123806965838456033, "bases": [], "derived": [], "types": [], @@ -27,6 +27,21 @@ typedef Foo Foo2; "vars": [], "instances": [], "uses": ["5:13-5:17|0|1|4"] + }, { + "usr": 5123806965838456033, + "detailed_name": "template<> struct Foo", + "qual_name_offset": 18, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["4:14-4:17|0|1|4"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo", @@ -41,7 +56,22 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["4:14-4:17|0|1|4", "5:9-5:12|0|1|4"] + "uses": [] + }, { + "usr": 14491685842684954828, + "detailed_name": "template<> struct Foo>", + "qual_name_offset": 18, + "short_name": "Foo", + "kind": 5, + "declarations": [], + "alias_of": 0, + "bases": [], + "derived": [], + "types": [], + "funcs": [], + "vars": [], + "instances": [], + "uses": ["5:9-5:12|0|1|4"] }, { "usr": 15933698173231330933, "detailed_name": "typedef Foo Foo2", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index c03e37ca1..c9934391d 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -21,8 +21,8 @@ extern Foo foo; "short_name": "make", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|513"], - "spell": "5:11-5:15|15041163540773201510|2|514", + "declarations": ["2:8-2:12|15041163540773201510|2|1025"], + "spell": "5:11-5:15|15041163540773201510|2|1026", "extent": "5:1-8:2|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 4417645ba..bf28a40e1 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -47,7 +47,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:14-14:17|0|1|8228"], + "uses": ["14:14-14:17|0|1|16420"], "callees": [] }, { "usr": 18319417758892371313, @@ -61,7 +61,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|0|1|8228"], + "uses": ["14:3-14:9|0|1|16420"], "callees": [] }], "usr2type": [{ @@ -119,7 +119,7 @@ void foo() { "qual_name_offset": 4, "short_name": "field_var", "declarations": [], - "spell": "7:7-7:16|15041163540773201510|2|514", + "spell": "7:7-7:16|15041163540773201510|2|1026", "extent": "7:3-7:16|15041163540773201510|2|0", "type": 53, "uses": ["14:28-14:37|15041163540773201510|2|12"], @@ -130,8 +130,8 @@ void foo() { "detailed_name": "static int Foo::static_var", "qual_name_offset": 11, "short_name": "static_var", - "declarations": ["6:14-6:24|15041163540773201510|2|513"], - "spell": "10:10-10:20|15041163540773201510|2|514", + "declarations": ["6:14-6:24|15041163540773201510|2|1025"], + "spell": "10:10-10:20|15041163540773201510|2|1026", "extent": "10:1-10:24|0|1|0", "type": 53, "uses": ["14:45-14:55|0|1|12"], diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 0e84edd68..dfde1cb31 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -41,7 +41,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:10-6:13|0|1|8228", "6:18-6:21|0|1|8228"], + "uses": ["6:10-6:13|0|1|16420", "6:18-6:21|0|1|16420"], "callees": [] }, { "usr": 18319417758892371313, @@ -55,7 +55,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:9|0|1|8228"], + "uses": ["6:3-6:9|0|1|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index d9cbb63f7..f549869a7 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -26,7 +26,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["4:13-4:19|0|1|132", "7:3-7:9|0|1|8228"], + "uses": ["4:13-4:19|0|1|132", "7:3-7:9|0|1|16420"], "callees": [] }, { "usr": 11404881820527069090, @@ -56,7 +56,7 @@ void caller() { "spell": "4:8-4:9|11404881820527069090|3|2", "extent": "4:3-4:19|11404881820527069090|3|0", "type": 0, - "uses": ["5:3-5:4|11404881820527069090|3|8236"], + "uses": ["5:3-5:4|11404881820527069090|3|16428"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 81a61d37b..fd6229a93 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -50,7 +50,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["16:3-16:9|0|1|8228"], + "uses": ["16:3-16:9|0|1|16420"], "callees": [] }, { "usr": 17175780305784503374, @@ -64,7 +64,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|0|1|8228", "15:3-15:9|0|1|8228", "17:3-17:9|0|1|8228"], + "uses": ["14:3-14:9|0|1|16420", "15:3-15:9|0|1|16420", "17:3-17:9|0|1|16420"], "callees": [] }], "usr2type": [{ @@ -112,7 +112,7 @@ void foo() { "qual_name_offset": 4, "short_name": "y", "declarations": [], - "spell": "4:7-4:8|15041163540773201510|2|514", + "spell": "4:7-4:8|15041163540773201510|2|1026", "extent": "4:3-4:8|15041163540773201510|2|0", "type": 53, "uses": ["17:12-17:13|15041163540773201510|2|12"], @@ -124,7 +124,7 @@ void foo() { "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "3:7-3:8|15041163540773201510|2|514", + "spell": "3:7-3:8|15041163540773201510|2|1026", "extent": "3:3-3:8|15041163540773201510|2|0", "type": 53, "uses": ["12:5-12:6|15041163540773201510|2|20", "13:5-13:6|15041163540773201510|2|4", "14:12-14:13|15041163540773201510|2|12", "15:12-15:13|15041163540773201510|2|12", "16:13-16:14|15041163540773201510|2|132"], diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 3f939310a..869fe29d3 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -41,7 +41,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|0|1|8228"], + "uses": ["8:3-8:9|0|1|16420"], "callees": [] }], "usr2type": [{ @@ -82,7 +82,7 @@ void foo() { "detailed_name": "static int Foo::x", "qual_name_offset": 11, "short_name": "x", - "declarations": ["2:14-2:15|15041163540773201510|2|513"], + "declarations": ["2:14-2:15|15041163540773201510|2|1025"], "type": 53, "uses": ["8:15-8:16|15041163540773201510|2|12"], "kind": 13, diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index a4d7e720c..1f2bcb068 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -54,8 +54,8 @@ const VarType Holder::static_var; "qual_name_offset": 25, "short_name": "static_var", "hover": "static constexpr VarType Holder::static_var = (VarType)0x0", - "declarations": ["4:28-4:38|10028537921178202800|2|513"], - "spell": "7:23-7:33|10028537921178202800|2|514", + "declarations": ["4:28-4:38|10028537921178202800|2|1025"], + "spell": "7:23-7:33|10028537921178202800|2|1026", "extent": "7:1-7:33|0|1|0", "type": 5792006888140599735, "uses": [], diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 8938f552b..278bdc7eb 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -45,7 +45,7 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|514", + "spell": "1:14-1:15|11998306017310352355|3|1026", "extent": "1:10-1:15|11998306017310352355|3|0", "type": 53, "uses": ["2:3-2:4|11998306017310352355|3|4"], diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 9d926c285..6a6084d6d 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -63,7 +63,7 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|514", + "spell": "1:14-1:15|11998306017310352355|3|1026", "extent": "1:10-1:15|11998306017310352355|3|0", "type": 53, "uses": ["2:3-2:4|11998306017310352355|3|20", "7:3-7:4|11998306017310352355|3|20"], diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index b20a65bd9..7eb364a58 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -34,7 +34,7 @@ class Foo { "qual_name_offset": 5, "short_name": "member", "declarations": [], - "spell": "2:8-2:14|15041163540773201510|2|514", + "spell": "2:8-2:14|15041163540773201510|2|1026", "extent": "2:3-2:14|15041163540773201510|2|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 84f65ba52..b4c4784d0 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -32,8 +32,8 @@ Foo* Foo::member = nullptr; "detailed_name": "static Foo *Foo::member", "qual_name_offset": 12, "short_name": "member", - "declarations": ["2:15-2:21|15041163540773201510|2|513"], - "spell": "4:11-4:17|15041163540773201510|2|514", + "declarations": ["2:15-2:21|15041163540773201510|2|1025"], + "spell": "4:11-4:17|15041163540773201510|2|1026", "extent": "4:1-4:27|0|1|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index 9689afe16..b0f84d67d 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -45,7 +45,7 @@ class Foo { "detailed_name": "static int Foo::member", "qual_name_offset": 11, "short_name": "member", - "declarations": ["2:14-2:20|15041163540773201510|2|513"], + "declarations": ["2:14-2:20|15041163540773201510|2|1025"], "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 06617a224..1b7da61d2 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -46,7 +46,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p1", "declarations": [], - "spell": "3:24-3:26|8908726657907936744|3|514", + "spell": "3:24-3:26|8908726657907936744|3|1026", "extent": "3:19-3:26|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], @@ -58,7 +58,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p0", "declarations": [], - "spell": "3:15-3:17|8908726657907936744|3|514", + "spell": "3:15-3:17|8908726657907936744|3|1026", "extent": "3:10-3:17|8908726657907936744|3|0", "type": 15041163540773201510, "uses": [], diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index a28583f39..9467753a3 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -45,7 +45,7 @@ void foo(int p) { "qual_name_offset": 4, "short_name": "p", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|514", + "spell": "1:14-1:15|11998306017310352355|3|1026", "extent": "1:10-1:15|11998306017310352355|3|0", "type": 53, "uses": [], diff --git a/src/indexer.cc b/src/indexer.cc index 8b006a0c3..a22508856 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -19,12 +19,10 @@ using ccls::Intern; using namespace clang; using llvm::Timer; -#include #include #include #include #include -#include #include namespace { @@ -54,12 +52,10 @@ struct IndexParam { // If this is the first time we have seen the file (ignoring if we are // generating an index for it): - auto it = SeenUniqueID.try_emplace(File.getUniqueID()); - if (it.second) { + auto [it, inserted] = SeenUniqueID.try_emplace(File.getUniqueID()); + if (inserted) { std::string file_name = FileName(File); - // Add to all files we have seen so we can generate proper dependency - // graph. - it.first->second = file_name; + it->second = file_name; // Set modification time. std::optional write_time = LastWriteTime(file_name); @@ -397,11 +393,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { Usr GetUsr(const Decl *D, IndexParam::DeclInfo **info = nullptr) const { D = D->getCanonicalDecl(); - auto R = param.Decl2Info.try_emplace(D); - if (R.second) { + auto [it, inserted] = param.Decl2Info.try_emplace(D); + if (inserted) { SmallString<256> USR; index::generateUSRForDecl(D, USR); - auto &info = R.first->second; + auto &info = it->second; info.usr = HashUsr(USR); if (auto *ND = dyn_cast(D)) { info.short_name = ND->getNameAsString(); @@ -410,8 +406,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } if (info) - *info = &R.first->second; - return R.first->second.usr; + *info = &it->second; + return it->second.usr; } Use GetUse(IndexFile *db, Range range, const DeclContext *DC, @@ -713,9 +709,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceRange R1 = D1->getSourceRange(); if (SM.getFileID(R1.getBegin()) == LocFID) { IndexType& type1 = db->ToType(usr1); - Range loc1 = FromTokenRange(SM, Lang, R1); - type1.def.spell = GetUse(db, loc1, SemDC, Role::Definition); - type1.def.extent = GetUse(db, loc1, LexDC, Role::None); + SourceLocation L1 = D1->getLocation(); + type1.def.spell = GetUse(db, FromTokenRange(SM, Lang, {L1, L1}), + SemDC, Role::Definition); + type1.def.extent = + GetUse(db, FromTokenRange(SM, Lang, R1), LexDC, Role::None); type1.def.detailed_name = Intern(info1->short_name); type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.kind = lsSymbolKind::TypeParameter; @@ -1046,24 +1044,24 @@ IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, : UniqueID(UniqueID), path(path), file_contents(contents) {} IndexFunc& IndexFile::ToFunc(Usr usr) { - auto ret = usr2func.try_emplace(usr); - if (ret.second) - ret.first->second.usr = usr; - return ret.first->second; + auto [it, inserted] = usr2func.try_emplace(usr); + if (inserted) + it->second.usr = usr; + return it->second; } IndexType& IndexFile::ToType(Usr usr) { - auto ret = usr2type.try_emplace(usr); - if (ret.second) - ret.first->second.usr = usr; - return ret.first->second; + auto [it, inserted] = usr2type.try_emplace(usr); + if (inserted) + it->second.usr = usr; + return it->second; } IndexVar& IndexFile::ToVar(Usr usr) { - auto ret = usr2var.try_emplace(usr); - if (ret.second) - ret.first->second.usr = usr; - return ret.first->second; + auto [it, inserted] = usr2var.try_emplace(usr); + if (inserted) + it->second.usr = usr; + return it->second; } std::string IndexFile::ToString() { @@ -1151,10 +1149,12 @@ std::vector> Index( auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; - memset(&IndexOpts, 1, sizeof IndexOpts); IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; +#if LLVM_VERSION_MAJOR >= 7 + IndexOpts.IndexImplicitInstantiation = true; +#endif std::unique_ptr IndexAction = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); diff --git a/src/message_handler.cc b/src/message_handler.cc index 60e74b593..711f1d2f6 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -345,16 +345,19 @@ void EmitSemanticHighlighting(DB *db, std::sort(scratch.begin(), scratch.end(), [](auto &l, auto &r) { return l.first.start < r.first.start; }); const auto &buf = wfile->buffer_content; - int l = 0, c = 0, i = 0; + int l = 0, c = 0, i = 0, p = 0; auto mov = [&](int line, int col) { if (l < line) c = 0; - for (; l < line && i < buf.size(); i++) + for (; l < line && i < buf.size(); i++) { if (buf[i] == '\n') l++; + if (uint8_t(buf[i]) < 128 || 192 <= uint8_t(buf[i])) + p++; + } if (l < line) return true; - for (; c < col && i < buf.size(); c++) - if (uint8_t(buf[i++]) >= 128) + for (; c < col && i < buf.size() && buf[i] != '\n'; c++) + if (p++, uint8_t(buf[i++]) >= 128) // Skip 0b10xxxxxx while (i < buf.size() && uint8_t(buf[i]) >= 128 && uint8_t(buf[i]) < 192) i++; @@ -364,10 +367,10 @@ void EmitSemanticHighlighting(DB *db, lsRange &r = entry.first; if (mov(r.start.line, r.start.character)) continue; - int beg = i; + int beg = p; if (mov(r.end.line, r.end.character)) continue; - entry.second->ranges.emplace_back(beg, i); + entry.second->ranges.emplace_back(beg, p); } } diff --git a/src/query.h b/src/query.h index b164b9caf..defce4857 100644 --- a/src/query.h +++ b/src/query.h @@ -113,15 +113,6 @@ struct IndexUpdate { UseUpdate vars_uses; }; -template -struct EntityToIndex { - using argument_type = const Q&; - llvm::DenseMap m; - unsigned operator()(const Q& entity) const { - return m[entity.usr]; - } -}; - struct WrappedUsr { Usr usr; }; From 3737d4c60f4292fba53d3e5c5ca0be7bc521ff3e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 12 Jul 2018 19:13:01 -0700 Subject: [PATCH 139/378] Support uses from other files and improve references in macro replacement-list --- index_tests/macros/complex.cc | 12 +- index_tests/macros/foo.cc | 10 +- index_tests/multi_file/funky_enum.cc | 6 +- .../usage/func_called_from_macro_argument.cc | 4 +- src/indexer.cc | 149 +++++++++----- src/indexer.h | 12 ++ src/query.cc | 194 +++++++++++------- src/query.h | 20 +- src/query_utils.cc | 12 +- src/serializer.cc | 1 + 10 files changed, 268 insertions(+), 152 deletions(-) diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 70d813855..0fed44b41 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -23,14 +23,14 @@ FOO(make1(), make2); "short_name": "a", "kind": 12, "storage": 0, - "declarations": ["12:1-12:4|0|1|1"], - "spell": "12:1-12:4|0|1|2", + "declarations": ["12:1-12:20|0|1|1"], + "spell": "12:1-12:20|0|1|2", "extent": "1:1-1:1|0|1|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["2:7-2:8|0|1|64", "3:7-3:8|0|1|64"], + "uses": ["2:7-2:8|0|1|64|0", "3:7-3:8|0|1|64|0"], "callees": [] }, { "usr": 14400399977994209582, @@ -46,7 +46,7 @@ FOO(make1(), make2); "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|0|1|16420"], + "uses": ["12:1-12:20|0|1|16420", "12:5-12:10|0|1|64|0"], "callees": [] }], "usr2type": [{ @@ -75,7 +75,7 @@ FOO(make1(), make2); "spell": "9:11-9:16|0|1|2", "extent": "9:1-9:20|0|1|0", "type": 53, - "uses": ["12:14-12:19|0|1|12"], + "uses": ["12:1-12:20|0|1|12", "12:14-12:19|0|1|64|0"], "kind": 13, "storage": 0 }, { @@ -88,7 +88,7 @@ FOO(make1(), make2); "spell": "1:9-1:12|0|1|2", "extent": "1:9-3:32|0|1|0", "type": 0, - "uses": ["12:1-12:20|0|1|4"], + "uses": ["12:1-12:4|0|1|64"], "kind": 255, "storage": 0 }] diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index e1c339203..ddc7a7049 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -20,13 +20,13 @@ int x = A; "kind": 9, "storage": 0, "declarations": [], - "spell": "5:12-5:15|15041163540773201510|2|1026", + "spell": "5:3-5:16|15041163540773201510|2|1026", "extent": "1:1-1:1|15041163540773201510|2|0", "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": [], + "uses": ["5:12-5:15|0|1|64|0"], "callees": [] }], "usr2type": [{ @@ -60,7 +60,7 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:12-5:15|0|1|4"] + "uses": ["5:3-5:16|0|1|4", "5:12-5:15|0|1|64|0"] }], "usr2var": [{ "usr": 1569772797058982873, @@ -72,7 +72,7 @@ int x = A; "spell": "1:9-1:10|0|1|2", "extent": "1:9-1:12|0|1|0", "type": 0, - "uses": ["8:9-8:10|0|1|4"], + "uses": ["8:9-8:10|0|1|64"], "kind": 255, "storage": 0 }, { @@ -85,7 +85,7 @@ int x = A; "spell": "2:9-2:17|0|1|2", "extent": "2:9-2:46|0|1|0", "type": 0, - "uses": ["5:3-5:16|0|1|4"], + "uses": ["5:3-5:11|0|1|64"], "kind": 255, "storage": 0 }, { diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index d3504989f..c76b4d471 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -33,7 +33,7 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "A", "hover": "A = 0", - "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], "spell": "4:1-4:2|16985894625255407295|2|1026", "extent": "4:1-4:2|16985894625255407295|2|0", @@ -47,7 +47,7 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "C", "hover": "C = 2", - "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], "spell": "6:1-6:2|16985894625255407295|2|1026", "extent": "6:1-6:2|16985894625255407295|2|0", @@ -61,7 +61,7 @@ OUTPUT: funky_enum.h "qual_name_offset": 0, "short_name": "B", "hover": "B = 1", - "comments": "This file cannot be built directory. It is included in an enum definition of\r\nanother file.", + "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], "spell": "5:1-5:2|16985894625255407295|2|1026", "extent": "5:1-5:2|16985894625255407295|2|0", diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index ce4e865ce..42e26b30d 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -23,7 +23,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|0|1|16420"], + "uses": ["6:3-6:33|0|1|16420", "6:14-6:20|0|1|64|0"], "callees": [] }, { "usr": 11404881820527069090, @@ -53,7 +53,7 @@ void caller() { "spell": "1:9-1:19|0|1|2", "extent": "1:9-1:24|0|1|0", "type": 0, - "uses": ["6:3-6:33|0|1|4"], + "uses": ["6:3-6:13|0|1|64"], "kind": 255, "storage": 0 }] diff --git a/src/indexer.cc b/src/indexer.cc index a22508856..bd2fe3a19 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -15,6 +15,7 @@ using ccls::Intern; #include #include #include +#include #include using namespace clang; using llvm::Timer; @@ -47,8 +48,7 @@ struct IndexParam { : Unit(Unit), file_consumer(file_consumer) {} IndexFile *ConsumeFile(const FileEntry &File) { - IndexFile *db = - file_consumer->TryConsumeFile(File, &file_contents); + IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents); // If this is the first time we have seen the file (ignoring if we are // generating an index for it): @@ -533,15 +533,25 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } - void AddMacroUse(SourceManager &SM, Usr usr, SymbolKind kind, + void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, SourceLocation Spell) const { const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); if (!FE) return; - IndexFile *db = param.ConsumeFile(*FE); - if (!db) return; + auto UID = FE->getUniqueID(); + auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID); + if (inserted) { + it->second.first = db->uid2lid_and_path.size() - 1; + SmallString<256> Path = FE->tryGetRealPathName(); + if (Path.empty()) + Path = FE->getName(); + if (!llvm::sys::path::is_absolute(Path) && + !SM.getFileManager().makeAbsolutePath(Path)) + return; + it->second.second = Path.str(); + } Range spell = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); - Use use = GetUse(db, spell, nullptr, Role::Dynamic); + Use use{{spell, 0, SymbolKind::File, Role::Dynamic}, it->second.first}; switch (kind) { case SymbolKind::Func: db->ToFunc(usr).uses.push_back(use); @@ -585,26 +595,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { FileID LocFID; #endif SourceLocation Spell = SM.getSpellingLoc(Loc); - Loc = SM.getFileLoc(Loc); - Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc)); - LocFID = SM.getFileID(Loc); - const FileEntry *FE = SM.getFileEntryForID(LocFID); - if (!FE) { - // TODO + const FileEntry *FE; + Range loc; #if LLVM_VERSION_MAJOR < 7 - auto P = SM.getExpansionRange(Loc); - loc = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); - LocFID = SM.getFileID(P.first); - FE = SM.getFileEntryForID(LocFID); + auto P = SM.getExpansionRange(Loc); + loc = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); + LocFID = SM.getFileID(P.first); + FE = SM.getFileEntryForID(LocFID); #else - auto R = SM.getExpansionRange(Loc); - loc = FromTokenRange(SM, Lang, R.getAsRange()); - LocFID = SM.getFileID(R.getBegin()); - FE = SM.getFileEntryForID(LocFID); + auto R = SM.getExpansionRange(Loc); + loc = FromTokenRange(SM, Lang, R.getAsRange()); + LocFID = SM.getFileID(R.getBegin()); + FE = SM.getFileEntryForID(LocFID); #endif - if (!FE) - return true; - } + if (!FE) + return true; IndexFile *db = param.ConsumeFile(*FE); if (!db) return true; @@ -650,7 +655,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { func = &db->ToFunc(usr); do_def_decl(func); if (Spell != Loc) - AddMacroUse(SM, usr, SymbolKind::Func, Spell); + AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); if (func->def.detailed_name[0] == '\0') SetName(OrigD, info->short_name, info->qualified, func->def); if (is_def || is_decl) { @@ -663,7 +668,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { type = &db->ToType(usr); do_def_decl(type); if (Spell != Loc) - AddMacroUse(SM, usr, SymbolKind::Type, Spell); + AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); if (type->def.detailed_name[0] == '\0') SetName(OrigD, info->short_name, info->qualified, type->def); if (is_def || is_decl) { @@ -676,7 +681,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { var = &db->ToVar(usr); do_def_decl(var); if (Spell != Loc) - AddMacroUse(SM, usr, SymbolKind::Var, Spell); + AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); if (var->def.detailed_name[0] == '\0') SetVarName(OrigD, info->short_name, info->qualified, var->def); QualType T; @@ -997,14 +1002,16 @@ class IndexPPCallbacks : public PPCallbacks { void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R, const MacroArgs *Args) override { llvm::sys::fs::UniqueID UniqueID; - auto range = FromTokenRange(SM, param.Ctx->getLangOpts(), R, &UniqueID); - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + SourceLocation L = SM.getSpellingLoc(R.getBegin()); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { auto[Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); - var.uses.push_back({{range, 0, SymbolKind::File, Role::Reference}}); + var.uses.push_back( + {{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), 0, + SymbolKind::File, Role::Dynamic}}); } } void MacroUndefined(const Token &Tok, const MacroDefinition &MD, @@ -1036,8 +1043,8 @@ class IndexFrontendAction : public ASTFrontendAction { }; } -const int IndexFile::kMajorVersion = 16; -const int IndexFile::kMinorVersion = 1; +const int IndexFile::kMajorVersion = 17; +const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) @@ -1198,6 +1205,9 @@ std::vector> Index( for (std::unique_ptr& entry : result) { entry->import_file = file; entry->args = args; + for (auto &[_, it] : entry->uid2lid_and_path) + entry->lid2path.emplace_back(it.first, std::move(it.second)); + entry->uid2lid_and_path.clear(); for (auto& it : entry->usr2func) { // e.g. declaration + out-of-line definition Uniquify(it.second.derived); @@ -1233,7 +1243,7 @@ std::vector> Index( // Update dependencies for the file. Do not include the file in its own // dependency set. - for (auto & [ _, path ] : param.SeenUniqueID) + for (auto &[_, path] : param.SeenUniqueID) if (path != entry->path && path != entry->import_file) entry->dependencies[path] = param.file2write_time[path]; } @@ -1245,34 +1255,67 @@ std::vector> Index( // |SymbolRef| is serialized this way. // |Use| also uses this though it has an extra field |file|, // which is not used by Index* so it does not need to be serialized. -void Reflect(Reader& visitor, Reference& value) { - if (visitor.Format() == SerializeFormat::Json) { - std::string t = visitor.GetString(); - char* s = const_cast(t.c_str()); - value.range = Range::FromString(s); +void Reflect(Reader &vis, Reference &v) { + if (vis.Format() == SerializeFormat::Json) { + std::string t = vis.GetString(); + char *s = const_cast(t.c_str()); + v.range = Range::FromString(s); s = strchr(s, '|'); - value.usr = strtoull(s + 1, &s, 10); - value.kind = static_cast(strtol(s + 1, &s, 10)); - value.role = static_cast(strtol(s + 1, &s, 10)); + v.usr = strtoull(s + 1, &s, 10); + v.kind = static_cast(strtol(s + 1, &s, 10)); + v.role = static_cast(strtol(s + 1, &s, 10)); } else { - Reflect(visitor, value.range); - Reflect(visitor, value.usr); - Reflect(visitor, value.kind); - Reflect(visitor, value.role); + Reflect(vis, v.range); + Reflect(vis, v.usr); + Reflect(vis, v.kind); + Reflect(vis, v.role); } } -void Reflect(Writer& visitor, Reference& value) { - if (visitor.Format() == SerializeFormat::Json) { +void Reflect(Writer &vis, Reference &v) { + if (vis.Format() == SerializeFormat::Json) { char buf[99]; snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", - value.range.ToString().c_str(), value.usr, int(value.kind), - int(value.role)); + v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role)); + std::string s(buf); + Reflect(vis, s); + } else { + Reflect(vis, v.range); + Reflect(vis, v.usr); + Reflect(vis, v.kind); + Reflect(vis, v.role); + } +} + +void Reflect(Reader& vis, Use& v) { + if (vis.Format() == SerializeFormat::Json) { + std::string t = vis.GetString(); + char* s = const_cast(t.c_str()); + v.range = Range::FromString(s); + s = strchr(s, '|'); + v.usr = strtoull(s + 1, &s, 10); + v.kind = static_cast(strtol(s + 1, &s, 10)); + v.role = static_cast(strtol(s + 1, &s, 10)); + if (*s == '|') + v.file_id = static_cast(strtol(s + 1, &s, 10)); + } else { + Reflect(vis, static_cast(v)); + Reflect(vis, v.file_id); + } +} +void Reflect(Writer& vis, Use& v) { + if (vis.Format() == SerializeFormat::Json) { + char buf[99]; + if (v.file_id == -1) + snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", + v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role)); + else + snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d|%d", + v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role), + v.file_id); std::string s(buf); - Reflect(visitor, s); + Reflect(vis, s); } else { - Reflect(visitor, value.range); - Reflect(visitor, value.usr); - Reflect(visitor, value.kind); - Reflect(visitor, value.role); + Reflect(vis, static_cast(v)); + Reflect(vis, v.file_id); } } diff --git a/src/indexer.h b/src/indexer.h index 681d2436e..7d2bc1370 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -52,16 +52,23 @@ struct Reference { // |id,kind| refer to the referenced entity. struct SymbolRef : Reference {}; +MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role); // Represents an occurrence of a variable/type, |usr,kind| refer to the lexical // parent. struct Use : Reference { // |file| is used in Query* but not in Index* int file_id = -1; + bool operator==(const Use& o) const { + return range == o.range && usr == o.usr && kind == o.kind && + role == o.role && file_id == o.file_id; + } }; void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); +void Reflect(Reader& visitor, Use& value); +void Reflect(Writer& visitor, Use& value); MAKE_REFLECT_TYPE_PROXY2(clang::StorageClass, uint8_t); @@ -255,6 +262,11 @@ struct IndexFile { int64_t last_write_time = 0; LanguageId language = LanguageId::Unknown; + // uid2lid_and_path is used to generate lid2path, but not serialized. + std::unordered_map> + uid2lid_and_path; + std::vector> lid2path; + // The path to the translation unit cc file which caused the creation of this // IndexFile. When parsing a translation unit we generate many IndexFile // instances (ie, each header has a separate one). When the user edits a diff --git a/src/query.cc b/src/query.cc index d70140655..c41163c48 100644 --- a/src/query.cc +++ b/src/query.cc @@ -17,41 +17,43 @@ MAKE_HASHABLE(Use, t.range, t.file_id); namespace { -void AssignFileId(int file_id, SymbolRef& ref) { +void AssignFileId(const Lid2file_id &, int file_id, SymbolRef &ref) { if (ref.kind == SymbolKind::File) ref.usr = file_id; } -void AssignFileId(int file_id, Use& use) { +void AssignFileId(const Lid2file_id& lid2file_id, int file_id, Use& use) { if (use.kind == SymbolKind::File) use.usr = file_id; - use.file_id = file_id; + if (use.file_id == -1) + use.file_id = file_id; + else + use.file_id = lid2file_id.find(use.file_id)->second; } template -void AssignFileId(int file_id, T&) {} +void AssignFileId(const Lid2file_id &, int file_id, T &) {} template -void AssignFileId(int file_id, Maybe& x) { +void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Maybe &x) { if (x) - AssignFileId(file_id, *x); + AssignFileId(lid2file_id, file_id, *x); } template -void AssignFileId(int file_id, std::vector& xs) { - for (T& x : xs) - AssignFileId(file_id, x); +void AssignFileId(const Lid2file_id &lid2file_id, int file_id, + std::vector &xs) { + for (T &x : xs) + AssignFileId(lid2file_id, file_id, x); } -void AddRange(int file_id, std::vector& into, const std::vector& from) { +void AddRange(std::vector& into, const std::vector& from) { into.reserve(into.size() + from.size()); - for (Use use : from) { - use.file_id = file_id; + for (Use use : from) into.push_back(use); - } } -void AddRange(int _, std::vector& into, const std::vector& from) { +void AddRange(std::vector& into, const std::vector& from) { into.insert(into.end(), from.begin(), from.end()); } @@ -98,7 +100,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { add_outline(decl, type.usr, SymbolKind::Type); } for (Use use : type.uses) - add_all_symbols(use, type.usr, SymbolKind::Type); + if (use.file_id == -1) + add_all_symbols(use, type.usr, SymbolKind::Type); } for (auto& it: indexed.usr2func) { const IndexFunc& func = it.second; @@ -110,18 +113,19 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { add_all_symbols(use, func.usr, SymbolKind::Func); add_outline(use, func.usr, SymbolKind::Func); } - for (Use use : func.uses) { - // Make ranges of implicit function calls larger (spanning one more column - // to the left/right). This is hacky but useful. e.g. - // textDocument/definition on the space/semicolon in `A a;` or `return - // 42;` will take you to the constructor. - if (use.role & Role::Implicit) { - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; + for (Use use : func.uses) + if (use.file_id == -1) { + // Make ranges of implicit function calls larger (spanning one more + // column to the left/right). This is hacky but useful. e.g. + // textDocument/definition on the space/semicolon in `A a;` or `return + // 42;` will take you to the constructor. + if (use.role & Role::Implicit) { + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; + } + add_all_symbols(use, func.usr, SymbolKind::Func); } - add_all_symbols(use, func.usr, SymbolKind::Func); - } } for (auto& it : indexed.usr2var) { const IndexVar& var = it.second; @@ -134,7 +138,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { add_outline(decl, var.usr, SymbolKind::Var); } for (Use use : var.uses) - add_all_symbols(use, var.usr, SymbolKind::Var); + if (use.file_id == -1) + add_all_symbols(use, var.usr, SymbolKind::Var); } std::sort(def.outline.begin(), def.outline.end(), @@ -162,19 +167,16 @@ bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { } // namespace -// ---------------------- -// INDEX THREAD FUNCTIONS -// ---------------------- - -// static IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, IndexFile* current) { IndexUpdate r; static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path, ""); - if (!previous) + if (previous) + r.prev_lid2path = std::move(previous->lid2path); + else previous = ∅ - + r.lid2path = std::move(current->lid2path); r.files_def_update = BuildFileDefUpdate(std::move(*current)); r.funcs_hint = current->usr2func.size() - previous->usr2func.size(); @@ -282,23 +284,59 @@ void DB::RemoveUsrs(SymbolKind kind, } } -void DB::ApplyIndexUpdate(IndexUpdate* u) { -#define REMOVE_ADD(C, F) \ - for (auto& it : u->C##s_##F) { \ - auto R = C##_usr.try_emplace({it.first}, C##_usr.size()); \ - if (R.second) \ - C##s.emplace_back().usr = it.first; \ - auto& entity = C##s[R.first->second]; \ - AssignFileId(u->file_id, it.second.first); \ - RemoveRange(entity.F, it.second.first); \ - AssignFileId(u->file_id, it.second.second); \ - AddRange(u->file_id, entity.F, it.second.second); \ +void DB::ApplyIndexUpdate(IndexUpdate *u) { +#define REMOVE_ADD(C, F) \ + for (auto &it : u->C##s_##F) { \ + auto R = C##_usr.try_emplace({it.first}, C##_usr.size()); \ + if (R.second) \ + C##s.emplace_back().usr = it.first; \ + auto &entity = C##s[R.first->second]; \ + AssignFileId(prev_lid2file_id, u->file_id, it.second.first); \ + RemoveRange(entity.F, it.second.first); \ + AssignFileId(lid2file_id, u->file_id, it.second.second); \ + AddRange(entity.F, it.second.second); \ } + std::unordered_map prev_lid2file_id, lid2file_id; + for (auto & [ lid, path ] : u->prev_lid2path) + prev_lid2file_id[lid] = GetFileId(path); + for (auto & [ lid, path ] : u->lid2path) + lid2file_id[lid] = GetFileId(path); + + auto UpdateUses = [&](Usr usr, SymbolKind kind, + llvm::DenseMap &entity_usr, + auto &entities, auto &p) { + auto R = entity_usr.try_emplace({usr}, entity_usr.size()); + if (R.second) + vars.emplace_back().usr = usr; + auto &entity = entities[R.first->second]; + for (Use &use : p.first) { + if (use.file_id == -1) + use.file_id = u->file_id; + else { + use.file_id = prev_lid2file_id.find(use.file_id)->second; + files[use.file_id] + .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]--; + } + } + RemoveRange(entity.uses, p.first); + for (Use &use : p.second) { + if (use.file_id == -1) + use.file_id = u->file_id; + else { + use.file_id = lid2file_id.find(use.file_id)->second; + files[use.file_id] + .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]++; + } + } + AddRange(entity.uses, p.second); + }; + if (u->files_removed) files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def = std::nullopt; - u->file_id = u->files_def_update ? Update(std::move(*u->files_def_update)) : -1; + u->file_id = + u->files_def_update ? Update(std::move(*u->files_def_update)) : -1; const double grow = 1.3; size_t t; @@ -309,10 +347,11 @@ void DB::ApplyIndexUpdate(IndexUpdate* u) { func_usr.reserve(t); } RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); - Update(u->file_id, std::move(u->funcs_def_update)); + Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); - REMOVE_ADD(func, uses); + for (auto & [ usr, p ] : u->funcs_uses) + UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p); if ((t = types.size() + u->types_hint) > types.capacity()) { t = size_t(t * grow); @@ -320,11 +359,12 @@ void DB::ApplyIndexUpdate(IndexUpdate* u) { type_usr.reserve(t); } RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); - Update(u->file_id, std::move(u->types_def_update)); + Update(lid2file_id, u->file_id, std::move(u->types_def_update)); REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); REMOVE_ADD(type, instances); - REMOVE_ADD(type, uses); + for (auto & [ usr, p ] : u->types_uses) + UpdateUses(usr, SymbolKind::Type, type_usr, types, p); if ((t = vars.size() + u->vars_hint) > vars.capacity()) { t = size_t(t * grow); @@ -332,30 +372,37 @@ void DB::ApplyIndexUpdate(IndexUpdate* u) { var_usr.reserve(t); } RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); - Update(u->file_id, std::move(u->vars_def_update)); + Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); REMOVE_ADD(var, declarations); - REMOVE_ADD(var, uses); + for (auto & [ usr, p ] : u->vars_uses) + UpdateUses(usr, SymbolKind::Var, var_usr, vars, p); #undef REMOVE_ADD } +int DB::GetFileId(const std::string& path) { + auto it = name2file_id.try_emplace(LowerPathIfInsensitive(path)); + if (it.second) { + int id = files.size(); + it.first->second = files.emplace_back().id = id; + } + return it.first->second; +} + int DB::Update(QueryFile::DefUpdate&& u) { - int id = files.size(); - auto it = name2file_id.try_emplace(LowerPathIfInsensitive(u.first.path), id); - if (it.second) - files.emplace_back().id = id; - QueryFile& existing = files[it.first->second]; - existing.def = u.first; - return existing.id; + int file_id = GetFileId(u.first.path); + files[file_id].def = u.first; + return file_id; } -void DB::Update(int file_id, std::vector>&& us) { - for (auto& u : us) { +void DB::Update(const Lid2file_id &lid2file_id, int file_id, + std::vector> &&us) { + for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); - AssignFileId(file_id, def.spell); - AssignFileId(file_id, def.extent); - AssignFileId(file_id, def.callees); + AssignFileId(lid2file_id, file_id, def.spell); + AssignFileId(lid2file_id, file_id, def.extent); + AssignFileId(lid2file_id, file_id, def.callees); auto R = func_usr.try_emplace({u.first}, func_usr.size()); if (R.second) funcs.emplace_back(); @@ -366,12 +413,13 @@ void DB::Update(int file_id, std::vector>&& us) { } } -void DB::Update(int file_id, std::vector>&& us) { - for (auto& u : us) { +void DB::Update(const Lid2file_id &lid2file_id, int file_id, + std::vector> &&us) { + for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); - AssignFileId(file_id, def.spell); - AssignFileId(file_id, def.extent); + AssignFileId(lid2file_id, file_id, def.spell); + AssignFileId(lid2file_id, file_id, def.extent); auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) types.emplace_back(); @@ -379,16 +427,16 @@ void DB::Update(int file_id, std::vector>&& us) { existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); - } } -void DB::Update(int file_id, std::vector>&& us) { - for (auto& u : us) { +void DB::Update(const Lid2file_id &lid2file_id, int file_id, + std::vector> &&us) { + for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); - AssignFileId(file_id, def.spell); - AssignFileId(file_id, def.extent); + AssignFileId(lid2file_id, file_id, def.spell); + AssignFileId(lid2file_id, file_id, def.extent); auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) vars.emplace_back(); diff --git a/src/query.h b/src/query.h index defce4857..795ca13af 100644 --- a/src/query.h +++ b/src/query.h @@ -27,6 +27,7 @@ struct QueryFile { int id = -1; std::optional def; + std::unordered_map symbol2refcnt; }; template @@ -84,6 +85,9 @@ struct IndexUpdate { // Dummy one to refresh all semantic highlight. bool refresh = false; + decltype(IndexFile::lid2path) prev_lid2path; + decltype(IndexFile::lid2path) lid2path; + // File updates. std::optional files_removed; std::optional files_def_update; @@ -124,6 +128,8 @@ struct llvm::DenseMapInfo { static bool isEqual(WrappedUsr l, WrappedUsr r) { return l.usr == r.usr; } }; +using Lid2file_id = std::unordered_map; + // The query database is heavily optimized for fast queries. It is stored // in-memory. struct DB { @@ -134,15 +140,17 @@ struct DB { std::vector types; std::vector vars; - // Marks the given Usrs as invalid. - void RemoveUsrs(SymbolKind usr_kind, const std::vector& to_remove); - void RemoveUsrs(SymbolKind usr_kind, int file_id, const std::vector& to_remove); + void RemoveUsrs(SymbolKind kind, int file_id, const std::vector& to_remove); // Insert the contents of |update| into |db|. void ApplyIndexUpdate(IndexUpdate* update); + int GetFileId(const std::string& path); int Update(QueryFile::DefUpdate&& u); - void Update(int file_id, std::vector>&& us); - void Update(int file_id, std::vector>&& us); - void Update(int file_id, std::vector>&& us); + void Update(const Lid2file_id &, int file_id, + std::vector> &&us); + void Update(const Lid2file_id &, int file_id, + std::vector> &&us); + void Update(const Lid2file_id &, int file_id, + std::vector> &&us); std::string_view GetSymbolName(SymbolIdx sym, bool qualified); bool HasFunc(Usr usr) const { return func_usr.count({usr}); } diff --git a/src/query_utils.cc b/src/query_utils.cc index 0ced17ba3..0a61ffd2a 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -319,10 +319,12 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, } } - for (const SymbolRef& sym : file->def->all_symbols) { + for (SymbolRef sym : file->def->all_symbols) if (sym.range.Contains(ls_pos.line, ls_pos.character)) symbols.push_back(sym); - } + for (auto[sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.range.Contains(ls_pos.line, ls_pos.character)) + symbols.push_back(sym); // Order shorter ranges first, since they are more detailed/precise. This is // important for macros which generate code so that we can resolving the @@ -340,8 +342,10 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); if (t) return t < 0; - t = (a.role & Role::Definition) - (b.role & Role::Definition); - if (t) + // MacroExpansion + if ((t = (a.role & Role::Dynamic) - (b.role & Role::Dynamic))) + return t > 0; + if ((t = (a.role & Role::Definition) - (b.role & Role::Definition))) return t > 0; // operator> orders Var/Func before Type. t = static_cast(a.kind) - static_cast(b.kind); diff --git a/src/serializer.cc b/src/serializer.cc index 423154bd5..8ab39b818 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -330,6 +330,7 @@ void Reflect(TVisitor& visitor, IndexFile& value) { if (!gTestOutputMode) { REFLECT_MEMBER(last_write_time); REFLECT_MEMBER(language); + REFLECT_MEMBER(lid2path); REFLECT_MEMBER(import_file); REFLECT_MEMBER(args); REFLECT_MEMBER(dependencies); From 39d4bbfe67b25abcd8284f1beb2d8318d7b2bca7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 13 Jul 2018 09:36:02 -0700 Subject: [PATCH 140/378] Use clangTooling --- cmake/FindClang.cmake | 1 + src/indexer.cc | 2 +- src/project.cc | 56 +++++++++++++------------------------------ 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 12cbd503c..fe44ece19 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -69,6 +69,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clang) +_Clang_find_add_library(clangTooling) _Clang_find_add_library(clangIndex) _Clang_find_add_library(clangFrontend) _Clang_find_add_library(clangParse) diff --git a/src/indexer.cc b/src/indexer.cc index bd2fe3a19..710499475 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -813,7 +813,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { } [[fallthrough]]; case Decl::Record: { - auto *RD = cast(D); + auto *RD = cast(OrigD); // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; diff --git a/src/project.cc b/src/project.cc index dc729ad08..c74ef410d 100644 --- a/src/project.cc +++ b/src/project.cc @@ -16,6 +16,7 @@ using namespace ccls; #include #include #include +#include #include #include #include @@ -25,7 +26,6 @@ using namespace clang; using namespace llvm; using namespace llvm::opt; -#include #include #if defined(__unix__) || defined(__APPLE__) @@ -142,14 +142,14 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( return result; const driver::ArgStringList& CCArgs = Jobs.begin()->getArguments(); - auto Invocation = std::make_unique(); - CompilerInvocation::CreateFromArgs(*Invocation, CCArgs.data(), + auto CI = std::make_unique(); + CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(), CCArgs.data() + CCArgs.size(), Diags); - Invocation->getFrontendOpts().DisableFree = false; - Invocation->getCodeGenOpts().DisableFree = false; + CI->getFrontendOpts().DisableFree = false; + CI->getCodeGenOpts().DisableFree = false; - HeaderSearchOptions& HeaderOpts = Invocation->getHeaderSearchOpts(); - for (auto& E : HeaderOpts.UserEntries) { + HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts(); + for (auto &E : HeaderOpts.UserEntries) { std::string path = entry.ResolveIfRelative(E.Path); switch (E.Group) { default: @@ -178,7 +178,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); - // if (Invocation->getFileSystemOpts().WorkingDir.empty()) + // if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); // There could be a clang version mismatch between what the project uses and @@ -300,9 +300,9 @@ std::vector LoadCompilationEntriesFromDirectory( #endif } - CXCompilationDatabase_Error cx_db_load_error; - CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( - comp_db_dir.c_str(), &cx_db_load_error); + std::string err_msg; + std::unique_ptr CDB = + tooling::CompilationDatabase::loadFromDirectory(comp_db_dir, err_msg); if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 // TODO @@ -311,44 +311,22 @@ std::vector LoadCompilationEntriesFromDirectory( rmdir(comp_db_dir.c_str()); #endif } - if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { - LOG_S(WARNING) << "unable to load " << Path.c_str(); + if (!CDB) { + LOG_S(WARNING) << "failed to load " << Path.c_str() << " " << err_msg; return {}; } LOG_S(INFO) << "loaded " << Path.c_str(); - CXCompileCommands cx_commands = - clang_CompilationDatabase_getAllCompileCommands(cx_db); - unsigned int num_commands = clang_CompileCommands_getSize(cx_commands); - std::vector result; - for (unsigned int i = 0; i < num_commands; i++) { - CXCompileCommand cx_command = - clang_CompileCommands_getCommand(cx_commands, i); - - std::string directory = - ToString(clang_CompileCommand_getDirectory(cx_command)); - std::string relative_filename = - ToString(clang_CompileCommand_getFilename(cx_command)); - - unsigned num_args = clang_CompileCommand_getNumArgs(cx_command); + for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { CompileCommandsEntry entry; - entry.args.reserve(num_args); - for (unsigned j = 0; j < num_args; ++j) { - entry.args.push_back( - ToString(clang_CompileCommand_getArg(cx_command, j))); - } - - entry.directory = directory; - entry.file = entry.ResolveIfRelative(relative_filename); - + entry.directory = std::move(Cmd.Directory); + entry.file = entry.ResolveIfRelative(Cmd.Filename); + entry.args = std::move(Cmd.CommandLine); result.push_back( GetCompilationEntryFromCompileCommandEntry(project, entry)); } - - clang_CompileCommands_dispose(cx_commands); - clang_CompilationDatabase_dispose(cx_db); return result; } From 0780e80f8a3ffd7cbb2a26a3c3e9a237f25619fc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Jul 2018 09:19:27 -0700 Subject: [PATCH 141/378] Fix FreeBSD build with -DUSE_SHARED_LLVM=off --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fee47d23a..8a901f763 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,8 @@ find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) + find_package(Backtrace REQUIRED) + target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES}) # src/platform_posix.cc uses libthr target_link_libraries(ccls PRIVATE thr) endif() From d604fc38dcb5cd9be8c4087646393ccc9c3b12ad Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Jul 2018 10:00:04 -0700 Subject: [PATCH 142/378] Use Sema/CodeCompleteConsumer --- src/clang_complete.cc | 331 ++++++++++-------------- src/messages/textDocument_completion.cc | 54 ++-- 2 files changed, 158 insertions(+), 227 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f2408ec0c..2d0fb2518 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -5,8 +5,10 @@ #include "log.hh" #include "platform.h" +#include #include #include +using namespace clang; using namespace llvm; #include @@ -30,23 +32,16 @@ std::string StripFileType(const std::string& path) { return Ret.str(); } -unsigned GetCompletionPriority(const CXCompletionString& str, +unsigned GetCompletionPriority(const CodeCompletionString& CCS, CXCursorKind result_kind, const std::optional& typedText) { - unsigned priority = clang_getCompletionPriority(str); - - // XXX: What happens if priority overflows? - if (result_kind == CXCursor_Destructor) { - priority *= 100; - } - if (result_kind == CXCursor_ConversionFunction || + unsigned priority = CCS.getPriority(); + if (CCS.getAvailability() != CXAvailability_Available || + result_kind == CXCursor_Destructor || + result_kind == CXCursor_ConversionFunction || (result_kind == CXCursor_CXXMethod && typedText && - StartsWith(*typedText, "operator"))) { + StartsWith(*typedText, "operator"))) priority *= 100; - } - if (clang_getCompletionAvailability(str) != CXAvailability_Available) { - priority *= 100; - } return priority; } @@ -142,85 +137,76 @@ lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { } } -void BuildCompletionItemTexts(std::vector& out, - CXCompletionString completion_string, +void BuildCompletionItemTexts(std::vector &out, + CodeCompletionString &CCS, bool include_snippets) { assert(!out.empty()); auto out_first = out.size() - 1; std::string result_type; - int num_chunks = clang_getNumCompletionChunks(completion_string); - for (int i = 0; i < num_chunks; ++i) { - CXCompletionChunkKind kind = - clang_getCompletionChunkKind(completion_string, i); - + for (unsigned i = 0, num_chunks = CCS.size(); i < num_chunks; ++i) { + const CodeCompletionString::Chunk &Chunk = CCS[i]; + CodeCompletionString::ChunkKind Kind = Chunk.Kind; std::string text; - switch (kind) { - // clang-format off - 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; - // clang-format on - - 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)); - - for (auto i = out_first; i < out.size(); ++i) { - // first typed text is used for filtering - if (kind == CXCompletionChunk_TypedText && !out[i].filterText) + switch (Kind) { + case CodeCompletionString::CK_TypedText: + case CodeCompletionString::CK_Text: + case CodeCompletionString::CK_Placeholder: + case CodeCompletionString::CK_Informative: + if (Chunk.Text) + text = Chunk.Text; + for (auto i = out_first; i < out.size(); i++) { + // first TypedText is used for filtering + if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) out[i].filterText = text; - - if (kind == CXCompletionChunk_Placeholder) + if (Kind == CodeCompletionString::CK_Placeholder) out[i].parameters_.push_back(text); } break; - - case CXCompletionChunk_CurrentParameter: + case CodeCompletionString::CK_ResultType: + if (Chunk.Text) + result_type = Chunk.Text; + continue; + case CodeCompletionString::CK_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); + case CodeCompletionString::CK_Optional: { // duplicate last element, the recursive call will complete it out.push_back(out.back()); - BuildCompletionItemTexts(out, nested, include_snippets); + BuildCompletionItemTexts(out, *Chunk.Optional, include_snippets); continue; } + // clang-format off + case CodeCompletionString::CK_LeftParen: text = '('; break; + case CodeCompletionString::CK_RightParen: text = ')'; break; + case CodeCompletionString::CK_LeftBracket: text = '['; break; + case CodeCompletionString::CK_RightBracket: text = ']'; break; + case CodeCompletionString::CK_LeftBrace: text = '{'; break; + case CodeCompletionString::CK_RightBrace: text = '}'; break; + case CodeCompletionString::CK_LeftAngle: text = '<'; break; + case CodeCompletionString::CK_RightAngle: text = '>'; break; + case CodeCompletionString::CK_Comma: text = ", "; break; + case CodeCompletionString::CK_Colon: text = ':'; break; + case CodeCompletionString::CK_SemiColon: text = ';'; break; + case CodeCompletionString::CK_Equal: text = '='; break; + case CodeCompletionString::CK_HorizontalSpace: text = ' '; break; + case CodeCompletionString::CK_VerticalSpace: text = ' '; break; + // clang-format on } for (auto i = out_first; i < out.size(); ++i) out[i].label += text; - if (kind == CXCompletionChunk_Informative) + if (Kind == CodeCompletionString::CK_Informative) continue; for (auto i = out_first; i < out.size(); ++i) { if (!include_snippets && !out[i].parameters_.empty()) continue; - if (kind == CXCompletionChunk_Placeholder) { + if (Kind == CodeCompletionString::CK_Placeholder) { out[i].insertText += "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; out[i].insertTextFormat = lsInsertTextFormat::Snippet; @@ -243,106 +229,71 @@ void BuildCompletionItemTexts(std::vector& out, // |do_insert|: if |!do_insert|, do not append strings to |insert| after // a placeholder. -void BuildDetailString(CXCompletionString completion_string, - std::string& label, - std::string& detail, - std::string& insert, - bool& do_insert, - lsInsertTextFormat& format, - std::vector* parameters, - bool include_snippets, - int& angle_stack) { - int num_chunks = clang_getNumCompletionChunks(completion_string); - auto append = [&](const char* text) { - detail += text; - if (do_insert && include_snippets) - insert += text; - }; - for (int i = 0; i < num_chunks; ++i) { - CXCompletionChunkKind kind = - clang_getCompletionChunkKind(completion_string, i); - - switch (kind) { - case CXCompletionChunk_Optional: { - CXCompletionString nested = - clang_getCompletionChunkCompletionString(completion_string, i); - // Do not add text to insert string if we're in angle brackets. - bool should_insert = do_insert && angle_stack == 0; - BuildDetailString(nested, label, detail, insert, - should_insert, format, parameters, - include_snippets, angle_stack); - break; - } - - case CXCompletionChunk_Placeholder: { - std::string text = - ToString(clang_getCompletionChunkText(completion_string, i)); - parameters->push_back(text); - detail += text; - // Add parameter declarations as snippets if enabled - if (include_snippets) { - insert += - "${" + std::to_string(parameters->size()) + ":" + text + "}"; - format = lsInsertTextFormat::Snippet; - } else - do_insert = false; - break; - } - - case CXCompletionChunk_CurrentParameter: - // We have our own parsing logic for active parameter. This doesn't seem - // to be very reliable. - break; - - case CXCompletionChunk_TypedText: { - std::string text = - ToString(clang_getCompletionChunkText(completion_string, i)); - label = text; - detail += text; - if (do_insert) - insert += text; - break; - } - - case CXCompletionChunk_Text: { - std::string text = - ToString(clang_getCompletionChunkText(completion_string, i)); - detail += text; - if (do_insert) - insert += text; - break; - } - - case CXCompletionChunk_Informative: { - detail += ToString(clang_getCompletionChunkText(completion_string, i)); - break; - } - - case CXCompletionChunk_ResultType: { - CXString text = clang_getCompletionChunkText(completion_string, i); - std::string new_detail = ToString(text) + detail + " "; - detail = new_detail; - break; - } - - // clang-format off - case CXCompletionChunk_LeftParen: append("("); break; - case CXCompletionChunk_RightParen: append(")"); break; - case CXCompletionChunk_LeftBracket: append("["); break; - case CXCompletionChunk_RightBracket: append("]"); break; - case CXCompletionChunk_LeftBrace: append("{"); break; - case CXCompletionChunk_RightBrace: append("}"); break; - case CXCompletionChunk_LeftAngle: append("<"); angle_stack++; break; - case CXCompletionChunk_RightAngle: append(">"); angle_stack--; break; - case CXCompletionChunk_Comma: append(", "); break; - case CXCompletionChunk_Colon: append(":"); break; - case CXCompletionChunk_SemiColon: append(";"); break; - case CXCompletionChunk_Equal: append("="); break; - // clang-format on - case CXCompletionChunk_HorizontalSpace: - case CXCompletionChunk_VerticalSpace: - append(" "); - break; +void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, + bool &do_insert, std::vector *parameters, + bool include_snippets, int &angle_stack) { + for (unsigned i = 0, num_chunks = CCS.size(); i < num_chunks; ++i) { + const CodeCompletionString::Chunk &Chunk = CCS[i]; + CodeCompletionString::ChunkKind Kind = Chunk.Kind; + const char* text = nullptr; + switch (Kind) { + case CodeCompletionString::CK_TypedText: + item.label = Chunk.Text; + [[fallthrough]]; + case CodeCompletionString::CK_Text: + item.detail += Chunk.Text; + if (do_insert) + item.insertText += Chunk.Text; + break; + case CodeCompletionString::CK_Placeholder: { + parameters->push_back(Chunk.Text); + item.detail += Chunk.Text; + // Add parameter declarations as snippets if enabled + if (include_snippets) { + item.insertText += "${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}"; + item.insertTextFormat = lsInsertTextFormat::Snippet; + } else + do_insert = false; + break; + } + case CodeCompletionString::CK_Informative: + item.detail += Chunk.Text; + break; + case CodeCompletionString::CK_Optional: { + // Do not add text to insert string if we're in angle brackets. + bool should_insert = do_insert && angle_stack == 0; + BuildDetailString(*Chunk.Optional, item, should_insert, + parameters, include_snippets, angle_stack); + break; + } + case CodeCompletionString::CK_ResultType: + item.detail = Chunk.Text + item.detail + " "; + break; + case CodeCompletionString::CK_CurrentParameter: + // We have our own parsing logic for active parameter. This doesn't seem + // to be very reliable. + break; + // clang-format off + case CodeCompletionString::CK_LeftParen: text = "("; break; + case CodeCompletionString::CK_RightParen: text = ")"; break; + case CodeCompletionString::CK_LeftBracket: text = "["; break; + case CodeCompletionString::CK_RightBracket: text = "]"; break; + case CodeCompletionString::CK_LeftBrace: text = "{"; break; + case CodeCompletionString::CK_RightBrace: text = "}"; break; + case CodeCompletionString::CK_LeftAngle: text = "<"; angle_stack++; break; + case CodeCompletionString::CK_RightAngle: text = ">"; angle_stack--; break; + case CodeCompletionString::CK_Comma: text = ", "; break; + case CodeCompletionString::CK_Colon: text = ":"; break; + case CodeCompletionString::CK_SemiColon: text = ";"; break; + case CodeCompletionString::CK_Equal: text = "="; break; + case CodeCompletionString::CK_HorizontalSpace: + case CodeCompletionString::CK_VerticalSpace: text = " "; break; + // clang-format on + } + if (text) { + item.detail += text; + if (do_insert && include_snippets) + item.insertText += text; } } } @@ -483,35 +434,24 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { for (unsigned i = 0; i < cx_results->NumResults; ++i) { CXCompletionResult& result = cx_results->Results[i]; - - // TODO: Try to figure out how we can hide base method calls without - // also hiding method implementation assistance, ie, - // - // void Foo::* { - // } - // - - if (clang_getCompletionAvailability(result.CompletionString) == - CXAvailability_NotAvailable) + auto CCS = (CodeCompletionString *)result.CompletionString; + if (CCS->getAvailability() == CXAvailability_NotAvailable) continue; - // TODO: fill in more data - lsCompletionItem ls_completion_item; - - ls_completion_item.kind = GetCompletionKind(result.CursorKind); - ls_completion_item.documentation = - ToString(clang_getCompletionBriefComment(result.CompletionString)); + lsCompletionItem ls_item; + ls_item.kind = GetCompletionKind(result.CursorKind); + if (const char* brief = CCS->getBriefComment()) + ls_item.documentation = brief; // label/detail/filterText/insertText/priority if (g_config->completion.detailedLabel) { - ls_completion_item.detail = ToString( - clang_getCompletionParent(result.CompletionString, nullptr)); + ls_item.detail = CCS->getParentContextName().str(); auto first_idx = ls_result.size(); - ls_result.push_back(ls_completion_item); + ls_result.push_back(ls_item); // label/filterText/insertText - BuildCompletionItemTexts(ls_result, result.CompletionString, + BuildCompletionItemTexts(ls_result, *CCS, g_config->client.snippetSupport); for (auto i = first_idx; i < ls_result.size(); ++i) { @@ -520,28 +460,21 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { ls_result[i].insertText += "$0"; } - ls_result[i].priority_ = - GetCompletionPriority(result.CompletionString, result.CursorKind, - ls_result[i].filterText); + ls_result[i].priority_ = GetCompletionPriority( + *CCS, result.CursorKind, ls_result[i].filterText); } } else { bool do_insert = true; int angle_stack = 0; - BuildDetailString(result.CompletionString, ls_completion_item.label, - ls_completion_item.detail, - ls_completion_item.insertText, do_insert, - ls_completion_item.insertTextFormat, - &ls_completion_item.parameters_, + BuildDetailString(*CCS, ls_item, do_insert, + &ls_item.parameters_, g_config->client.snippetSupport, angle_stack); if (g_config->client.snippetSupport && - ls_completion_item.insertTextFormat == - lsInsertTextFormat::Snippet) { - ls_completion_item.insertText += "$0"; - } - ls_completion_item.priority_ = - GetCompletionPriority(result.CompletionString, result.CursorKind, - ls_completion_item.label); - ls_result.push_back(ls_completion_item); + ls_item.insertTextFormat == lsInsertTextFormat::Snippet) + ls_item.insertText += "$0"; + ls_item.priority_ = + GetCompletionPriority(*CCS, result.CursorKind, ls_item.label); + ls_result.push_back(ls_item); } } diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 1479f8030..200935392 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -19,10 +19,11 @@ enum class lsCompletionTriggerKind { // Completion was triggered by typing an identifier (24x7 code // complete), manual invocation (e.g Ctrl+Space) or via API. Invoked = 1, - // Completion was triggered by a trigger character specified by // the `triggerCharacters` properties of the `CompletionRegistrationOptions`. - TriggerCharacter = 2 + TriggerCharacter = 2, + // Completion was re-triggered as the current completion list is incomplete. + TriggerForIncompleteCompletions = 3, }; MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind); @@ -30,7 +31,7 @@ MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind); // request is triggered. struct lsCompletionContext { // How the completion was triggered. - lsCompletionTriggerKind triggerKind; + lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked; // The trigger character (a single character) that has trigger code complete. // Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` @@ -42,7 +43,7 @@ struct lsCompletionParams : lsTextDocumentPositionParams { // The completion context. This is only available it the client specifies to // send this using // `ClientCapabilities.textDocument.completion.contextSupport === true` - std::optional context; + lsCompletionContext context; }; MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); @@ -254,6 +255,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { void Run(std::unique_ptr message) override { auto request = std::shared_ptr( static_cast(message.release())); + auto& params = request->params; auto write_empty_result = [request]() { Out_TextDocumentComplete out; @@ -261,7 +263,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { pipeline::WriteStdout(kMethodType, out); }; - std::string path = request->params.textDocument.uri.GetPath(); + std::string path = params.textDocument.uri.GetPath(); WorkingFile* file = working_files->GetFileByFilename(path); if (!file) { write_empty_result(); @@ -271,21 +273,19 @@ struct Handler_TextDocumentCompletion : MessageHandler { // It shouldn't be possible, but sometimes vscode will send queries out // of order, ie, we get completion request before buffer content update. std::string buffer_line; - if (request->params.position.line >= 0 && - request->params.position.line < file->buffer_lines.size()) { - buffer_line = file->buffer_lines[request->params.position.line]; - } + if (params.position.line >= 0 && + params.position.line < file->buffer_lines.size()) + buffer_line = file->buffer_lines[params.position.line]; // Check for - and : before completing -> or ::, since vscode does not // support multi-character trigger characters. - if (request->params.context && - request->params.context->triggerKind == + if (params.context.triggerKind == lsCompletionTriggerKind::TriggerCharacter && - request->params.context->triggerCharacter) { + params.context.triggerCharacter) { bool did_fail_check = false; - std::string character = *request->params.context->triggerCharacter; - int preceding_index = request->params.position.character - 2; + std::string character = *params.context.triggerCharacter; + int preceding_index = params.position.character - 2; // If the character is '"', '<' or '/', make sure that the line starts // with '#'. @@ -318,11 +318,11 @@ struct Handler_TextDocumentCompletion : MessageHandler { bool is_global_completion = false; std::string existing_completion; - lsPosition end_pos = request->params.position; + lsPosition end_pos = params.position; if (file) { - request->params.position = file->FindStableCompletionSource( - request->params.position, &is_global_completion, - &existing_completion, &end_pos); + params.position = file->FindStableCompletionSource( + request->params.position, &is_global_completion, &existing_completion, + &end_pos); } ParseIncludeLineResult result = ParseIncludeLine(buffer_line); @@ -359,16 +359,16 @@ struct Handler_TextDocumentCompletion : MessageHandler { } for (lsCompletionItem& item : out.result.items) { - item.textEdit->range.start.line = request->params.position.line; + item.textEdit->range.start.line = params.position.line; item.textEdit->range.start.character = 0; - item.textEdit->range.end.line = request->params.position.line; + item.textEdit->range.end.line = params.position.line; item.textEdit->range.end.character = (int)buffer_line.size(); } pipeline::WriteStdout(kMethodType, out); } else { ClangCompleteManager::OnComplete callback = std::bind( - [this, request, is_global_completion, existing_completion, + [this, request, params, is_global_completion, existing_completion, has_open_paren](const std::vector& results, bool is_cached_result) { Out_TextDocumentComplete out; @@ -381,7 +381,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { // Cache completion results. if (!is_cached_result) { - std::string path = request->params.textDocument.uri.GetPath(); + std::string path = params.textDocument.uri.GetPath(); if (is_global_completion) { global_code_complete_cache->WithLock([&]() { global_code_complete_cache->cached_path_ = path; @@ -391,7 +391,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { non_global_code_complete_cache->WithLock([&]() { non_global_code_complete_cache->cached_path_ = path; non_global_code_complete_cache->cached_completion_position_ = - request->params.position; + params.position; non_global_code_complete_cache->cached_results_ = results; }); } @@ -421,16 +421,14 @@ struct Handler_TextDocumentCompletion : MessageHandler { callback(global_code_complete_cache->cached_results_, true /*is_cached_result*/); }); - clang_complete->CodeComplete(request->id, request->params, - freshen_global); - } else if (non_global_code_complete_cache->IsCacheValid( - request->params)) { + clang_complete->CodeComplete(request->id, params, freshen_global); + } else if (non_global_code_complete_cache->IsCacheValid(params)) { non_global_code_complete_cache->WithLock([&]() { callback(non_global_code_complete_cache->cached_results_, true /*is_cached_result*/); }); } else { - clang_complete->CodeComplete(request->id, request->params, callback); + clang_complete->CodeComplete(request->id, params, callback); } } } From 4612aa062bc23e44da62dd58e4b3d3a8ef13d998 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Jul 2018 13:56:00 -0700 Subject: [PATCH 143/378] $ccls/publishSemanticHighlighting: support both line/character-style and position-style ranges --- src/config.h | 5 ++++- src/message_handler.cc | 8 +++++--- src/message_handler.h | 12 +++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/config.h b/src/config.h index 1ba2f1c69..13379fbf6 100644 --- a/src/config.h +++ b/src/config.h @@ -144,6 +144,9 @@ struct Config { // Semantic highlighting struct Highlight { + // true: LSP line/character; false: position + bool lsRanges = false; + // Like index.{whitelist,blacklist}, don't publish semantic highlighting to // blacklisted files. std::vector blacklist; @@ -230,7 +233,7 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, onParse, onType, whitelist) -MAKE_REFLECT_STRUCT(Config::Highlight, blacklist, whitelist) +MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist, diff --git a/src/message_handler.cc b/src/message_handler.cc index 711f1d2f6..f6ef46952 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -336,12 +336,14 @@ void EmitSemanticHighlighting(DB *db, Out_CclsPublishSemanticHighlighting out; out.params.uri = lsDocumentUri::FromPath(wfile->filename); // Transform lsRange into pair (offset pairs) - { + if (!g_config->highlight.lsRanges) { std::vector> scratch; - for (auto &entry : grouped_symbols) + for (auto &entry : grouped_symbols) { for (auto &range : entry.second.lsRanges) scratch.emplace_back(range, &entry.second); + entry.second.lsRanges.clear(); + } std::sort(scratch.begin(), scratch.end(), [](auto &l, auto &r) { return l.first.start < r.first.start; }); const auto &buf = wfile->buffer_content; @@ -375,7 +377,7 @@ void EmitSemanticHighlighting(DB *db, } for (auto &entry : grouped_symbols) - if (entry.second.ranges.size()) + if (entry.second.ranges.size() || entry.second.lsRanges.size()) out.params.symbols.push_back(std::move(entry.second)); pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } diff --git a/src/message_handler.h b/src/message_handler.h index 425a134d9..f771ec0ba 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -76,15 +76,9 @@ struct Out_CclsPublishSemanticHighlighting std::string method = "$ccls/publishSemanticHighlighting"; Params params; }; -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, - stableId, - parentKind, - kind, - storage, - ranges); -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, - uri, - symbols); +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId, + parentKind, kind, storage, ranges, lsRanges); +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols); MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, From 5dcccea285cada701ada4c5a858afa6ed97b72b0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Jul 2018 16:02:59 -0700 Subject: [PATCH 144/378] Use Clang C++ for completion and diagnostics --- src/clang_complete.cc | 351 ++++++++++++++------------- src/clang_complete.h | 2 - src/clang_tu.cc | 242 +++++++----------- src/clang_tu.h | 59 ++--- src/clang_utils.cc | 274 +++++++++++---------- src/clang_utils.h | 5 +- src/indexer.cc | 67 +---- src/messages/textDocument_didOpen.cc | 2 + src/working_files.cc | 14 -- src/working_files.h | 1 - 10 files changed, 456 insertions(+), 561 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 2d0fb2518..42813cc85 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -5,6 +5,8 @@ #include "log.hh" #include "platform.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include #include #include @@ -16,25 +18,15 @@ using namespace llvm; namespace { -unsigned Flags() { - // TODO: use clang_defaultEditingTranslationUnitOptions()? - return CXTranslationUnit_Incomplete | CXTranslationUnit_KeepGoing | - CXTranslationUnit_CacheCompletionResults | - CXTranslationUnit_PrecompiledPreamble | - CXTranslationUnit_IncludeBriefCommentsInCodeCompletion | - CXTranslationUnit_DetailedPreprocessingRecord | - CXTranslationUnit_CreatePreambleOnFirstParse; -} - std::string StripFileType(const std::string& path) { SmallString<128> Ret; sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path)); return Ret.str(); } -unsigned GetCompletionPriority(const CodeCompletionString& CCS, +unsigned GetCompletionPriority(const CodeCompletionString &CCS, CXCursorKind result_kind, - const std::optional& typedText) { + const std::optional &typedText) { unsigned priority = CCS.getPriority(); if (CCS.getAvailability() != CXAvailability_Available || result_kind == CXCursor_Destructor || @@ -196,35 +188,29 @@ void BuildCompletionItemTexts(std::vector &out, // clang-format on } - for (auto i = out_first; i < out.size(); ++i) - out[i].label += text; - - if (Kind == CodeCompletionString::CK_Informative) - continue; - - for (auto i = out_first; i < out.size(); ++i) { - if (!include_snippets && !out[i].parameters_.empty()) - continue; + if (Kind != CodeCompletionString::CK_Informative) + for (auto i = out_first; i < out.size(); ++i) { + out[i].label += text; + if (!include_snippets && !out[i].parameters_.empty()) + continue; - if (Kind == CodeCompletionString::CK_Placeholder) { - out[i].insertText += + if (Kind == CodeCompletionString::CK_Placeholder) { + out[i].insertText += "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; - out[i].insertTextFormat = lsInsertTextFormat::Snippet; - } else { - out[i].insertText += text; + out[i].insertTextFormat = lsInsertTextFormat::Snippet; + } else { + out[i].insertText += text; + } } - } } - if (result_type.empty()) - return; - - for (auto i = out_first; i < out.size(); ++i) { - // ' : ' for variables, - // ' -> ' (trailing return type-like) for functions - out[i].label += (out[i].label == out[i].filterText ? " : " : " -> "); - out[i].label += result_type; - } + if (result_type.size()) + for (auto i = out_first; i < out.size(); ++i) { + // ' : ' for variables, + // ' -> ' (trailing return type-like) for functions + out[i].label += (out[i].label == out[i].filterText ? " : " : " -> "); + out[i].label += result_type; + } } // |do_insert|: if |!do_insert|, do not append strings to |insert| after @@ -298,56 +284,87 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, } } +class CaptureCompletionResults : public CodeCompleteConsumer { + std::shared_ptr Alloc; + CodeCompletionTUInfo CCTUInfo; + +public: + std::vector ls_items; + + CaptureCompletionResults(const CodeCompleteOptions &Opts) + : CodeCompleteConsumer(Opts, false), + Alloc(std::make_shared()), + CCTUInfo(Alloc) {} + + void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override { + ls_items.reserve(NumResults); + for (unsigned i = 0; i != NumResults; i++) { + CodeCompletionString *CCS = Results[i].CreateCodeCompletionString( + S, Context, getAllocator(), getCodeCompletionTUInfo(), + includeBriefComments()); + if (CCS->getAvailability() == CXAvailability_NotAvailable) + continue; + + lsCompletionItem ls_item; + ls_item.kind = GetCompletionKind(Results[i].CursorKind); + if (const char* brief = CCS->getBriefComment()) + ls_item.documentation = brief; + + // label/detail/filterText/insertText/priority + if (g_config->completion.detailedLabel) { + ls_item.detail = CCS->getParentContextName().str(); + + size_t first_idx = ls_items.size(); + ls_items.push_back(ls_item); + BuildCompletionItemTexts(ls_items, *CCS, + g_config->client.snippetSupport); + + for (size_t j = first_idx; j < ls_items.size(); j++) { + if (g_config->client.snippetSupport && + ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) + ls_items[j].insertText += "$0"; + ls_items[j].priority_ = GetCompletionPriority( + *CCS, Results[i].CursorKind, ls_items[i].filterText); + } + } else { + bool do_insert = true; + int angle_stack = 0; + BuildDetailString(*CCS, ls_item, do_insert, + &ls_item.parameters_, + g_config->client.snippetSupport, angle_stack); + if (g_config->client.snippetSupport && + ls_item.insertTextFormat == lsInsertTextFormat::Snippet) + ls_item.insertText += "$0"; + ls_item.priority_ = + GetCompletionPriority(*CCS, Results[i].CursorKind, ls_item.label); + ls_items.push_back(ls_item); + } + } + } + + CodeCompletionAllocator &getAllocator() override { return *Alloc; } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;} +}; + void TryEnsureDocumentParsed(ClangCompleteManager* manager, std::shared_ptr session, std::unique_ptr* tu, - ClangIndex* index, bool emit_diag) { // Nothing to do. We already have a translation unit. if (*tu) return; - std::vector args = session->file.args; - - // -fspell-checking enables FixIts for, ie, misspelled types. - if (!std::count(args.begin(), args.end(), "-fno-spell-checking") && - !std::count(args.begin(), args.end(), "-fspell-checking")) { - args.push_back("-fspell-checking"); - } - + const auto &args = session->file.args; WorkingFiles::Snapshot snapshot = session->working_files->AsSnapshot( {StripFileType(session->file.filename)}); - std::vector unsaved = snapshot.AsUnsavedFiles(); LOG_S(INFO) << "Creating completion session with arguments " << StringJoin(args, " "); - *tu = ClangTranslationUnit::Create(index, session->file.filename, args, - unsaved, Flags()); - - // Build diagnostics. - if (g_config->diagnostics.onParse && *tu) { - // If we're emitting diagnostics, do an immediate reparse, otherwise we will - // emit stale/bad diagnostics. - *tu = ClangTranslationUnit::Reparse(std::move(*tu), unsaved); - if (!*tu) { - LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " - << session->file.filename; - return; - } - - std::vector ls_diagnostics; - unsigned num_diagnostics = clang_getNumDiagnostics((*tu)->cx_tu); - for (unsigned i = 0; i < num_diagnostics; ++i) { - std::optional diagnostic = BuildAndDisposeDiagnostic( - clang_getDiagnostic((*tu)->cx_tu, i), session->file.filename); - // Filter messages like "too many errors emitted, stopping now - // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after - // conversion to lsDiagnostic - if (diagnostic && diagnostic->range.start.line >= 0) - ls_diagnostics.push_back(*diagnostic); - } - manager->on_diagnostic_(session->file.filename, ls_diagnostics); - } + *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot); } void CompletionPreloadMain(ClangCompleteManager* completion_manager) { @@ -374,8 +391,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) { continue; std::unique_ptr parsing; - TryEnsureDocumentParsed(completion_manager, session, &parsing, &tu->index, - true); + TryEnsureDocumentParsed(completion_manager, session, &parsing, true); // Activate new translation unit. std::lock_guard lock(tu->lock); @@ -404,84 +420,43 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { true /*create_if_needed*/); std::lock_guard lock(session->completion.lock); - TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, - &session->completion.index, false); + TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, false); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. - if (!session->completion.tu) - continue; - - WorkingFiles::Snapshot snapshot = - completion_manager->working_files_->AsSnapshot({StripFileType(path)}); - std::vector unsaved = snapshot.AsUnsavedFiles(); - - unsigned const kCompleteOptions = - CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeBriefComments; - CXCodeCompleteResults* cx_results = clang_codeCompleteAt( - session->completion.tu->cx_tu, session->file.filename.c_str(), - request->position.line + 1, request->position.character + 1, - unsaved.data(), (unsigned)unsaved.size(), kCompleteOptions); - if (!cx_results) { - request->on_complete({}, false /*is_cached_result*/); - continue; - } - - std::vector ls_result; - // this is a guess but can be larger in case of std::optional - // parameters, as they may be expanded into multiple items - ls_result.reserve(cx_results->NumResults); - - for (unsigned i = 0; i < cx_results->NumResults; ++i) { - CXCompletionResult& result = cx_results->Results[i]; - auto CCS = (CodeCompletionString *)result.CompletionString; - if (CCS->getAvailability() == CXAvailability_NotAvailable) - continue; - - lsCompletionItem ls_item; - ls_item.kind = GetCompletionKind(result.CursorKind); - if (const char* brief = CCS->getBriefComment()) - ls_item.documentation = brief; - - // label/detail/filterText/insertText/priority - if (g_config->completion.detailedLabel) { - ls_item.detail = CCS->getParentContextName().str(); - - auto first_idx = ls_result.size(); - ls_result.push_back(ls_item); - - // label/filterText/insertText - BuildCompletionItemTexts(ls_result, *CCS, - g_config->client.snippetSupport); - - for (auto i = first_idx; i < ls_result.size(); ++i) { - if (g_config->client.snippetSupport && - ls_result[i].insertTextFormat == lsInsertTextFormat::Snippet) { - ls_result[i].insertText += "$0"; - } - - ls_result[i].priority_ = GetCompletionPriority( - *CCS, result.CursorKind, ls_result[i].filterText); - } - } else { - bool do_insert = true; - int angle_stack = 0; - BuildDetailString(*CCS, ls_item, do_insert, - &ls_item.parameters_, - g_config->client.snippetSupport, angle_stack); - if (g_config->client.snippetSupport && - ls_item.insertTextFormat == lsInsertTextFormat::Snippet) - ls_item.insertText += "$0"; - ls_item.priority_ = - GetCompletionPriority(*CCS, result.CursorKind, ls_item.label); - ls_result.push_back(ls_item); - } + if (ClangTranslationUnit* tu = session->completion.tu.get()) { + WorkingFiles::Snapshot snapshot = + completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + IntrusiveRefCntPtr FileMgr(&tu->Unit->getFileManager()); + IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); + IntrusiveRefCntPtr Diag(new DiagnosticsEngine( + IntrusiveRefCntPtr(new DiagnosticIDs), &*DiagOpts)); + // StoreDiags Diags; + // IntrusiveRefCntPtr DiagE = + // CompilerInstance::createDiagnostics(DiagOpts.get(), &Diags, false); + + IntrusiveRefCntPtr SrcMgr( + new SourceManager(*Diag, *FileMgr)); + std::vector Remapped = GetRemapped(snapshot); + SmallVector Diagnostics; + SmallVector TemporaryBuffers; + + CodeCompleteOptions Opts; + LangOptions LangOpts; + Opts.IncludeBriefComments = true; + Opts.LoadExternal = false; + Opts.IncludeFixIts = true; + CaptureCompletionResults capture(Opts); + tu->Unit->CodeComplete(session->file.filename, request->position.line + 1, + request->position.character + 1, Remapped, + /*IncludeMacros=*/true, + /*IncludeCodePatterns=*/false, + /*IncludeBriefComments=*/true, capture, tu->PCHCO, + *Diag, LangOpts, *SrcMgr, *FileMgr, Diagnostics, + TemporaryBuffers); + request->on_complete(capture.ls_items, false /*is_cached_result*/); + // completion_manager->on_diagnostic_(session->file.filename, Diags.take()); } - - request->on_complete(ls_result, false /*is_cached_result*/); - - // Make sure |ls_results| is destroyed before clearing |cx_results|. - clang_disposeCodeCompleteResults(cx_results); } } @@ -500,44 +475,72 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { // At this point, we must have a translation unit. Block until we have one. std::lock_guard lock(session->diagnostics.lock); - TryEnsureDocumentParsed( - completion_manager, session, &session->diagnostics.tu, - &session->diagnostics.index, false /*emit_diagnostics*/); + TryEnsureDocumentParsed(completion_manager, session, + &session->diagnostics.tu, + false /*emit_diagnostics*/); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. - if (!session->diagnostics.tu) + ClangTranslationUnit* tu = session->diagnostics.tu.get(); + if (!tu) continue; WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); - std::vector unsaved = snapshot.AsUnsavedFiles(); - - // Emit diagnostics. - session->diagnostics.tu = ClangTranslationUnit::Reparse( - std::move(session->diagnostics.tu), unsaved); - if (!session->diagnostics.tu) { + llvm::CrashRecoveryContext CRC; + if (tu->Reparse(CRC, snapshot)) { LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " << path; continue; } - size_t num_diagnostics = - clang_getNumDiagnostics(session->diagnostics.tu->cx_tu); - std::vector ls_diagnostics; - ls_diagnostics.reserve(num_diagnostics); - for (unsigned i = 0; i < num_diagnostics; ++i) { - CXDiagnostic cx_diag = - clang_getDiagnostic(session->diagnostics.tu->cx_tu, i); - std::optional diagnostic = - BuildAndDisposeDiagnostic(cx_diag, path); - // Filter messages like "too many errors emitted, stopping now - // [-ferror-limit=]" which has line = 0 and got subtracted by 1 after - // conversion to lsDiagnostic - if (diagnostic && diagnostic->range.start.line >= 0) - ls_diagnostics.push_back(*diagnostic); + auto &SM = tu->Unit->getSourceManager(); + auto &LangOpts = tu->Unit->getLangOpts(); + std::vector ls_diags; + for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(), + E = tu->Unit->stored_diag_end(); + I != E; ++I) { + FullSourceLoc FLoc = I->getLocation(); + SourceRange R; + for (const auto &CR : I->getRanges()) { + auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); + if (SM.isPointWithin(FLoc, RT.getBegin(), RT.getEnd())) { + R = CR.getAsRange(); + break; + } + } + Range r = R.isValid() ? FromCharRange(SM, LangOpts, R) + : FromTokenRange(SM, LangOpts, {FLoc, FLoc}); + lsDiagnostic ls_diag; + ls_diag.range = + lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; + switch (I->getLevel()) { + case DiagnosticsEngine::Ignored: + // llvm_unreachable + break; + case DiagnosticsEngine::Note: + case DiagnosticsEngine::Remark: + ls_diag.severity = lsDiagnosticSeverity::Information; + break; + case DiagnosticsEngine::Warning: + ls_diag.severity = lsDiagnosticSeverity::Warning; + break; + case DiagnosticsEngine::Error: + case DiagnosticsEngine::Fatal: + ls_diag.severity = lsDiagnosticSeverity::Error; + } + ls_diag.message = I->getMessage().str(); + for (const FixItHint &FixIt : I->getFixIts()) { + lsTextEdit edit; + edit.newText = FixIt.CodeToInsert; + r = FromCharRange(SM, LangOpts, FixIt.RemoveRange.getAsRange()); + edit.range = + lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; + ls_diag.fixits_.push_back(edit); + } + ls_diags.push_back(ls_diag); } - completion_manager->on_diagnostic_(path, ls_diagnostics); + completion_manager->on_diagnostic_(path, ls_diags); } } diff --git a/src/clang_complete.h b/src/clang_complete.h index af824df18..d9874c91b 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -19,8 +19,6 @@ struct CompletionSession : public std::enable_shared_from_this { // Translation unit for clang. struct Tu { - ClangIndex index{0, 0}; - // When |tu| was last parsed. std::optional> last_parsed_at; diff --git a/src/clang_tu.cc b/src/clang_tu.cc index e98d0453d..5411c9239 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -4,173 +4,113 @@ #include "log.hh" #include "platform.h" #include "utils.h" +#include "working_files.h" + +#include +using namespace clang; #include -#include -#include #include -namespace { - -void EmitDiagnostics(std::string path, - std::vector args, - CXTranslationUnit tu) { - std::string output = "Fatal errors while trying to parse " + path + "\n"; - output += - "Args: " + - StringJoinMap(args, [](const char* arg) { return std::string(arg); }) + - "\n"; - - size_t num_diagnostics = clang_getNumDiagnostics(tu); - for (unsigned i = 0; i < num_diagnostics; ++i) { - output += " - "; - - CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); - - // Location. - CXFile file; - unsigned int line, column; - clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, - &line, &column, nullptr); - std::string path = FileName(file); - output += path + ":" + std::to_string(line - 1) + ":" + - std::to_string(column) + " "; - - // Severity - switch (clang_getDiagnosticSeverity(diagnostic)) { - case CXDiagnostic_Ignored: - case CXDiagnostic_Note: - output += "[info]"; - break; - case CXDiagnostic_Warning: - output += "[warning]"; - break; - case CXDiagnostic_Error: - output += "[error]"; - break; - case CXDiagnostic_Fatal: - output += "[fatal]"; - break; - } - - // Content. - output += " " + ToString(clang_getDiagnosticSpelling(diagnostic)); - - clang_disposeDiagnostic(diagnostic); - - output += "\n"; +Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R, llvm::sys::fs::UniqueID *UniqueID, + bool token) { + SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); + std::pair BInfo = SM.getDecomposedLoc(BLoc); + std::pair EInfo = SM.getDecomposedLoc(ELoc); + if (token) + EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); + unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1, + c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1, + l1 = SM.getLineNumber(EInfo.first, EInfo.second) - 1, + c1 = SM.getColumnNumber(EInfo.first, EInfo.second) - 1; + if (l0 > INT16_MAX) + l0 = 0; + if (c0 > INT16_MAX) + c0 = 0; + if (l1 > INT16_MAX) + l1 = 0; + if (c1 > INT16_MAX) + c1 = 0; + if (UniqueID) { + if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) + *UniqueID = F->getUniqueID(); + else + *UniqueID = llvm::sys::fs::UniqueID(0, 0); } - - LOG_S(WARNING) << output; + return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}}; } -} // namespace - -ClangIndex::ClangIndex() : ClangIndex(1, 0) {} - -ClangIndex::ClangIndex(int exclude_declarations_from_pch, - int display_diagnostics) { - // llvm::InitializeAllTargets (and possibly others) called by - // clang_createIndex transtively modifies/reads lib/Support/TargetRegistry.cpp - // FirstTarget. There will be a race condition if two threads call - // clang_createIndex concurrently. - static std::mutex mutex_; - std::lock_guard lock(mutex_); - cx_index = - clang_createIndex(exclude_declarations_from_pch, display_diagnostics); +Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R, + llvm::sys::fs::UniqueID *UniqueID) { + return FromSourceRange(SM, LangOpts, R, UniqueID, false); } -ClangIndex::~ClangIndex() { - clang_disposeIndex(cx_index); +Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, + SourceRange R, + llvm::sys::fs::UniqueID *UniqueID) { + return FromSourceRange(SM, LangOpts, R, UniqueID, true); } -// static -std::unique_ptr ClangTranslationUnit::Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags) { - std::vector args; - for (auto& arg : arguments) - args.push_back(arg.c_str()); - - CXTranslationUnit cx_tu; - CXErrorCode error_code; - { - error_code = clang_parseTranslationUnit2FullArgv( - index->cx_index, nullptr, args.data(), (int)args.size(), - unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); - } - - if (error_code != CXError_Success && cx_tu) - EmitDiagnostics(filepath, args, cx_tu); - - // We sometimes dump the command to logs and ask the user to run it. Include - // -fsyntax-only so they don't do a full compile. - auto make_msg = [&]() { - return "Please try running the following, identify which flag causes the " - "issue, and report a bug. ccls will then filter the flag for you " - " automatically:\n " + - StringJoin(args, " ") + " -fsyntax-only"; - }; - - switch (error_code) { - case CXError_Success: - return std::make_unique(cx_tu); - case CXError_Failure: - 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(); - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " - << make_msg(); - return nullptr; +std::vector +GetRemapped(const WorkingFiles::Snapshot &snapshot) { + std::vector Remapped; + for (auto &file : snapshot.files) { + std::unique_ptr MB = + llvm::MemoryBuffer::getMemBufferCopy(file.content, file.filename); + Remapped.emplace_back(file.filename, MB.release()); } - - return nullptr; + return Remapped; } -// static -std::unique_ptr ClangTranslationUnit::Reparse( - std::unique_ptr tu, - std::vector& unsaved) { - int error_code = clang_reparseTranslationUnit( - tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), - clang_defaultReparseOptions(tu->cx_tu)); - - if (error_code != CXError_Success && tu->cx_tu) - EmitDiagnostics("", {}, tu->cx_tu); - - switch (error_code) { - case CXError_Success: - return tu; - case CXError_Failure: - LOG_S(ERROR) << "libclang reparse generic failure"; - return nullptr; - case CXError_Crashed: - LOG_S(ERROR) << "libclang reparse crashed"; - return nullptr; - case CXError_InvalidArguments: - LOG_S(ERROR) << "libclang reparse had invalid arguments"; - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang reparse had ast read error"; - return nullptr; +std::unique_ptr +ClangTranslationUnit::Create(const std::string &filepath, + const std::vector &args, + const WorkingFiles::Snapshot &snapshot) { + std::vector Args; + for (auto& arg : args) + Args.push_back(arg.c_str()); + Args.push_back("-fno-spell-checking"); + + auto ret = std::make_unique(); + IntrusiveRefCntPtr Diags( + CompilerInstance::createDiagnostics(new DiagnosticOptions)); + std::vector Remapped = GetRemapped(snapshot); + + ret->PCHCO = std::make_shared(); + std::unique_ptr ErrUnit, Unit; + llvm::CrashRecoveryContext CRC; + auto parse = [&]() { + Unit.reset(ASTUnit::LoadFromCommandLine( + Args.data(), Args.data() + Args.size(), + /*PCHContainerOpts=*/ret->PCHCO, Diags, + /*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false, + /*CaptureDiagnostics=*/true, Remapped, + /*RemappedFilesKeepOriginalName=*/true, 1, TU_Prefix, + /*CacheCodeCompletionResults=*/true, true, + /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodiesScope::None, + /*SingleFileParse=*/false, + /*UserFilesAreVolatile=*/true, false, + ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); + }; + if (!RunSafely(CRC, parse)) { + LOG_S(ERROR) + << "clang crashed for " << filepath << "\n" + << StringJoin(args, " ") + " -fsyntax-only"; + return {}; } + if (!Unit && !ErrUnit) + return {}; - return nullptr; + ret->Unit = std::move(Unit); + return ret; } -ClangTranslationUnit::ClangTranslationUnit(CXTranslationUnit tu) : cx_tu(tu) {} - -ClangTranslationUnit::~ClangTranslationUnit() { - clang_disposeTranslationUnit(cx_tu); +int ClangTranslationUnit::Reparse(llvm::CrashRecoveryContext &CRC, + const WorkingFiles::Snapshot &snapshot) { + int ret = 1; + auto parse = [&]() { ret = Unit->Reparse(PCHCO, GetRemapped(snapshot)); }; + (void)RunSafely(CRC, parse); + return ret; } diff --git a/src/clang_tu.h b/src/clang_tu.h index b363c68be..17b4b0e27 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -1,40 +1,45 @@ #pragma once #include "position.h" +#include "working_files.h" -#include +#include +#include +#include #include #include #include +#include -// Simple RAII wrapper about CXIndex. -// Note: building a ClangIndex instance acquires a global lock, since libclang -// API does not appear to be thread-safe here. -class ClangIndex { - public: - ClangIndex(); - ClangIndex(int exclude_declarations_from_pch, int display_diagnostics); - ~ClangIndex(); - CXIndex cx_index; -}; +std::vector +GetRemapped(const WorkingFiles::Snapshot &snapshot); -// RAII wrapper around CXTranslationUnit which also makes it much more -// challenging to use a CXTranslationUnit instance that is not correctly -// initialized. -struct ClangTranslationUnit { - static std::unique_ptr Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags); +Range FromCharRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, + clang::SourceRange R, + llvm::sys::fs::UniqueID *UniqueID = nullptr); + +Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, + clang::SourceRange R, + llvm::sys::fs::UniqueID *UniqueID = nullptr); - static std::unique_ptr Reparse( - std::unique_ptr tu, - std::vector& unsaved); +template +bool RunSafely(llvm::CrashRecoveryContext &CRC, Fn &&fn) { + const char *env = getenv("CCLS_CRASH_RECOVERY"); + if (env && strcmp(env, "0") == 0) { + fn(); + return true; + } + return CRC.RunSafely(fn); +} + +struct ClangTranslationUnit { + static std::unique_ptr + Create(const std::string &filepath, const std::vector &arguments, + const WorkingFiles::Snapshot &snapshot); - explicit ClangTranslationUnit(CXTranslationUnit tu); - ~ClangTranslationUnit(); + int Reparse(llvm::CrashRecoveryContext &CRC, + const WorkingFiles::Snapshot &snapshot); - CXTranslationUnit cx_tu; + std::shared_ptr PCHCO; + std::unique_ptr Unit; }; diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 24bbfb892..d1d141ead 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -1,113 +1,12 @@ #include "clang_utils.h" +#include "filesystem.hh" #include "platform.h" -#include "filesystem.hh" +#include using namespace clang; using namespace llvm; -namespace { - -lsRange GetLsRangeForFixIt(const CXSourceRange& range) { - CXSourceLocation start = clang_getRangeStart(range); - CXSourceLocation end = clang_getRangeEnd(range); - - unsigned int start_line, start_column; - clang_getSpellingLocation(start, nullptr, &start_line, &start_column, - nullptr); - unsigned int end_line, end_column; - clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr); - - return lsRange{lsPosition{int(start_line) - 1, int(start_column) - 1}, - lsPosition{int(end_line) - 1, int(end_column)}}; -} - -} // namespace - -// See clang_formatDiagnostic -std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, - const std::string& path) { - // Get diagnostic location. - CXFile file; - unsigned start_line, start_column; - clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, - &start_line, &start_column, nullptr); - - if (file && path != FileName(file)) { - clang_disposeDiagnostic(diagnostic); - return std::nullopt; - } - - unsigned end_line = start_line, end_column = start_column, - num_ranges = clang_getDiagnosticNumRanges(diagnostic); - for (unsigned i = 0; i < num_ranges; i++) { - CXFile file0, file1; - unsigned line0, column0, line1, column1; - CXSourceRange range = clang_getDiagnosticRange(diagnostic, i); - clang_getSpellingLocation(clang_getRangeStart(range), &file0, &line0, - &column0, nullptr); - clang_getSpellingLocation(clang_getRangeEnd(range), &file1, &line1, - &column1, nullptr); - if (file0 != file1 || file0 != file) - continue; - if (line0 < start_line || (line0 == start_line && column0 < start_column)) { - start_line = line0; - start_column = column0; - } - if (line1 > end_line || (line1 == end_line && column1 > end_column)) { - end_line = line1; - end_column = column1; - } - } - - // Build diagnostic. - lsDiagnostic ls_diagnostic; - ls_diagnostic.range = lsRange{{int(start_line) - 1, int(start_column) - 1}, - {int(end_line) - 1, int(end_column) - 1}}; - - ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic)); - - // Append the flag that enables this diagnostic, ie, [-Wswitch] - std::string enabling_flag = - ToString(clang_getDiagnosticOption(diagnostic, nullptr)); - if (!enabling_flag.empty()) - ls_diagnostic.message += " [" + enabling_flag + "]"; - - ls_diagnostic.code = clang_getDiagnosticCategory(diagnostic); - - switch (clang_getDiagnosticSeverity(diagnostic)) { - case CXDiagnostic_Ignored: - // llvm_unreachable - break; - case CXDiagnostic_Note: - ls_diagnostic.severity = lsDiagnosticSeverity::Information; - break; - case CXDiagnostic_Warning: - ls_diagnostic.severity = lsDiagnosticSeverity::Warning; - break; - case CXDiagnostic_Error: - case CXDiagnostic_Fatal: - ls_diagnostic.severity = lsDiagnosticSeverity::Error; - break; - } - - // Report fixits - unsigned num_fixits = clang_getDiagnosticNumFixIts(diagnostic); - for (unsigned i = 0; i < num_fixits; ++i) { - CXSourceRange replacement_range; - CXString text = clang_getDiagnosticFixIt(diagnostic, i, &replacement_range); - - lsTextEdit edit; - edit.newText = ToString(text); - edit.range = GetLsRangeForFixIt(replacement_range); - ls_diagnostic.fixits_.push_back(edit); - } - - clang_disposeDiagnostic(diagnostic); - - return ls_diagnostic; -} - std::string FileName(CXFile file) { std::string ret; // clang > 6 @@ -153,34 +52,145 @@ std::string ToString(CXCursorKind kind) { return ToString(clang_getCursorKindSpelling(kind)); } -const char* ClangBuiltinTypeName(CXTypeKind kind) { - switch (kind) { - // clang-format off - case CXType_Bool: return "bool"; - case CXType_Char_U: return "char"; - case CXType_UChar: return "unsigned char"; - case CXType_Char16: return "char16_t"; - case CXType_Char32: return "char32_t"; - case CXType_UShort: return "unsigned short"; - case CXType_UInt: return "unsigned int"; - case CXType_ULong: return "unsigned long"; - case CXType_ULongLong: return "unsigned long long"; - case CXType_UInt128: return "unsigned __int128"; - case CXType_Char_S: return "char"; - case CXType_SChar: return "signed char"; - case CXType_WChar: return "wchar_t"; - case CXType_Short: return "short"; - case CXType_Int: return "int"; - case CXType_Long: return "long"; - case CXType_LongLong: return "long long"; - case CXType_Int128: return "__int128"; - case CXType_Float: return "float"; - case CXType_Double: return "double"; - case CXType_LongDouble: return "long double"; - case CXType_Float128: return "__float128"; - case CXType_Half: return "_Float16"; - case CXType_NullPtr: return "nullptr"; - default: return ""; - // clang-format on +// clang::BuiltinType::getName without PrintingPolicy +const char* ClangBuiltinTypeName(int kind) { + switch (BuiltinType::Kind(kind)) { + case BuiltinType::Void: + return "void"; + case BuiltinType::Bool: + return "bool"; + case BuiltinType::Char_S: + return "char"; + case BuiltinType::Char_U: + return "char"; + case BuiltinType::SChar: + return "signed char"; + case BuiltinType::Short: + return "short"; + case BuiltinType::Int: + return "int"; + case BuiltinType::Long: + return "long"; + case BuiltinType::LongLong: + return "long long"; + case BuiltinType::Int128: + return "__int128"; + case BuiltinType::UChar: + return "unsigned char"; + case BuiltinType::UShort: + return "unsigned short"; + case BuiltinType::UInt: + return "unsigned int"; + case BuiltinType::ULong: + return "unsigned long"; + case BuiltinType::ULongLong: + return "unsigned long long"; + case BuiltinType::UInt128: + return "unsigned __int128"; + case BuiltinType::Half: + return "__fp16"; + case BuiltinType::Float: + return "float"; + case BuiltinType::Double: + return "double"; + case BuiltinType::LongDouble: + return "long double"; + case BuiltinType::ShortAccum: + return "short _Accum"; + case BuiltinType::Accum: + return "_Accum"; + case BuiltinType::LongAccum: + return "long _Accum"; + case BuiltinType::UShortAccum: + return "unsigned short _Accum"; + case BuiltinType::UAccum: + return "unsigned _Accum"; + case BuiltinType::ULongAccum: + return "unsigned long _Accum"; + case BuiltinType::BuiltinType::ShortFract: + return "short _Fract"; + case BuiltinType::BuiltinType::Fract: + return "_Fract"; + case BuiltinType::BuiltinType::LongFract: + return "long _Fract"; + case BuiltinType::BuiltinType::UShortFract: + return "unsigned short _Fract"; + case BuiltinType::BuiltinType::UFract: + return "unsigned _Fract"; + case BuiltinType::BuiltinType::ULongFract: + return "unsigned long _Fract"; + case BuiltinType::BuiltinType::SatShortAccum: + return "_Sat short _Accum"; + case BuiltinType::BuiltinType::SatAccum: + return "_Sat _Accum"; + case BuiltinType::BuiltinType::SatLongAccum: + return "_Sat long _Accum"; + case BuiltinType::BuiltinType::SatUShortAccum: + return "_Sat unsigned short _Accum"; + case BuiltinType::BuiltinType::SatUAccum: + return "_Sat unsigned _Accum"; + case BuiltinType::BuiltinType::SatULongAccum: + return "_Sat unsigned long _Accum"; + case BuiltinType::BuiltinType::SatShortFract: + return "_Sat short _Fract"; + case BuiltinType::BuiltinType::SatFract: + return "_Sat _Fract"; + case BuiltinType::BuiltinType::SatLongFract: + return "_Sat long _Fract"; + case BuiltinType::BuiltinType::SatUShortFract: + return "_Sat unsigned short _Fract"; + case BuiltinType::BuiltinType::SatUFract: + return "_Sat unsigned _Fract"; + case BuiltinType::BuiltinType::SatULongFract: + return "_Sat unsigned long _Fract"; + case BuiltinType::Float16: + return "_Float16"; + case BuiltinType::Float128: + return "__float128"; + case BuiltinType::WChar_S: + case BuiltinType::WChar_U: + return "wchar_t"; + case BuiltinType::Char8: + return "char8_t"; + case BuiltinType::Char16: + return "char16_t"; + case BuiltinType::Char32: + return "char32_t"; + case BuiltinType::NullPtr: + return "nullptr_t"; + case BuiltinType::Overload: + return ""; + case BuiltinType::BoundMember: + return ""; + case BuiltinType::PseudoObject: + return ""; + case BuiltinType::Dependent: + return ""; + case BuiltinType::UnknownAny: + return ""; + case BuiltinType::ARCUnbridgedCast: + return ""; + case BuiltinType::BuiltinFn: + return ""; + case BuiltinType::ObjCId: + return "id"; + case BuiltinType::ObjCClass: + return "Class"; + case BuiltinType::ObjCSel: + return "SEL"; + case BuiltinType::OCLSampler: + return "sampler_t"; + case BuiltinType::OCLEvent: + return "event_t"; + case BuiltinType::OCLClkEvent: + return "clk_event_t"; + case BuiltinType::OCLQueue: + return "queue_t"; + case BuiltinType::OCLReserveID: + return "reserve_id_t"; + case BuiltinType::OMPArraySection: + return ""; + default: + return ""; } } diff --git a/src/clang_utils.h b/src/clang_utils.h index 7b7a1da47..7f52eded6 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -8,9 +8,6 @@ #include #include -std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, - const std::string& path); - // Returns the absolute path to |file|. std::string FileName(CXFile file); std::string FileName(const clang::FileEntry& file); @@ -19,4 +16,4 @@ std::string ToString(CXString cx_string); std::string ToString(CXCursorKind cursor_kind); -const char* ClangBuiltinTypeName(CXTypeKind); +const char* ClangBuiltinTypeName(int); diff --git a/src/indexer.cc b/src/indexer.cc index 710499475..505d1ea05 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1,5 +1,6 @@ #include "indexer.h" +#include "clang_tu.h" #include "log.hh" #include "platform.h" #include "serializer.h" @@ -83,43 +84,6 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, BInfo.second); } -Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, llvm::sys::fs::UniqueID *UniqueID, - bool token) { - SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); - std::pair BInfo = SM.getDecomposedLoc(BLoc); - std::pair EInfo = SM.getDecomposedLoc(ELoc); - if (token) - EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); - unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1, - c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1, - l1 = SM.getLineNumber(EInfo.first, EInfo.second) - 1, - c1 = SM.getColumnNumber(EInfo.first, EInfo.second) - 1; - if (l0 > INT16_MAX) l0 = 0; - if (c0 > INT16_MAX) c0 = 0; - if (l1 > INT16_MAX) l1 = 0; - if (c1 > INT16_MAX) c1 = 0; - if (UniqueID) { - if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) - *UniqueID = F->getUniqueID(); - else - *UniqueID = llvm::sys::fs::UniqueID(0, 0); - } - return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}}; -} - -Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, - llvm::sys::fs::UniqueID *UniqueID = nullptr) { - return FromSourceRange(SM, LangOpts, R, UniqueID, false); -} - -Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, - llvm::sys::fs::UniqueID *UniqueID = nullptr) { - return FromSourceRange(SM, LangOpts, R, UniqueID, true); -} - SymbolKind GetSymbolKind(const Decl* D) { switch (D->getKind()) { case Decl::TranslationUnit: @@ -1167,31 +1131,22 @@ std::vector> Index( DataConsumer, IndexOpts, std::make_unique(param)); DiagnosticErrorTrap DiagTrap(*Diags); - bool success = false; llvm::CrashRecoveryContext CRC; - { - auto compile = [&]() { - success = ASTUnit::LoadFromCompilerInvocationAction( - std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), - /*Persistent=*/true, /*ResourceDir=*/"", - /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, true); - }; - const char *env = getenv("CCLS_CRASH_RECOVERY"); - if (env && strcmp(env, "0") == 0) - compile(); - else - CRC.RunSafely(compile); + auto compile = [&]() { + ASTUnit::LoadFromCompilerInvocationAction( + std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), + /*Persistent=*/true, /*ResourceDir=*/"", + /*OnlyLocalDecls=*/true, + /*CaptureDiagnostics=*/true, 0, false, false, true); + }; + if (!RunSafely(CRC, compile)) { + LOG_S(ERROR) << "clang crashed for " << file; + return {}; } - if (!Unit) { LOG_S(ERROR) << "failed to index " << file; return {}; } - if (!success) { - LOG_S(ERROR) << "clang crashed for " << file; - return {}; - } const SourceManager& SM = Unit->getSourceManager(); const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index ed96e6de7..70ae716b6 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -51,6 +51,8 @@ struct Handler_TextDocumentDidOpen include_complete->AddFile(working_file->filename); clang_complete->NotifyView(path); + if (g_config->diagnostics.onParse) + clang_complete->DiagnosticsUpdate({params.textDocument.uri}); if (params.args.size()) project->SetFlagsForFile(params.args, path); diff --git a/src/working_files.cc b/src/working_files.cc index 1ad076c2b..6f0ca26b9 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -195,20 +195,6 @@ std::optional FindMatchingLine(const std::vector& index_lines, } // namespace -std::vector WorkingFiles::Snapshot::AsUnsavedFiles() const { - std::vector result; - result.reserve(files.size()); - for (auto& file : files) { - CXUnsavedFile unsaved; - unsaved.Filename = file.filename.c_str(); - unsaved.Contents = file.content.c_str(); - unsaved.Length = (unsigned long)file.content.size(); - - result.push_back(unsaved); - } - return result; -} - WorkingFile::WorkingFile(const std::string& filename, const std::string& buffer_content) : filename(filename), buffer_content(buffer_content) { diff --git a/src/working_files.h b/src/working_files.h index 690149893..d5a960ac0 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -84,7 +84,6 @@ struct WorkingFiles { std::string content; }; - std::vector AsUnsavedFiles() const; std::vector files; }; From df72a9eb72d3869721f35527444518f251461fba Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 00:45:51 -0700 Subject: [PATCH 145/378] Simplify --- src/clang_complete.h | 2 -- src/clang_utils.cc | 33 ++-------------------------- src/clang_utils.h | 11 +--------- src/file_consumer.h | 1 - src/indexer.cc | 3 ++- src/indexer.h | 1 + src/messages/ccls_memberHierarchy.cc | 2 +- src/test.cc | 9 ++++---- src/working_files.h | 4 +--- 9 files changed, 13 insertions(+), 53 deletions(-) diff --git a/src/clang_complete.h b/src/clang_complete.h index d9874c91b..8633ddced 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -8,8 +8,6 @@ #include "threaded_queue.h" #include "working_files.h" -#include - #include #include #include diff --git a/src/clang_utils.cc b/src/clang_utils.cc index d1d141ead..8e0b11252 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -1,30 +1,14 @@ #include "clang_utils.h" +#include "config.h" #include "filesystem.hh" #include "platform.h" +#include "utils.h" #include using namespace clang; using namespace llvm; -std::string FileName(CXFile file) { - std::string ret; - // clang > 6 -#if CINDEX_VERSION >= 48 - ret = ToString(clang_File_tryGetRealPathName(file)); -#endif - if (ret.empty()) - // clang_getFileName return values may contain .. - ret = NormalizePath(ToString(clang_getFileName(file))); - // Resolve /usr/include/c++/7.3.0 symlink. - if (!StartsWith(ret, g_config->projectRoot)) { - SmallString<256> dest; - sys::fs::real_path(ret, dest); - ret = dest.str(); - } - return ret; -} - std::string FileName(const FileEntry& file) { StringRef Name = file.tryGetRealPathName(); if (Name.empty()) @@ -39,19 +23,6 @@ std::string FileName(const FileEntry& file) { return ret; } -std::string ToString(CXString cx_string) { - std::string string; - if (cx_string.data != nullptr) { - string = clang_getCString(cx_string); - clang_disposeString(cx_string); - } - return string; -} - -std::string ToString(CXCursorKind kind) { - return ToString(clang_getCursorKindSpelling(kind)); -} - // clang::BuiltinType::getName without PrintingPolicy const char* ClangBuiltinTypeName(int kind) { switch (BuiltinType::Kind(kind)) { diff --git a/src/clang_utils.h b/src/clang_utils.h index 7f52eded6..6bf5d04e3 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -1,19 +1,10 @@ #pragma once -#include "lsp_diagnostic.h" - -#include #include -#include -#include +#include // Returns the absolute path to |file|. -std::string FileName(CXFile file); std::string FileName(const clang::FileEntry& file); -std::string ToString(CXString cx_string); - -std::string ToString(CXCursorKind cursor_kind); - const char* ClangBuiltinTypeName(int); diff --git a/src/file_consumer.h b/src/file_consumer.h index a2ec01294..2dcb9622e 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -4,7 +4,6 @@ #include "serializer.h" #include "utils.h" -#include #include #include diff --git a/src/indexer.cc b/src/indexer.cc index 505d1ea05..60aad85f5 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -6,6 +6,7 @@ #include "serializer.h" using ccls::Intern; +#include #include #include #include @@ -777,7 +778,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { } [[fallthrough]]; case Decl::Record: { - auto *RD = cast(OrigD); + auto *RD = cast(D); // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; diff --git a/src/indexer.h b/src/indexer.h index 7d2bc1370..0e925e851 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -4,6 +4,7 @@ #include "file_consumer.h" #include "language.h" #include "lsp.h" +#include "lsp_diagnostic.h" #include "maybe.h" #include "position.h" #include "serializer.h" diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index 653b773de..e40244c40 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -125,7 +125,7 @@ bool Expand(MessageHandler* m, bool qualified, int levels) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { - entry->name = ClangBuiltinTypeName(CXTypeKind(entry->usr)); + entry->name = ClangBuiltinTypeName(int(entry->usr)); return true; } const QueryType& type = m->db->Type(entry->usr); diff --git a/src/test.cc b/src/test.cc index cade7314b..83ba466cb 100644 --- a/src/test.cc +++ b/src/test.cc @@ -6,6 +6,8 @@ #include "serializer.h" #include "utils.h" +#include + #include #include #include @@ -227,13 +229,12 @@ IndexFile* FindDbForPathEnding( bool RunIndexTests(const std::string& filter_path, bool enable_update) { gTestOutputMode = true; - std::string version = ToString(clang_getClangVersion()); + std::string version = LLVM_VERSION_STRING; // Index tests change based on the version of clang used. - static const char kRequiredClangVersion[] = - "clang version 6.0.0 (tags/RELEASE_600/final)"; + static const char kRequiredClangVersion[] = "6.0.0"; if (version != kRequiredClangVersion && - version.find("trunk") == std::string::npos) { + version.find("svn") == std::string::npos) { fprintf(stderr, "Index tests must be run using clang version %s, ccls is running " "with %s\n", diff --git a/src/working_files.h b/src/working_files.h index d5a960ac0..a1758b744 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -3,10 +3,8 @@ #include "lsp_diagnostic.h" #include "utils.h" -#include -#include - #include +#include #include struct WorkingFile { From eea1b928250ee24266ab737036b72d3843b6544d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 00:57:48 -0700 Subject: [PATCH 146/378] Enable clangDriver in project.cc https://bugs.llvm.org/show_bug.cgi?id=37695 is not fixed. But since we have eliminated libclang for indexing and completion the bug no longer bothers us. --- README.md | 6 +++--- src/clang_complete.cc | 5 ++++- src/clang_tu.cc | 7 ++++++- src/clang_utils.cc | 5 +++++ src/project.cc | 24 ++---------------------- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 7075260dd..289e80ff4 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,18 @@ a C/C++/Objective-C language server. It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ](../../wiki/FAQ). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. -The comparison with cquery as noted on 2018-07-09: +The comparison with cquery as noted on 2018-07-15: | | cquery | ccls | |------------ |--------------------------------|------------------------------| | third_party | more | fewer | | C++ | C++14 | C++17 | -| clang API | libclang (C) | libclang + clang/llvm C++ | +| clang API | libclang (C) | clang/llvm C++ | | Filesystem | AbsolutePath + custom routines | llvm/Support | | index | libclang | clangIndex, some enhancement | | pipeline | index merge+id remapping | simpler and more robust | -cquery has system include path detection (through running the compiler driver) while ccls does not. +cquery has system include path detection (through running the compiler driver) while ccls uses clangDriver. # >>> [Getting started](../../wiki/Getting-started) (CLICK HERE) <<< diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 42813cc85..af7e936c7 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -9,6 +9,7 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include #include +#include #include using namespace clang; using namespace llvm; @@ -444,8 +445,10 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { CodeCompleteOptions Opts; LangOptions LangOpts; Opts.IncludeBriefComments = true; - Opts.LoadExternal = false; +#if LLVM_VERSION_MAJOR >= 7 + Opts.LoadExternal = true; Opts.IncludeFixIts = true; +#endif CaptureCompletionResults capture(Opts); tu->Unit->CodeComplete(session->file.filename, request->position.line + 1, request->position.character + 1, Remapped, diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 5411c9239..092caab43 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -89,7 +89,12 @@ ClangTranslationUnit::Create(const std::string &filepath, /*CaptureDiagnostics=*/true, Remapped, /*RemappedFilesKeepOriginalName=*/true, 1, TU_Prefix, /*CacheCodeCompletionResults=*/true, true, - /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodiesScope::None, + /*AllowPCHWithCompilerErrors=*/true, +#if LLVM_VERSION_MAJOR >= 7 + SkipFunctionBodiesScope::None, +#else + false, +#endif /*SingleFileParse=*/false, /*UserFilesAreVolatile=*/true, false, ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 8e0b11252..8ed4c2016 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -6,6 +6,7 @@ #include "utils.h" #include +#include using namespace clang; using namespace llvm; @@ -66,6 +67,7 @@ const char* ClangBuiltinTypeName(int kind) { return "double"; case BuiltinType::LongDouble: return "long double"; +#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::ShortAccum: return "short _Accum"; case BuiltinType::Accum: @@ -114,6 +116,7 @@ const char* ClangBuiltinTypeName(int kind) { return "_Sat unsigned _Fract"; case BuiltinType::BuiltinType::SatULongFract: return "_Sat unsigned long _Fract"; +#endif case BuiltinType::Float16: return "_Float16"; case BuiltinType::Float128: @@ -121,8 +124,10 @@ const char* ClangBuiltinTypeName(int kind) { case BuiltinType::WChar_S: case BuiltinType::WChar_U: return "wchar_t"; +#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::Char8: return "char8_t"; +#endif case BuiltinType::Char16: return "char16_t"; case BuiltinType::Char32: diff --git a/src/project.cc b/src/project.cc index c74ef410d..7140e0827 100644 --- a/src/project.cc +++ b/src/project.cc @@ -14,12 +14,9 @@ using namespace ccls; #include #include -#include #include #include #include -#include -#include #include #include using namespace clang; @@ -99,22 +96,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( args.insert(args.end(), config->extra_flags.begin(), config->extra_flags.end()); -#if 1 - std::unique_ptr Opts = driver::createDriverOptTable(); - unsigned MissingArgIndex, MissingArgCount; - std::vector cargs; - for (auto& arg : args) - cargs.push_back(arg.c_str()); - InputArgList Args = - Opts->ParseArgs(makeArrayRef(cargs), MissingArgIndex, MissingArgCount, - driver::options::CC1Option); - using namespace clang::driver::options; - for (const auto* A : Args.filtered(OPT_I, OPT_c_isystem, OPT_cxx_isystem, - OPT_isystem, OPT_idirafter)) - config->angle_dirs.insert(entry.ResolveIfRelative(A->getValue())); - for (const auto* A : Args.filtered(OPT_I, OPT_iquote)) - config->quote_dirs.insert(entry.ResolveIfRelative(A->getValue())); -#else // a weird C++ deduction guide heap-use-after-free causes libclang to crash. IgnoringDiagConsumer DiagC; IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); @@ -164,7 +145,6 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( break; } } -#endif for (size_t i = 1; i < args.size(); i++) // This is most likely the file path we will be passing to clang. The @@ -176,9 +156,9 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - // if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) + if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); - // if (CI->getFileSystemOpts().WorkingDir.empty()) + if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); // There could be a clang version mismatch between what the project uses and From dd05ad9f65fe9dd8ec5252ec3b1f81b960a46a02 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 10:10:24 -0700 Subject: [PATCH 147/378] Diagnostics --- src/clang_complete.cc | 46 +++++++++++++++++++++++-------------------- src/clang_tu.cc | 15 +++++++------- src/clang_tu.h | 4 ++-- src/indexer.cc | 3 ++- src/project.cc | 5 ++--- 5 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index af7e936c7..5328437ea 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -346,15 +346,19 @@ class CaptureCompletionResults : public CodeCompleteConsumer { } } + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates) override {} + CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;} }; -void TryEnsureDocumentParsed(ClangCompleteManager* manager, +void TryEnsureDocumentParsed(ClangCompleteManager *manager, std::shared_ptr session, - std::unique_ptr* tu, - bool emit_diag) { + std::unique_ptr *tu, + bool diagnostic) { // Nothing to do. We already have a translation unit. if (*tu) return; @@ -365,7 +369,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, LOG_S(INFO) << "Creating completion session with arguments " << StringJoin(args, " "); - *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot); + *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot, + diagnostic); } void CompletionPreloadMain(ClangCompleteManager* completion_manager) { @@ -392,7 +397,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) { continue; std::unique_ptr parsing; - TryEnsureDocumentParsed(completion_manager, session, &parsing, true); + TryEnsureDocumentParsed(completion_manager, session, &parsing, false); // Activate new translation unit. std::lock_guard lock(tu->lock); @@ -454,33 +459,30 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { request->position.character + 1, Remapped, /*IncludeMacros=*/true, /*IncludeCodePatterns=*/false, - /*IncludeBriefComments=*/true, capture, tu->PCHCO, - *Diag, LangOpts, *SrcMgr, *FileMgr, Diagnostics, - TemporaryBuffers); + /*IncludeBriefComments=*/g_config->index.comments, + capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr, + *FileMgr, Diagnostics, TemporaryBuffers); request->on_complete(capture.ls_items, false /*is_cached_result*/); // completion_manager->on_diagnostic_(session->file.filename, Diags.take()); } } } -void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { +void DiagnosticQueryMain(ClangCompleteManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = - completion_manager->diagnostic_request_.Dequeue(); + manager->diagnostic_request_.Dequeue(); if (!g_config->diagnostics.onType) continue; std::string path = request.document.uri.GetPath(); - std::shared_ptr session = - completion_manager->TryGetSession(path, true /*mark_as_completion*/, - true /*create_if_needed*/); + std::shared_ptr session = manager->TryGetSession( + path, true /*mark_as_completion*/, true /*create_if_needed*/); // At this point, we must have a translation unit. Block until we have one. std::lock_guard lock(session->diagnostics.lock); - TryEnsureDocumentParsed(completion_manager, session, - &session->diagnostics.tu, - false /*emit_diagnostics*/); + TryEnsureDocumentParsed(manager, session, &session->diagnostics.tu, true); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. @@ -489,7 +491,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { continue; WorkingFiles::Snapshot snapshot = - completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + manager->working_files_->AsSnapshot({StripFileType(path)}); llvm::CrashRecoveryContext CRC; if (tu->Reparse(CRC, snapshot)) { LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " @@ -497,13 +499,16 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { continue; } - auto &SM = tu->Unit->getSourceManager(); auto &LangOpts = tu->Unit->getLangOpts(); std::vector ls_diags; for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(), E = tu->Unit->stored_diag_end(); I != E; ++I) { FullSourceLoc FLoc = I->getLocation(); + const auto &SM = FLoc.getManager(); + + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(FLoc)); + if (!FE || FileName(*FE) != path) continue; SourceRange R; for (const auto &CR : I->getRanges()) { auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); @@ -520,11 +525,10 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { switch (I->getLevel()) { case DiagnosticsEngine::Ignored: // llvm_unreachable - break; case DiagnosticsEngine::Note: case DiagnosticsEngine::Remark: ls_diag.severity = lsDiagnosticSeverity::Information; - break; + continue; case DiagnosticsEngine::Warning: ls_diag.severity = lsDiagnosticSeverity::Warning; break; @@ -543,7 +547,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { } ls_diags.push_back(ls_diag); } - completion_manager->on_diagnostic_(path, ls_diags); + manager->on_diagnostic_(path, ls_diags); } } diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 092caab43..9e2b3ac28 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -64,14 +64,14 @@ GetRemapped(const WorkingFiles::Snapshot &snapshot) { return Remapped; } -std::unique_ptr -ClangTranslationUnit::Create(const std::string &filepath, - const std::vector &args, - const WorkingFiles::Snapshot &snapshot) { +std::unique_ptr ClangTranslationUnit::Create( + const std::string &filepath, const std::vector &args, + const WorkingFiles::Snapshot &snapshot, bool diagnostic) { std::vector Args; for (auto& arg : args) Args.push_back(arg.c_str()); Args.push_back("-fno-spell-checking"); + Args.push_back("-fallow-editor-placeholders"); auto ret = std::make_unique(); IntrusiveRefCntPtr Diags( @@ -86,9 +86,10 @@ ClangTranslationUnit::Create(const std::string &filepath, Args.data(), Args.data() + Args.size(), /*PCHContainerOpts=*/ret->PCHCO, Diags, /*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false, - /*CaptureDiagnostics=*/true, Remapped, - /*RemappedFilesKeepOriginalName=*/true, 1, TU_Prefix, - /*CacheCodeCompletionResults=*/true, true, + /*CaptureDiagnostics=*/diagnostic, Remapped, + /*RemappedFilesKeepOriginalName=*/true, 1, + diagnostic ? TU_Complete : TU_Prefix, + /*CacheCodeCompletionResults=*/true, g_config->index.comments, /*AllowPCHWithCompilerErrors=*/true, #if LLVM_VERSION_MAJOR >= 7 SkipFunctionBodiesScope::None, diff --git a/src/clang_tu.h b/src/clang_tu.h index 17b4b0e27..741d9a40f 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -34,8 +34,8 @@ bool RunSafely(llvm::CrashRecoveryContext &CRC, Fn &&fn) { struct ClangTranslationUnit { static std::unique_ptr - Create(const std::string &filepath, const std::vector &arguments, - const WorkingFiles::Snapshot &snapshot); + Create(const std::string &filepath, const std::vector &args, + const WorkingFiles::Snapshot &snapshot, bool diagnostic); int Reparse(llvm::CrashRecoveryContext &CRC, const WorkingFiles::Snapshot &snapshot); diff --git a/src/indexer.cc b/src/indexer.cc index 60aad85f5..24f601e36 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1138,7 +1138,8 @@ std::vector> Index( std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), /*Persistent=*/true, /*ResourceDir=*/"", /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, true); + /*CaptureDiagnostics=*/true, 0, false, false, + /*UserFilesAreVolatile=*/true); }; if (!RunSafely(CRC, compile)) { LOG_S(ERROR) << "clang crashed for " << file; diff --git a/src/project.cc b/src/project.cc index 7140e0827..da24705cd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -17,11 +17,9 @@ using namespace ccls; #include #include #include -#include #include using namespace clang; using namespace llvm; -using namespace llvm::opt; #include @@ -156,7 +154,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) + if (!sys::path::is_absolute(HeaderOpts.ResourceDir) && + HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); From 814f054e6ede5800c43817fae6421414448459f6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 11:27:59 -0700 Subject: [PATCH 148/378] Misc improvement to indexer * Make CXXConstructor span one more column to left/right * Use OrigD to collect Decl::Record members * Better comment parsing * Limit lines of initializers and macro definition to 3 * Attribute macro arg uses to spelling loc * Remove FuncDef::declaring_type --- index_tests/constructors/constructor.cc | 4 +- index_tests/constructors/destructor.cc | 5 +- .../constructors/implicit_constructor.cc | 4 +- index_tests/constructors/invalid_reference.cc | 1 - index_tests/constructors/make_functions.cc | 10 -- index_tests/declaration_vs_definition/func.cc | 1 - .../func_associated_function_params.cc | 1 - .../declaration_vs_definition/method.cc | 3 - index_tests/function_declaration.cc | 1 - .../function_declaration_definition.cc | 1 - index_tests/function_definition.cc | 1 - index_tests/inheritance/function_override.cc | 2 - .../inheritance/interface_pure_virtual.cc | 1 - .../inheritance/multiple_base_functions.cc | 3 - index_tests/lambdas/lambda.cc | 4 +- index_tests/macros/complex.cc | 6 +- index_tests/macros/foo.cc | 5 +- index_tests/method_declaration.cc | 1 - index_tests/method_definition.cc | 1 - index_tests/method_inline_declaration.cc | 1 - index_tests/multi_file/impl.cc | 3 - index_tests/multi_file/simple_impl.cc | 3 - index_tests/multi_file/static.cc | 2 - index_tests/namespaces/anonymous_function.cc | 1 - .../namespaces/function_declaration.cc | 1 - index_tests/namespaces/function_definition.cc | 1 - index_tests/namespaces/method_declaration.cc | 1 - index_tests/namespaces/method_definition.cc | 1 - .../namespaces/method_inline_declaration.cc | 1 - index_tests/namespaces/namespace_alias.cc | 1 - index_tests/namespaces/namespace_reference.cc | 2 - index_tests/operators/operator.cc | 4 - .../outline/static_function_in_type.cc | 2 - .../func_specialized_template_param.cc | 1 - .../templates/member_ref_in_template.cc | 2 - ...ass_template_func_usage_folded_into_one.cc | 1 - index_tests/templates/specialization.cc | 4 - .../templates/specialized_func_definition.cc | 2 - ...mplate_class_func_usage_folded_into_one.cc | 1 - ...ass_template_func_usage_folded_into_one.cc | 1 - .../template_func_usage_folded_into_one.cc | 1 - index_tests/types/typedefs.cc | 1 - index_tests/unions/union_usage.cc | 1 - .../usage/func_called_from_constructor.cc | 2 - .../usage/func_called_from_macro_argument.cc | 4 +- .../usage/func_called_from_template.cc | 3 - .../usage/func_called_implicit_ctor.cc | 5 +- index_tests/usage/func_usage_addr_func.cc | 3 - index_tests/usage/func_usage_addr_method.cc | 2 - index_tests/usage/func_usage_call_func.cc | 2 - index_tests/usage/func_usage_call_method.cc | 2 - .../usage/func_usage_class_inline_var_def.cc | 1 - .../usage/func_usage_forward_decl_func.cc | 2 - .../usage/func_usage_forward_decl_method.cc | 2 - index_tests/usage/func_usage_template_func.cc | 2 - .../usage/type_usage_as_template_parameter.cc | 1 - ...ype_usage_as_template_parameter_complex.cc | 4 - index_tests/usage/type_usage_declare_local.cc | 1 - index_tests/usage/type_usage_declare_param.cc | 1 - .../type_usage_declare_param_prototype.cc | 1 - .../usage/type_usage_declare_param_unnamed.cc | 1 - .../usage/type_usage_declare_qualifiers.cc | 1 - .../usage/type_usage_on_return_type.cc | 5 - .../usage/type_usage_typedef_and_using.cc | 4 - index_tests/usage/type_usage_various.cc | 1 - index_tests/usage/usage_inside_of_call.cc | 3 - .../usage/usage_inside_of_call_simple.cc | 3 - index_tests/usage/var_usage_call_function.cc | 2 - index_tests/usage/var_usage_class_member.cc | 3 - .../usage/var_usage_class_member_static.cc | 2 - index_tests/usage/var_usage_extern.cc | 1 - index_tests/usage/var_usage_func_parameter.cc | 1 - index_tests/usage/var_usage_local.cc | 1 - index_tests/usage/var_usage_shadowed_local.cc | 1 - .../usage/var_usage_shadowed_parameter.cc | 1 - index_tests/usage/var_usage_static.cc | 1 - index_tests/vars/deduce_auto_type.cc | 1 - index_tests/vars/function_local.cc | 1 - index_tests/vars/function_param.cc | 1 - index_tests/vars/function_param_unnamed.cc | 1 - index_tests/vars/function_shadow_local.cc | 1 - index_tests/vars/function_shadow_param.cc | 1 - .../vars/type_instance_on_using_type.cc | 1 - src/clang_complete.cc | 7 +- src/indexer.cc | 91 +++++++++++-------- src/indexer.h | 4 - src/serializer.cc | 1 - 87 files changed, 66 insertions(+), 207 deletions(-) diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index fac49ff86..c3689b87e 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -23,11 +23,10 @@ void foo() { "declarations": [], "spell": "3:3-3:6|15041163540773201510|2|1026", "extent": "3:3-3:11|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|15041163540773201510|2|16420", "8:17-8:20|15041163540773201510|2|16420"], + "uses": ["7:7-7:8|15041163540773201510|2|16676", "8:17-8:20|15041163540773201510|2|16676"], "callees": [] }, { "usr": 4259594751088586730, @@ -39,7 +38,6 @@ void foo() { "declarations": [], "spell": "6:6-6:9|0|1|2", "extent": "6:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [10983126130596230582, 17165811951126099095], diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index c144373d1..0c4a0c929 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -28,11 +28,10 @@ void foo() { "declarations": [], "spell": "3:3-3:6|15041163540773201510|2|1026", "extent": "3:3-3:11|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|15041163540773201510|2|16420"], + "uses": ["8:7-8:8|15041163540773201510|2|16676"], "callees": [] }, { "usr": 4259594751088586730, @@ -44,7 +43,6 @@ void foo() { "declarations": [], "spell": "7:6-7:9|0|1|2", "extent": "7:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [1893354193220338759], @@ -60,7 +58,6 @@ void foo() { "declarations": [], "spell": "4:3-4:4|15041163540773201510|2|1026", "extent": "4:3-4:12|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index 3b81b4778..9d934c972 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -22,7 +22,6 @@ void Make() { "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [449111627548814328, 17097499197730163115], @@ -38,11 +37,10 @@ void Make() { "declarations": [], "spell": "2:3-2:7|13487927231218873822|2|1026", "extent": "2:3-2:12|13487927231218873822|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|13487927231218873822|2|16420", "7:15-7:19|13487927231218873822|2|16420"], + "uses": ["6:8-6:12|13487927231218873822|2|16676", "7:15-7:19|13487927231218873822|2|16676"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index 283104433..b1ea44652 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -22,7 +22,6 @@ Foo::Foo() {} "declarations": [], "spell": "4:6-4:9|15041163540773201510|2|1026", "extent": "4:1-4:11|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index e5631096f..04699b41f 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -38,7 +38,6 @@ OUTPUT: make_functions.h "declarations": [], "spell": "7:3-7:9|14935975554338052500|2|1026", "extent": "7:3-7:32|14935975554338052500|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -54,7 +53,6 @@ OUTPUT: make_functions.h "declarations": [], "spell": "6:3-6:9|14935975554338052500|2|1026", "extent": "6:3-6:17|14935975554338052500|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -70,7 +68,6 @@ OUTPUT: make_functions.h "declarations": [], "spell": "5:3-5:9|14935975554338052500|2|1026", "extent": "5:3-5:14|14935975554338052500|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -86,7 +83,6 @@ OUTPUT: make_functions.h "declarations": [], "spell": "8:3-8:9|14935975554338052500|2|1026", "extent": "8:3-8:30|14935975554338052500|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -145,7 +141,6 @@ OUTPUT: make_functions.cc "kind": 0, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [2555873744476712860, 2555873744476712860, 2555873744476712860], @@ -161,7 +156,6 @@ OUTPUT: make_functions.cc "declarations": [], "spell": "9:4-9:15|0|1|2", "extent": "9:1-11:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [3908732770590594660], @@ -177,7 +171,6 @@ OUTPUT: make_functions.cc "declarations": [], "spell": "13:6-13:14|0|1|2", "extent": "13:1-18:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -191,7 +184,6 @@ OUTPUT: make_functions.cc "kind": 0, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [16395392342608151399], @@ -205,7 +197,6 @@ OUTPUT: make_functions.cc "kind": 0, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [180270746871803062, 180270746871803062, 180270746871803062], @@ -221,7 +212,6 @@ OUTPUT: make_functions.cc "declarations": [], "spell": "4:4-4:14|0|1|2", "extent": "4:1-6:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [8463700030555379526], diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index 10f53f1ec..718eaffab 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -19,7 +19,6 @@ void foo(); "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:14|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index bbc66a25f..a7cc5e0bc 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -19,7 +19,6 @@ int foo(int a, int b) { return 0; } "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], "spell": "5:5-5:8|0|1|2", "extent": "5:1-5:36|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [14555488990109936920, 10963664335057337329], diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 92edeb9be..c51fd99e9 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -19,7 +19,6 @@ void Foo::def() {} "kind": 6, "storage": 0, "declarations": ["2:8-2:16|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -33,7 +32,6 @@ void Foo::def() {} "kind": 6, "storage": 0, "declarations": ["3:16-3:27|15041163540773201510|2|1089"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -49,7 +47,6 @@ void Foo::def() {} "declarations": ["4:8-4:11|15041163540773201510|2|1025"], "spell": "7:11-7:14|15041163540773201510|2|1026", "extent": "7:1-7:19|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index 8c012d02d..2d23e7d97 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -13,7 +13,6 @@ void foo(int a, int b); "kind": 12, "storage": 0, "declarations": ["1:6-1:9|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index 67bbfe771..c35a6f770 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -17,7 +17,6 @@ void foo() {} "declarations": ["1:6-1:9|0|1|1"], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:14|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index 9a58dfaf4..1662c48a8 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -15,7 +15,6 @@ void foo() {} "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-1:14|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 94348b67b..518fb3ba2 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -20,7 +20,6 @@ class Derived : public Root { "declarations": [], "spell": "5:8-5:11|10963370434658308541|2|5186", "extent": "5:3-5:25|10963370434658308541|2|0", - "declaring_type": 0, "bases": [9948027785633571339], "derived": [], "vars": [], @@ -34,7 +33,6 @@ class Derived : public Root { "kind": 6, "storage": 0, "declarations": ["2:16-2:19|3897841498936210886|2|1089"], - "declaring_type": 0, "bases": [], "derived": [6666242542855173890], "vars": [], diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index b68b4d289..d002b0bd2 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -15,7 +15,6 @@ class IFoo { "kind": 6, "storage": 0, "declarations": ["2:16-2:19|9949214233977131946|2|1089"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 6b128d747..3ae72322e 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -23,7 +23,6 @@ struct Derived : Base0, Base1 { "declarations": [], "spell": "5:11-5:12|15826803741381445676|2|1090", "extent": "5:3-5:23|15826803741381445676|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -39,7 +38,6 @@ struct Derived : Base0, Base1 { "declarations": [], "spell": "8:3-8:4|10963370434658308541|2|5186", "extent": "8:3-8:26|10963370434658308541|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -55,7 +53,6 @@ struct Derived : Base0, Base1 { "declarations": [], "spell": "2:11-2:12|11628904180681204356|2|1090", "extent": "2:3-2:23|11628904180681204356|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 983889e99..f95792761 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -26,7 +26,6 @@ void foo() { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-12:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [12666114896600231317, 2981279427664991319], @@ -40,7 +39,6 @@ void foo() { "kind": 6, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -85,7 +83,7 @@ void foo() { "detailed_name": "(lambda) dosomething", "qual_name_offset": 9, "short_name": "dosomething", - "hover": "(lambda) dosomething = [&x](int y) {\n ++x;\n ++y;\n }", + "hover": "(lambda) dosomething", "declarations": [], "spell": "4:8-4:19|4259594751088586730|3|2", "extent": "4:3-7:4|4259594751088586730|3|0", diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 0fed44b41..080e247f9 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -26,7 +26,6 @@ FOO(make1(), make2); "declarations": ["12:1-12:20|0|1|1"], "spell": "12:1-12:20|0|1|2", "extent": "1:1-1:1|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -42,11 +41,10 @@ FOO(make1(), make2); "declarations": [], "spell": "6:5-6:10|0|1|2", "extent": "6:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["12:1-12:20|0|1|16420", "12:5-12:10|0|1|64|0"], + "uses": ["12:5-12:10|0|1|16420"], "callees": [] }], "usr2type": [{ @@ -75,7 +73,7 @@ FOO(make1(), make2); "spell": "9:11-9:16|0|1|2", "extent": "9:1-9:20|0|1|0", "type": 53, - "uses": ["12:1-12:20|0|1|12", "12:14-12:19|0|1|64|0"], + "uses": ["12:14-12:19|0|1|12"], "kind": 13, "storage": 0 }, { diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index ddc7a7049..7e5f159da 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -20,9 +20,8 @@ int x = A; "kind": 9, "storage": 0, "declarations": [], - "spell": "5:3-5:16|15041163540773201510|2|1026", + "spell": "5:12-5:15|15041163540773201510|2|1026", "extent": "1:1-1:1|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -60,7 +59,7 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:3-5:16|0|1|4", "5:12-5:15|0|1|64|0"] + "uses": ["5:12-5:15|0|1|4"] }], "usr2var": [{ "usr": 1569772797058982873, diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index 7d00e90ee..00edb4dee 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -19,7 +19,6 @@ class Foo { "kind": 6, "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 3f129e24c..083dbcb33 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -19,7 +19,6 @@ void Foo::foo() const {} "declarations": ["2:8-2:11|15041163540773201510|2|1025"], "spell": "5:11-5:14|15041163540773201510|2|1026", "extent": "5:1-5:25|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index 601d5d313..64ced29b4 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -17,7 +17,6 @@ class Foo { "declarations": [], "spell": "2:8-2:11|15041163540773201510|2|1026", "extent": "2:3-2:16|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 369504355..db74ff21e 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -19,7 +19,6 @@ OUTPUT: header.h "declarations": [], "spell": "10:6-10:10|0|1|2", "extent": "10:1-10:15|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -209,7 +208,6 @@ OUTPUT: impl.cc "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -223,7 +221,6 @@ OUTPUT: impl.cc "kind": 12, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index fa2b9fb11..5109c2a20 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -17,7 +17,6 @@ OUTPUT: simple_header.h "kind": 12, "storage": 0, "declarations": ["3:6-3:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -44,7 +43,6 @@ OUTPUT: simple_impl.cc "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -58,7 +56,6 @@ OUTPUT: simple_impl.cc "kind": 12, "storage": 0, "declarations": [], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 9ef71ea26..c0a7267a2 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -15,7 +15,6 @@ OUTPUT: static.h "kind": 6, "storage": 0, "declarations": ["4:15-4:33|9411323049603567600|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -59,7 +58,6 @@ OUTPUT: static.cc "declarations": [], "spell": "3:14-3:32|9411323049603567600|2|1026", "extent": "3:1-3:37|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index c07d54abe..eb89d959b 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -15,7 +15,6 @@ void foo(); "kind": 12, "storage": 0, "declarations": ["2:6-2:9|7144845543074395457|2|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index f73d3e180..2438c99c5 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -15,7 +15,6 @@ void foo(int a, int b); "kind": 12, "storage": 0, "declarations": ["2:6-2:9|2029211996748007610|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index a003e49fd..7afe9d29e 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -17,7 +17,6 @@ void foo() {} "declarations": [], "spell": "2:6-2:9|2029211996748007610|2|1026", "extent": "2:1-2:14|2029211996748007610|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index 09a336984..48a8456e8 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -17,7 +17,6 @@ class Foo { "kind": 6, "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index e83677296..3774972c6 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -21,7 +21,6 @@ void Foo::foo() {} "declarations": ["3:8-3:11|4508214972876735896|2|1025"], "spell": "6:11-6:14|4508214972876735896|2|1026", "extent": "6:1-6:19|2029211996748007610|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index bd8dda460..55c951185 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -19,7 +19,6 @@ class Foo { "declarations": [], "spell": "3:8-3:11|4508214972876735896|2|1026", "extent": "3:3-3:16|4508214972876735896|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index f42a38b03..46f0983ee 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -28,7 +28,6 @@ void func() { "declarations": [], "spell": "11:6-11:10|0|1|2", "extent": "11:1-14:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [6030927277961448585, 7657277353101371136], diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 815133e20..758c39e76 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -24,7 +24,6 @@ void Runner() { "declarations": [], "spell": "6:6-6:12|0|1|2", "extent": "6:1-10:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -40,7 +39,6 @@ void Runner() { "declarations": [], "spell": "3:8-3:14|11072669167287398027|2|1026", "extent": "3:3-3:24|11072669167287398027|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [3649375698083002347], diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 2a5d10449..e05be650a 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -19,7 +19,6 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": ["3:8-3:16|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -33,7 +32,6 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": ["4:7-4:15|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -49,7 +47,6 @@ Foo &operator += (const Foo&, const int&); "declarations": [], "spell": "2:8-2:16|15041163540773201510|2|1026", "extent": "2:3-2:27|15041163540773201510|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -63,7 +60,6 @@ Foo &operator += (const Foo&, const int&); "kind": 12, "storage": 0, "declarations": ["7:6-7:14|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 9f5f84b67..c9caa3bb4 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -19,7 +19,6 @@ OUTPUT: static_function_in_type.h "kind": 6, "storage": 0, "declarations": ["6:15-6:23|17262466801709381811|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -94,7 +93,6 @@ OUTPUT: static_function_in_type.cc "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|1026", "extent": "5:1-6:2|11072669167287398027|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [13569879755236306838], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 4945caf43..6a3dc6311 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -22,7 +22,6 @@ void Foo::Bar(Template&) {} "declarations": ["5:8-5:11|15041163540773201510|2|1025"], "spell": "8:11-8:14|15041163540773201510|2|1026", "extent": "8:1-8:36|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index db98e0c0b..e4b593918 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -35,7 +35,6 @@ void foo() { "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-8:11|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -49,7 +48,6 @@ void foo() { "kind": 6, "storage": 0, "declarations": ["4:8-4:11|8402783583255987702|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 55452c0b9..ba245e898 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -26,7 +26,6 @@ namespace ns { "declarations": [], "spell": "5:16-5:19|14042997404480181958|2|1026", "extent": "5:5-7:6|14042997404480181958|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 3c92252d7..aba5f2c99 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -55,7 +55,6 @@ void foo(float Value); "kind": 12, "storage": 0, "declarations": ["43:6-43:9|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -69,7 +68,6 @@ void foo(float Value); "kind": 6, "storage": 0, "declarations": ["27:8-27:13|1663022413889915338|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -85,7 +83,6 @@ void foo(float Value); "declarations": [], "spell": "39:6-39:9|0|1|2", "extent": "39:1-39:21|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [17826688417349629938], @@ -99,7 +96,6 @@ void foo(float Value); "kind": 6, "storage": 0, "declarations": ["13:8-13:13|7440942986741176606|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 1add46b70..68ce9f8b2 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -32,7 +32,6 @@ void Template::Foo() {} "declarations": [], "spell": "10:22-10:25|17649312483543982122|2|1026", "extent": "9:1-10:30|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -48,7 +47,6 @@ void Template::Foo() {} "declarations": ["3:8-3:11|17107291254533526269|2|1025"], "spell": "7:19-7:22|17107291254533526269|2|1026", "extent": "6:1-7:24|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 741c23562..0f59f6737 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -23,7 +23,6 @@ int b = Foo::foo(); "declarations": [], "spell": "3:14-3:17|10528472276654770367|2|1026", "extent": "3:3-5:4|10528472276654770367|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index e969f6500..034b6ef34 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -24,7 +24,6 @@ int b = Foo::foo(); "declarations": [], "spell": "4:14-4:17|10528472276654770367|2|1026", "extent": "4:3-6:4|10528472276654770367|2|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index aa6b9d0b7..8fccd50a0 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -24,7 +24,6 @@ int b = foo(); "declarations": [], "spell": "2:12-2:15|0|1|2", "extent": "2:1-4:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index 96407a128..38505c299 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -14,7 +14,6 @@ static func g; "kind": 12, "storage": 0, "declarations": ["2:13-2:14|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index ee53d3fb4..eadb06c71 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -26,7 +26,6 @@ void act(Foo*) { "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-10:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 3a874534f..9f43fd00d 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -23,7 +23,6 @@ Foo::Foo() { "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -39,7 +38,6 @@ Foo::Foo() { "declarations": ["4:3-4:6|15041163540773201510|2|1025"], "spell": "7:6-7:9|15041163540773201510|2|1026", "extent": "7:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 42e26b30d..9ceebb33e 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -19,11 +19,10 @@ void caller() { "kind": 12, "storage": 0, "declarations": ["3:6-3:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:33|0|1|16420", "6:14-6:20|0|1|64|0"], + "uses": ["6:14-6:20|0|1|16420"], "callees": [] }, { "usr": 11404881820527069090, @@ -35,7 +34,6 @@ void caller() { "declarations": [], "spell": "5:6-5:12|0|1|2", "extent": "5:1-7:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 19a12e696..34338f343 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -24,7 +24,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["1:6-1:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -40,7 +39,6 @@ void foo() { "declarations": [], "spell": "8:6-8:9|0|1|2", "extent": "8:1-10:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -56,7 +54,6 @@ void foo() { "declarations": [], "spell": "4:6-4:12|0|1|2", "extent": "4:1-6:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index 78ef5d0a1..372c2f127 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -23,7 +23,6 @@ Wrapper caller() { "declarations": [], "spell": "5:5-5:11|0|1|2", "extent": "5:1-5:27|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -37,11 +36,10 @@ Wrapper caller() { "kind": 9, "storage": 0, "declarations": ["2:3-2:10|13611487872560323389|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|13611487872560323389|2|16420"], + "uses": ["8:10-8:16|13611487872560323389|2|16676"], "callees": [] }, { "usr": 11404881820527069090, @@ -53,7 +51,6 @@ Wrapper caller() { "declarations": [], "spell": "7:9-7:15|0|1|2", "extent": "7:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index f6fa7e868..3d163e139 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -22,7 +22,6 @@ void user() { "declarations": [], "spell": "3:6-3:10|0|1|2", "extent": "3:1-3:15|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -38,7 +37,6 @@ void user() { "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [16088407831770615719], @@ -54,7 +52,6 @@ void user() { "declarations": [], "spell": "1:6-1:13|0|1|2", "extent": "1:1-1:28|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index aec722252..1953c9cc7 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -22,7 +22,6 @@ void user() { "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-7:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [4636142131003982569], @@ -36,7 +35,6 @@ void user() { "kind": 6, "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index acf35619c..7552f625c 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -18,7 +18,6 @@ void caller() { "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -34,7 +33,6 @@ void caller() { "declarations": [], "spell": "2:6-2:12|0|1|2", "extent": "2:1-4:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 9cd1fa562..a727815e6 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -22,7 +22,6 @@ void user() { "declarations": [], "spell": "5:6-5:10|0|1|2", "extent": "5:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [14045150712868309451], @@ -36,7 +35,6 @@ void user() { "kind": 6, "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index dbbd7288a..fb529c480 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -21,7 +21,6 @@ class Foo { "declarations": [], "spell": "1:12-1:18|0|1|2", "extent": "1:1-3:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 5796e6401..503465bc4 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -16,7 +16,6 @@ void usage() { "kind": 12, "storage": 0, "declarations": ["1:6-1:9|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -32,7 +31,6 @@ void usage() { "declarations": [], "spell": "3:6-3:11|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 19fa07184..2fbc2f9c9 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -21,7 +21,6 @@ void usage() { "declarations": [], "spell": "5:6-5:11|0|1|2", "extent": "5:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [16229832321010999607], @@ -35,7 +34,6 @@ void usage() { "kind": 6, "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1025"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 40952f828..a70dcf5f2 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -21,7 +21,6 @@ void foo() { "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-7:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -35,7 +34,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["2:6-2:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 129c33f58..da797cfaf 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -25,7 +25,6 @@ unique_ptr* return_type() { "declarations": [], "spell": "9:16-9:27|0|1|2", "extent": "9:1-12:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [3364438781074774169], diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 1173d954b..97c57d7c4 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -93,7 +93,6 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": [], "spell": "33:37-33:51|0|1|2", "extent": "33:1-33:92|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -109,7 +108,6 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": [], "spell": "40:6-40:20|0|1|2", "extent": "40:1-40:28|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -125,7 +123,6 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": ["65:23-65:26|15041163540773201510|2|1025"], "spell": "79:26-79:29|15041163540773201510|2|1026", "extent": "79:1-79:51|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -141,7 +138,6 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": [], "spell": "53:6-53:11|0|1|2", "extent": "53:1-55:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [500112618220246], diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 09af0afe9..848ab490d 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -21,7 +21,6 @@ void Foo() { "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-7:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [16374832544037266261, 2580122838476012357], diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 25c07db28..4495b5ede 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -18,7 +18,6 @@ void foo(ForwardType* f, ImplementedType a) {} "declarations": [], "spell": "4:6-4:9|0|1|2", "extent": "4:1-4:47|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [13058491096576226774, 11055777568039014776], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 1605291d0..cee275579 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -23,7 +23,6 @@ void foo(Foo* f, Foo*) {} "declarations": ["3:6-3:9|0|1|1"], "spell": "4:6-4:9|0|1|2", "extent": "4:1-4:26|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [13823260660189154978], diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index f9e6096d3..f0cda5364 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -15,7 +15,6 @@ void foo(ForwardType*) {} "declarations": [], "spell": "2:6-2:9|0|1|2", "extent": "2:1-2:26|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 17ac5ceaf..e5c12bf9a 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -21,7 +21,6 @@ void foo(Type& a0, const Type& a1) { "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index c1b59773e..bf825b69f 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -32,7 +32,6 @@ static Type* bar() { return nullptr; } "declarations": ["9:8-9:13|15041163540773201510|2|1025"], "spell": "13:11-13:16|15041163540773201510|2|1026", "extent": "13:1-13:21|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -48,7 +47,6 @@ static Type* bar() { return nullptr; } "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "5:7-5:10|0|1|2", "extent": "5:1-5:32|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -62,7 +60,6 @@ static Type* bar() { return nullptr; } "kind": 12, "storage": 0, "declarations": ["15:20-15:28|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -78,7 +75,6 @@ static Type* bar() { return nullptr; } "declarations": ["8:9-8:12|15041163540773201510|2|1025"], "spell": "12:12-12:15|15041163540773201510|2|1026", "extent": "12:1-12:40|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -94,7 +90,6 @@ static Type* bar() { return nullptr; } "declarations": ["17:14-17:17|0|1|1"], "spell": "18:14-18:17|0|1|2", "extent": "18:1-18:39|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index d3c6dc4ff..ded74f43e 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -24,7 +24,6 @@ void accept3(Foo3*) {} "declarations": [], "spell": "8:6-8:13|0|1|2", "extent": "8:1-8:23|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -40,7 +39,6 @@ void accept3(Foo3*) {} "declarations": [], "spell": "7:6-7:12|0|1|2", "extent": "7:1-7:21|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -56,7 +54,6 @@ void accept3(Foo3*) {} "declarations": [], "spell": "9:6-9:13|0|1|2", "extent": "9:1-9:23|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -72,7 +69,6 @@ void accept3(Foo3*) {} "declarations": [], "spell": "10:6-10:13|0|1|2", "extent": "10:1-10:23|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index c9934391d..c313d4361 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -24,7 +24,6 @@ extern Foo foo; "declarations": ["2:8-2:12|15041163540773201510|2|1025"], "spell": "5:11-5:15|15041163540773201510|2|1026", "extent": "5:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [16380484338511689669], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index bf28a40e1..78c2c340b 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -29,7 +29,6 @@ void foo() { "declarations": [], "spell": "12:6-12:9|0|1|2", "extent": "12:1-15:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [8039186520399841081], @@ -43,7 +42,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["3:5-3:8|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -57,7 +55,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["1:6-1:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index dfde1cb31..0dc7dcd85 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -21,7 +21,6 @@ void foo() { "declarations": [], "spell": "5:6-5:9|0|1|2", "extent": "5:1-7:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -37,7 +36,6 @@ void foo() { "declarations": [], "spell": "3:5-3:8|0|1|2", "extent": "3:1-3:24|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -51,7 +49,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["1:6-1:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index f549869a7..ee39a73ca 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -22,7 +22,6 @@ void caller() { "declarations": [], "spell": "1:6-1:12|0|1|2", "extent": "1:1-1:17|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -38,7 +37,6 @@ void caller() { "declarations": [], "spell": "3:6-3:12|0|1|2", "extent": "3:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [9121974011454213596], diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index fd6229a93..0433edb32 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -32,7 +32,6 @@ void foo() { "declarations": [], "spell": "10:6-10:9|0|1|2", "extent": "10:1-18:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [14669930844300034456], @@ -46,7 +45,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["8:6-8:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -60,7 +58,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["7:6-7:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 869fe29d3..28e6da571 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -23,7 +23,6 @@ void foo() { "declarations": [], "spell": "7:6-7:9|0|1|2", "extent": "7:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], @@ -37,7 +36,6 @@ void foo() { "kind": 12, "storage": 0, "declarations": ["5:6-5:12|0|1|1"], - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 2dbbf1c28..fe5c928f7 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -18,7 +18,6 @@ void foo() { "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 278bdc7eb..9bfd50aa2 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -16,7 +16,6 @@ void foo(int a) { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-3:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [10063793875496522529], diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 7adc7df43..f6eb9d022 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -17,7 +17,6 @@ void foo() { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-4:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [14014650769929566957], diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 8c8dc547c..d0f9a35fc 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -22,7 +22,6 @@ void foo() { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [13311055950748663970, 14036425367303419504], diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 6a6084d6d..8a99171d5 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -22,7 +22,6 @@ void foo(int a) { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-8:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [11608231465452906059, 6997229590862003559], diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index aaee22260..873fc5dbd 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -19,7 +19,6 @@ void foo() { "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 8c9460a55..2212b9afe 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -19,7 +19,6 @@ void f() { "declarations": [], "spell": "2:6-2:7|0|1|2", "extent": "2:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [10601729374837386290, 18422884837902130475], diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 3cca9f453..8090f1cdf 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -19,7 +19,6 @@ void foo() { "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [13198746475679542317], diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 1b7da61d2..96a844ad0 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -17,7 +17,6 @@ void foo(Foo* p0, Foo* p1) {} "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-3:30|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [8730439006497971620, 2525014371090380500], diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index 99b79d879..6ecfe2fa4 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -14,7 +14,6 @@ void foo(int, int) {} "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-1:22|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [], diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 5cb9abecd..27c7b00be 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -22,7 +22,6 @@ void foo() { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-9:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [1894874819807168345, 4508045017817092115], diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index 9467753a3..f2d522113 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -16,7 +16,6 @@ void foo(int p) { "declarations": [], "spell": "1:6-1:9|0|1|2", "extent": "1:1-3:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [5875271969926422921, 11404600766177939811], diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index d35c568df..229959d52 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -21,7 +21,6 @@ void Foo() { "declarations": [], "spell": "3:6-3:9|0|1|2", "extent": "3:1-5:2|0|1|0", - "declaring_type": 0, "bases": [], "derived": [], "vars": [6975456769752895964], diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 5328437ea..bbac2320a 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -505,10 +505,11 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { E = tu->Unit->stored_diag_end(); I != E; ++I) { FullSourceLoc FLoc = I->getLocation(); - const auto &SM = FLoc.getManager(); - - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(FLoc)); + if (!FLoc.isValid()) // why? + continue; + const FileEntry *FE = FLoc.getFileEntry(); if (!FE || FileName(*FE) != path) continue; + const auto &SM = FLoc.getManager(); SourceRange R; for (const auto &CR : I->getRanges()) { auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); diff --git a/src/indexer.cc b/src/indexer.cc index 24f601e36..1e310d527 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -30,6 +30,8 @@ using llvm::Timer; namespace { +constexpr int kInitializerMaxLines = 3; + struct IndexParam { std::unordered_map SeenUniqueID; std::unordered_map file_contents; @@ -327,7 +329,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (pad < 0) { // First line, detect the length of comment marker and put into |pad| const char *begin = p; - while (p < E && (*p == '/' || *p == '*')) + while (p < E && (*p == '/' || *p == '*' || *p == '-' || *p == '=')) p++; if (p < E && (*p == '<' || *p == '!')) p++; @@ -488,9 +490,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); - Twine T = - def.detailed_name + - (Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) : Twine(" = ", Buf)); + Twine T = Buf.count('\n') <= kInitializerMaxLines - 1 + ? def.detailed_name + (Buf.size() && Buf[0] == ':' + ? Twine(" ", Buf) + : Twine(" = ", Buf)) + : def.detailed_name; def.hover = def.storage == SC_Static && strncmp(def.detailed_name, "static ", 7) ? Intern(("static " + T).str()) @@ -568,7 +572,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { LocFID = SM.getFileID(P.first); FE = SM.getFileEntryForID(LocFID); #else - auto R = SM.getExpansionRange(Loc); + auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) + : SM.getExpansionRange(Loc); loc = FromTokenRange(SM, Lang, R.getAsRange()); LocFID = SM.getFileID(R.getBegin()); FE = SM.getFileEntryForID(LocFID); @@ -618,6 +623,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; case SymbolKind::Func: func = &db->ToFunc(usr); + // Span one more column to the left/right if D is CXXConstructor. + if (!is_def && !is_decl && D->getKind() == Decl::CXXConstructor) + role = Role(role | Role::Implicit); do_def_decl(func); if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); @@ -752,45 +760,46 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::Enum: type->def.kind = lsSymbolKind::Enum; break; - case Decl::CXXRecord: { - auto *RD = cast(D); - if (is_def && RD->hasDefinition()) { - for (const CXXBaseSpecifier &Base : RD->bases()) { - QualType T = Base.getType(); - const NamedDecl *BaseD = nullptr; - if (auto *TDT = T->getAs()) { - BaseD = TDT->getDecl(); - } else if (auto *TST = T->getAs()) { - BaseD = TST->getTemplateName().getAsTemplateDecl(); - } else if (auto *RT = T->getAs()) { - BaseD = RT->getDecl(); - } - if (BaseD) { - Usr usr1 = GetUsr(BaseD); - auto it = db->usr2type.find(usr1); - if (it != db->usr2type.end()) { - type->def.bases.push_back(usr1); - it->second.derived.push_back(usr); + case Decl::CXXRecord: + if (is_def) { + auto *RD = dyn_cast(OrigD); + if (RD && RD->hasDefinition()) { + for (const CXXBaseSpecifier &Base : RD->bases()) { + QualType T = Base.getType(); + const NamedDecl *BaseD = nullptr; + if (auto *TDT = T->getAs()) { + BaseD = TDT->getDecl(); + } else if (auto *TST = T->getAs()) { + BaseD = TST->getTemplateName().getAsTemplateDecl(); + } else if (auto *RT = T->getAs()) { + BaseD = RT->getDecl(); + } + if (BaseD) { + Usr usr1 = GetUsr(BaseD); + auto it = db->usr2type.find(usr1); + if (it != db->usr2type.end()) { + type->def.bases.push_back(usr1); + it->second.derived.push_back(usr); + } } } } } - } [[fallthrough]]; - case Decl::Record: { - auto *RD = cast(D); - // spec has no Union, use Class - type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct - : lsSymbolKind::Class; - if (is_def) { - bool can_get_offset = - RD->isCompleteDefinition() && !RD->isDependentType(); - for (FieldDecl *FD : RD->fields()) - type->def.vars.emplace_back( - GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); + case Decl::Record: + if (auto *RD = dyn_cast(OrigD)) { + // spec has no Union, use Class + type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct + : lsSymbolKind::Class; + if (is_def) { + bool can_get_offset = + RD->isCompleteDefinition() && !RD->isDependentType(); + for (FieldDecl *FD : RD->fields()) + type->def.vars.emplace_back( + GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); + } } break; - } case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: type->def.kind = lsSymbolKind::Class; @@ -960,7 +969,11 @@ class IndexPPCallbacks : public PPCallbacks { if (var.def.detailed_name[0] == '\0') { var.def.detailed_name = Intern(Name); var.def.short_name_size = Name.size(); - var.def.hover = Intern(Twine("#define ", GetSourceInRange(SM, Lang, R)).str()); + StringRef Buf = GetSourceInRange(SM, Lang, R); + var.def.hover = + Intern(Buf.count('\n') <= kInitializerMaxLines - 1 + ? Twine("#define ", GetSourceInRange(SM, Lang, R)).str() + : Twine("#define ", Name).str()); } } } @@ -1009,7 +1022,7 @@ class IndexFrontendAction : public ASTFrontendAction { } const int IndexFile::kMajorVersion = 17; -const int IndexFile::kMinorVersion = 0; +const int IndexFile::kMinorVersion = 1; IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) diff --git a/src/indexer.h b/src/indexer.h index 0e925e851..793b49cd8 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -104,8 +104,6 @@ struct FuncDef : NameMixin { // Functions that this function calls. std::vector callees; - // Type which declares this one (ie, it is a method) - Usr declaring_type = 0; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; @@ -125,7 +123,6 @@ MAKE_REFLECT_STRUCT(FuncDef, comments, spell, extent, - declaring_type, bases, vars, callees); @@ -202,7 +199,6 @@ struct VarDef : NameMixin { // Type of the variable. Usr type = 0; - // Function/type which declares this one. int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; diff --git a/src/serializer.cc b/src/serializer.cc index 8ab39b818..ba6086f48 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -292,7 +292,6 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("extent", value.def.extent); - REFLECT_MEMBER2("declaring_type", value.def.declaring_type); REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("derived", value.derived); REFLECT_MEMBER2("vars", value.def.vars); From 8912b003811a6cea060e029fd6511444e80e44cf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 18:26:48 -0700 Subject: [PATCH 149/378] Support BindingDecl and VarTemplate{,Partial}SpecializationDecl --- src/indexer.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 1e310d527..eac3b8bf4 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -125,6 +125,8 @@ SymbolKind GetSymbolKind(const Decl* D) { case Decl::ParmVar: case Decl::ImplicitParam: case Decl::Decomposition: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: case Decl::EnumConstant: case Decl::UnresolvedUsingValue: return SymbolKind::Var; @@ -457,6 +459,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { std::string_view qualified, IndexVar::Def &def) { QualType T; const Expr* init = nullptr; + bool binding = false; if (auto *VD = dyn_cast(D)) { T = VD->getType(); init = VD->getAnyInitializer(); @@ -464,9 +467,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { } else if (auto *FD = dyn_cast(D)) { T = FD->getType(); init = FD->getInClassInitializer(); + } else if (auto *BD = dyn_cast(D)) { + T = BD->getType(); + binding = true; } auto BT = GetBaseType(T, false); - if (!BT.isNull() && BT->getAs()) { + if (!BT.isNull() && (binding || BT->getAs())) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP = GetDefaultPolicy(); @@ -592,6 +598,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); + if (is_decl && D->getKind() == Decl::Binding) + is_def = true; IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; @@ -617,7 +625,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { switch (kind) { case SymbolKind::Invalid: LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " << info->qualified - << " in " << db->path << ":" << loc.start.line; + << " in " << db->path << ":" << loc.start.line + 1; return true; case SymbolKind::File: return true; @@ -886,6 +894,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { // ccls extension var->def.kind = lsSymbolKind::Parameter; break; + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: + var->def.kind = lsSymbolKind::Variable; + break; case Decl::EnumConstant: var->def.kind = lsSymbolKind::EnumMember; // TODO Pretty printer may print = From 344f00fbb2eb39a010b4dc19bdc012c475cf269c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 22:49:32 -0700 Subject: [PATCH 150/378] CrashRecoveryContext --- src/clang_complete.cc | 5 +++-- src/clang_tu.cc | 6 +++--- src/clang_tu.h | 10 ---------- src/indexer.cc | 2 +- src/main.cc | 5 ++++- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index bbac2320a..15b0761ee 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -5,11 +5,12 @@ #include "log.hh" #include "platform.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" +#include +#include #include #include #include +#include #include using namespace clang; using namespace llvm; diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 9e2b3ac28..64c4a4ece 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -100,7 +100,7 @@ std::unique_ptr ClangTranslationUnit::Create( /*UserFilesAreVolatile=*/true, false, ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); }; - if (!RunSafely(CRC, parse)) { + if (!CRC.RunSafely(parse)) { LOG_S(ERROR) << "clang crashed for " << filepath << "\n" << StringJoin(args, " ") + " -fsyntax-only"; @@ -116,7 +116,7 @@ std::unique_ptr ClangTranslationUnit::Create( int ClangTranslationUnit::Reparse(llvm::CrashRecoveryContext &CRC, const WorkingFiles::Snapshot &snapshot) { int ret = 1; - auto parse = [&]() { ret = Unit->Reparse(PCHCO, GetRemapped(snapshot)); }; - (void)RunSafely(CRC, parse); + (void)CRC.RunSafely( + [&]() { ret = Unit->Reparse(PCHCO, GetRemapped(snapshot)); }); return ret; } diff --git a/src/clang_tu.h b/src/clang_tu.h index 741d9a40f..a20ad74e7 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -22,16 +22,6 @@ Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &L clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); -template -bool RunSafely(llvm::CrashRecoveryContext &CRC, Fn &&fn) { - const char *env = getenv("CCLS_CRASH_RECOVERY"); - if (env && strcmp(env, "0") == 0) { - fn(); - return true; - } - return CRC.RunSafely(fn); -} - struct ClangTranslationUnit { static std::unique_ptr Create(const std::string &filepath, const std::vector &args, diff --git a/src/indexer.cc b/src/indexer.cc index eac3b8bf4..97ff2a937 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1166,7 +1166,7 @@ std::vector> Index( /*CaptureDiagnostics=*/true, 0, false, false, /*UserFilesAreVolatile=*/true); }; - if (!RunSafely(CRC, compile)) { + if (!CRC.RunSafely(compile)) { LOG_S(ERROR) << "clang crashed for " << file; return {}; } diff --git a/src/main.cc b/src/main.cc index 11c7bb243..63c5148b8 100644 --- a/src/main.cc +++ b/src/main.cc @@ -8,6 +8,7 @@ using namespace ccls; #include +#include #include #include #include @@ -55,7 +56,9 @@ int main(int argc, char** argv) { } pipeline::Init(); - idx::IndexInit(); + const char *env = getenv("CCLS_CRASH_RECOVERY"); + if (!env || strcmp(env, "0") != 0) + CrashRecoveryContext::Enable(); bool language_server = true; From 73ac788f9e94c0b2835240c2579e91cef98afc8f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 21:01:10 -0700 Subject: [PATCH 151/378] Remove libclang --- cmake/FindClang.cmake | 3 +-- src/indexer.cc | 8 -------- src/indexer.h | 2 -- src/project.cc | 3 +-- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index fe44ece19..87ab72b54 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -68,9 +68,8 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE Clang_RESOURCE_DIR Clang_VERSION LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) -_Clang_find_library(Clang_LIBRARY clang) +_Clang_find_library(Clang_LIBRARY clangIndex) _Clang_find_add_library(clangTooling) -_Clang_find_add_library(clangIndex) _Clang_find_add_library(clangFrontend) _Clang_find_add_library(clangParse) _Clang_find_add_library(clangSerialization) diff --git a/src/indexer.cc b/src/indexer.cc index 97ff2a937..1ff32a1fc 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -6,7 +6,6 @@ #include "serializer.h" using ccls::Intern; -#include #include #include #include @@ -1086,13 +1085,6 @@ void Uniquify(std::vector& uses) { namespace ccls::idx { -void IndexInit() { - // This calls llvm::InitializeAllTargets() ... for us, we would otherwise link - // all target libraries. - CXIndex CXIdx = clang_createIndex(0, 0); - clang_disposeIndex(CXIdx); -} - std::vector> Index( VFS* vfs, const std::string& opt_wdir, diff --git a/src/indexer.h b/src/indexer.h index 793b49cd8..99fbc9212 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -295,8 +295,6 @@ struct IndexFile { }; namespace ccls::idx { -void IndexInit(); - std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/project.cc b/src/project.cc index da24705cd..2777634c8 100644 --- a/src/project.cc +++ b/src/project.cc @@ -154,8 +154,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - if (!sys::path::is_absolute(HeaderOpts.ResourceDir) && - HeaderOpts.UseBuiltinIncludes) + if (!sys::fs::exists(HeaderOpts.ResourceDir) && HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); From af54645e5e67e9a36add16c5e041800dee3e3199 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 16 Jul 2018 09:49:32 -0700 Subject: [PATCH 152/378] Fix spell for clang < 7 --- src/indexer.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 1ff32a1fc..7f8300f05 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -572,17 +572,20 @@ class IndexDataConsumer : public index::IndexDataConsumer { const FileEntry *FE; Range loc; #if LLVM_VERSION_MAJOR < 7 - auto P = SM.getExpansionRange(Loc); - loc = FromCharRange(SM, Ctx->getLangOpts(), SourceRange(P.first, P.second)); - LocFID = SM.getFileID(P.first); - FE = SM.getFileEntryForID(LocFID); + CharSourceRange R; + if (SM.isMacroArgExpansion(Loc)) + R = CharSourceRange::getTokenRange(Spell); + else { + auto P = SM.getExpansionRange(Loc); + R = CharSourceRange::getTokenRange(P.first, P.second); + } #else auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) : SM.getExpansionRange(Loc); +#endif loc = FromTokenRange(SM, Lang, R.getAsRange()); LocFID = SM.getFileID(R.getBegin()); FE = SM.getFileEntryForID(LocFID); -#endif if (!FE) return true; IndexFile *db = param.ConsumeFile(*FE); From 0732d37817a97a53708a0e598aae3738d5ed03ec Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 16 Jul 2018 23:22:34 -0700 Subject: [PATCH 153/378] Better bases/derived and initializer --- src/clang_complete.cc | 2 +- src/indexer.cc | 64 +++++++++++++++++++------------------------ src/project.cc | 4 +-- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 15b0761ee..1fa09840b 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -329,7 +329,7 @@ class CaptureCompletionResults : public CodeCompleteConsumer { ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) ls_items[j].insertText += "$0"; ls_items[j].priority_ = GetCompletionPriority( - *CCS, Results[i].CursorKind, ls_items[i].filterText); + *CCS, Results[i].CursorKind, ls_items[j].filterText); } } else { bool do_insert = true; diff --git a/src/indexer.cc b/src/indexer.cc index 7f8300f05..c8a00bd53 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -492,7 +492,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { const LangOptions& Lang = Ctx->getLangOpts(); SourceRange R = init->getSourceRange(); SourceLocation L = D->getLocation(); - if (!SM.isBeforeInTranslationUnit(L, R.getBegin())) + if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); Twine T = Buf.count('\n') <= kInitializerMaxLines - 1 @@ -729,14 +729,23 @@ class IndexDataConsumer : public index::IndexDataConsumer { switch (D->getKind()) { case Decl::Namespace: type->def.kind = lsSymbolKind::Namespace; + if (OrigD->isFirstDecl()) { + auto *ND = cast(OrigD); + auto *ND1 = cast(ND->getParent()); + if (isa(ND1)) { + Usr usr1 = GetUsr(ND1); + type->def.bases.push_back(usr1); + db->ToType(usr1).derived.push_back(usr); + } + } break; case Decl::NamespaceAlias: { type->def.kind = lsSymbolKind::TypeAlias; - auto* NAD = cast(D); - if (const NamespaceDecl* ND = NAD->getNamespace()) { + auto *NAD = cast(D); + if (const NamespaceDecl *ND = NAD->getNamespace()) { Usr usr1 = GetUsr(ND); - if (db->usr2type.count(usr1)) - type->def.alias_of = usr1; + type->def.alias_of = usr1; + (void)db->ToType(usr1); } break; } @@ -786,11 +795,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { } if (BaseD) { Usr usr1 = GetUsr(BaseD); - auto it = db->usr2type.find(usr1); - if (it != db->usr2type.end()) { - type->def.bases.push_back(usr1); - it->second.derived.push_back(usr); - } + type->def.bases.push_back(usr1); + db->ToType(usr1).derived.push_back(usr); } } } @@ -831,11 +837,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { D1 = RD->getInstantiatedFromMemberClass(); if (D1) { Usr usr1 = GetUsr(D1); - auto it = db->usr2type.find(usr1); - if (it != db->usr2type.end()) { - type->def.bases.push_back(usr1); - it->second.derived.push_back(usr); - } + type->def.bases.push_back(usr1); + db->ToType(usr1).derived.push_back(usr); } } } @@ -871,11 +874,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { Ctx->getOverriddenMethods(ND, OverDecls); for (const auto* ND1 : OverDecls) { Usr usr1 = GetUsr(ND1); - auto it = db->usr2func.find(usr1); - if (it != db->usr2func.end()) { - func->def.bases.push_back(usr1); - it->second.derived.push_back(usr); - } + func->def.bases.push_back(usr1); + db->ToFunc(usr1).derived.push_back(usr); } } } @@ -1067,26 +1067,18 @@ std::string IndexFile::ToString() { return ccls::Serialize(SerializeFormat::Json, *this); } -void Uniquify(std::vector& usrs) { - std::unordered_set seen; - size_t n = 0; - for (size_t i = 0; i < usrs.size(); i++) - if (seen.insert(usrs[i]).second) - usrs[n++] = usrs[i]; - usrs.resize(n); -} +MAKE_HASHABLE(Use, t.range, t.file_id) -void Uniquify(std::vector& uses) { - std::unordered_set seen; +template +void Uniquify(std::vector& a) { + std::unordered_set seen; size_t n = 0; - for (size_t i = 0; i < uses.size(); i++) { - if (seen.insert(uses[i].range).second) - uses[n++] = uses[i]; - } - uses.resize(n); + for (size_t i = 0; i < a.size(); i++) + if (seen.insert(a[i]).second) + a[n++] = a[i]; + a.resize(n); } - namespace ccls::idx { std::vector> Index( VFS* vfs, diff --git a/src/project.cc b/src/project.cc index 2777634c8..b564b591e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -154,8 +154,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - if (!sys::fs::exists(HeaderOpts.ResourceDir) && HeaderOpts.UseBuiltinIncludes) - args.push_back("-resource-dir=" + g_config->clang.resourceDir); + // if (!sys::fs::exists(HeaderOpts.ResourceDir) && HeaderOpts.UseBuiltinIncludes) + args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); From 46d397f4b3a1c57ca7b5cbe0210ccf1fe1469363 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 18 Jul 2018 10:51:18 -0700 Subject: [PATCH 154/378] --init --- src/messages/initialize.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index bed6295d1..ac7a03892 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -423,14 +423,6 @@ struct Handler_Initialize : BaseMessageHandler { auto& params = request->params; if (!params.rootUri) return; - { - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer(&writer); - Reflect(json_writer, params.initializationOptions); - LOG_S(INFO) << "initializationOptions: " << output.GetString(); - } - std::string project_path = NormalizePath(params.rootUri->GetPath()); LOG_S(INFO) << "initialize in directory " << project_path << " with uri " << params.rootUri->raw_uri; @@ -452,6 +444,12 @@ struct Handler_Initialize : BaseMessageHandler { } } + rapidjson::StringBuffer output; + rapidjson::Writer writer(output); + JsonWriter json_writer(&writer); + Reflect(json_writer, *g_config); + LOG_S(INFO) << "initializationOptions: " << output.GetString(); + if (g_config->cacheDirectory.empty()) { LOG_S(ERROR) << "cacheDirectory cannot be empty."; exit(1); From 19fa911908eceda203198dc16228aa657775a6b8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 18 Jul 2018 22:10:40 -0700 Subject: [PATCH 155/378] links --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 289e80ff4..3a20910ad 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # ccls -ccls is a rewrite of cquery (originally written by Jacob Dufault), -a C/C++/Objective-C language server. +[![Telegram](https://img.shields.io/badge/telegram-@cclsp-blue.svg)](https://telegram.me/cclsp) +[![Gitter](https://img.shields.io/badge/gitter-ccls--project-blue.svg?logo=gitter-white)](https://gitter.im/ccls-project/ccls) + +ccls, which originates from [cquery](https://github.com/cquery-project/cquery), is a C/C++/Objective-C language server. * code completion (with both signature help and snippets) * [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc), and other cross references From 27d641bf64879ebbf46b7dfd54ec00339a9a650d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 19 Jul 2018 20:50:52 -0700 Subject: [PATCH 156/378] Add Query*::file_id to allow textDocument/hover on declarations Also change StorageClass storage to uint8_t --- index_tests/macros/complex.cc | 4 ++-- index_tests/macros/foo.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 8 +++---- .../usage/func_called_from_macro_argument.cc | 2 +- src/indexer.h | 9 ++++---- src/message_handler.cc | 2 +- src/message_handler.h | 2 +- src/messages/ccls_callHierarchy.cc | 2 +- src/query.cc | 23 +++++++++++-------- 9 files changed, 29 insertions(+), 25 deletions(-) diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 080e247f9..c943f2c67 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -44,7 +44,7 @@ FOO(make1(), make2); "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|0|1|16420"], + "uses": ["12:5-12:10|0|1|16420", "12:5-12:10|0|1|64|0"], "callees": [] }], "usr2type": [{ @@ -73,7 +73,7 @@ FOO(make1(), make2); "spell": "9:11-9:16|0|1|2", "extent": "9:1-9:20|0|1|0", "type": 53, - "uses": ["12:14-12:19|0|1|12"], + "uses": ["12:14-12:19|0|1|12", "12:14-12:19|0|1|64|0"], "kind": 13, "storage": 0 }, { diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 7e5f159da..7a832595e 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -59,7 +59,7 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:12-5:15|0|1|4"] + "uses": ["5:12-5:15|0|1|4", "5:12-5:15|0|1|64|0"] }], "usr2var": [{ "usr": 1569772797058982873, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 46f0983ee..01e27631c 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -58,7 +58,7 @@ void func() { "declarations": ["1:11-1:14|0|1|1"], "alias_of": 0, "bases": [], - "derived": [], + "derived": [17805385787823406700], "types": [17805385787823406700], "funcs": [], "vars": [], @@ -87,7 +87,7 @@ void func() { "kind": 3, "declarations": ["3:20-3:23|17805385787823406700|2|1025"], "alias_of": 0, - "bases": [], + "bases": [17805385787823406700, 17805385787823406700, 17805385787823406700, 17805385787823406700], "derived": [], "types": [], "funcs": [], @@ -105,8 +105,8 @@ void func() { "kind": 3, "declarations": ["2:15-2:18|926793467007732869|2|1025"], "alias_of": 0, - "bases": [], - "derived": [], + "bases": [926793467007732869, 926793467007732869, 926793467007732869, 926793467007732869], + "derived": [14450849931009540802], "types": [14450849931009540802], "funcs": [], "vars": [], diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 9ceebb33e..c3bb78d8f 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -22,7 +22,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|0|1|16420"], + "uses": ["6:14-6:20|0|1|16420", "6:14-6:20|0|1|64|0"], "callees": [] }, { "usr": 11404881820527069090, diff --git a/src/indexer.h b/src/indexer.h index 99fbc9212..146ff5b43 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -71,8 +71,6 @@ void Reflect(Writer& visitor, Reference& value); void Reflect(Reader& visitor, Use& value); void Reflect(Writer& visitor, Use& value); -MAKE_REFLECT_TYPE_PROXY2(clang::StorageClass, uint8_t); - template struct NameMixin { std::string_view Name(bool qualified) const { @@ -104,11 +102,12 @@ struct FuncDef : NameMixin { // Functions that this function calls. std::vector callees; + int file_id = -1; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; - clang::StorageClass storage = clang::SC_None; + uint8_t storage = clang::SC_None; std::vector GetBases() const { return bases; } }; @@ -155,6 +154,7 @@ struct TypeDef : NameMixin { // type comes from a using or typedef statement). Usr alias_of = 0; + int file_id = -1; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; @@ -199,6 +199,7 @@ struct VarDef : NameMixin { // Type of the variable. Usr type = 0; + int file_id = -1; int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; @@ -206,7 +207,7 @@ struct VarDef : NameMixin { lsSymbolKind kind = lsSymbolKind::Unknown; // Note a variable may have instances of both |None| and |Extern| // (declaration). - clang::StorageClass storage = clang::SC_None; + uint8_t storage = clang::SC_None; bool is_local() const { return spell && spell->kind != SymbolKind::File && diff --git a/src/message_handler.cc b/src/message_handler.cc index f6ef46952..a4be9c95b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -198,7 +198,7 @@ void EmitSemanticHighlighting(DB *db, std::string_view detailed_name; lsSymbolKind parent_kind = lsSymbolKind::Unknown; lsSymbolKind kind = lsSymbolKind::Unknown; - StorageClass storage = SC_None; + uint8_t storage = SC_None; // This switch statement also filters out symbols that are not highlighted. switch (sym.kind) { case SymbolKind::Func: { diff --git a/src/message_handler.h b/src/message_handler.h index f771ec0ba..e4f79e78e 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -63,7 +63,7 @@ struct Out_CclsPublishSemanticHighlighting int stableId = 0; lsSymbolKind parentKind; lsSymbolKind kind; - clang::StorageClass storage; + uint8_t storage; std::vector> ranges; // `lsRanges` is used to compute `ranges`. diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_callHierarchy.cc index 92267d83e..97b753dd4 100644 --- a/src/messages/ccls_callHierarchy.cc +++ b/src/messages/ccls_callHierarchy.cc @@ -114,7 +114,7 @@ bool Expand(MessageHandler* m, for (SymbolRef ref : def->callees) if (ref.kind == SymbolKind::Func) handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, - def->spell->file_id}, + def->file_id}, call_type); } else { for (Use use : func.uses) diff --git a/src/query.cc b/src/query.cc index c41163c48..7e49c6871 100644 --- a/src/query.cc +++ b/src/query.cc @@ -158,7 +158,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { template bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { for (auto& def1 : def_list) - if (def1.spell->file_id == def.spell->file_id) { + if (def1.file_id == def.file_id) { def1 = std::move(def); return true; } @@ -182,7 +182,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.funcs_hint = current->usr2func.size() - previous->usr2func.size(); for (auto& it : previous->usr2func) { auto& func = it.second; - if (func.def.spell) + if (func.def.detailed_name[0]) r.funcs_removed.push_back(func.usr); r.funcs_declarations[func.usr].first = std::move(func.declarations); r.funcs_uses[func.usr].first = std::move(func.uses); @@ -190,7 +190,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, } for (auto& it : current->usr2func) { auto& func = it.second; - if (func.def.spell && func.def.detailed_name[0]) + if (func.def.detailed_name[0]) r.funcs_def_update.emplace_back(it.first, func.def); r.funcs_declarations[func.usr].second = std::move(func.declarations); r.funcs_uses[func.usr].second = std::move(func.uses); @@ -200,7 +200,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.types_hint = current->usr2type.size() - previous->usr2type.size(); for (auto& it : previous->usr2type) { auto& type = it.second; - if (type.def.spell) + if (type.def.detailed_name[0]) r.types_removed.push_back(type.usr); r.types_declarations[type.usr].first = std::move(type.declarations); r.types_uses[type.usr].first = std::move(type.uses); @@ -209,7 +209,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, }; for (auto& it : current->usr2type) { auto& type = it.second; - if (type.def.spell && type.def.detailed_name[0]) + if (type.def.detailed_name[0]) r.types_def_update.emplace_back(it.first, type.def); r.types_declarations[type.usr].second = std::move(type.declarations); r.types_uses[type.usr].second = std::move(type.uses); @@ -220,14 +220,14 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.vars_hint = current->usr2var.size() - previous->usr2var.size(); for (auto& it : previous->usr2var) { auto& var = it.second; - if (var.def.spell) + if (var.def.detailed_name[0]) r.vars_removed.push_back(var.usr); r.vars_declarations[var.usr].first = std::move(var.declarations); r.vars_uses[var.usr].first = std::move(var.uses); } for (auto& it : current->usr2var) { auto& var = it.second; - if (var.def.spell && var.def.detailed_name[0]) + if (var.def.detailed_name[0]) r.vars_def_update.emplace_back(it.first, var.def); r.vars_declarations[var.usr].second = std::move(var.declarations); r.vars_uses[var.usr].second = std::move(var.uses); @@ -246,7 +246,7 @@ void DB::RemoveUsrs(SymbolKind kind, if (!HasFunc(usr)) continue; QueryFunc& func = Func(usr); auto it = llvm::find_if(func.def, [=](const QueryFunc::Def& def) { - return def.spell->file_id == file_id; + return def.file_id == file_id; }); if (it != func.def.end()) func.def.erase(it); @@ -259,7 +259,7 @@ void DB::RemoveUsrs(SymbolKind kind, if (!HasType(usr)) continue; QueryType& type = Type(usr); auto it = llvm::find_if(type.def, [=](const QueryType::Def& def) { - return def.spell->file_id == file_id; + return def.file_id == file_id; }); if (it != type.def.end()) type.def.erase(it); @@ -272,7 +272,7 @@ void DB::RemoveUsrs(SymbolKind kind, if (!HasVar(usr)) continue; QueryVar& var = Var(usr); auto it = llvm::find_if(var.def, [=](const QueryVar::Def& def) { - return def.spell->file_id == file_id; + return def.file_id == file_id; }); if (it != var.def.end()) var.def.erase(it); @@ -400,6 +400,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); + u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); AssignFileId(lid2file_id, file_id, def.extent); AssignFileId(lid2file_id, file_id, def.callees); @@ -418,6 +419,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); + u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); AssignFileId(lid2file_id, file_id, def.extent); auto R = type_usr.try_emplace({u.first}, type_usr.size()); @@ -435,6 +437,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, for (auto &u : us) { auto& def = u.second; assert(def.detailed_name[0]); + u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); AssignFileId(lid2file_id, file_id, def.extent); auto R = var_usr.try_emplace({u.first}, var_usr.size()); From e67ea3af87322725a99d2e80c66144012c697aed Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 20 Jul 2018 23:27:47 -0700 Subject: [PATCH 157/378] Use ContainerDC for extent, index callees, set StaticMethod --- index_tests/constructors/constructor.cc | 6 +++--- index_tests/constructors/destructor.cc | 6 +++--- .../constructors/implicit_constructor.cc | 6 +++--- index_tests/constructors/invalid_reference.cc | 4 ++-- index_tests/constructors/make_functions.cc | 14 ++++++------- .../class_member_static.cc | 2 +- .../declaration_vs_definition/method.cc | 2 +- index_tests/enums/enum_usage.cc | 2 +- index_tests/foobar.cc | 2 +- index_tests/inheritance/class_inherit.cc | 2 +- .../class_inherit_templated_parent.cc | 10 ++++----- .../inheritance/class_multiple_inherit.cc | 6 +++--- index_tests/inheritance/function_override.cc | 2 +- .../inheritance/multiple_base_functions.cc | 6 +++--- index_tests/lambdas/lambda.cc | 8 +++---- index_tests/macros/complex.cc | 6 +++--- index_tests/macros/foo.cc | 2 +- index_tests/method_definition.cc | 2 +- index_tests/multi_file/impl.cc | 10 ++++----- index_tests/multi_file/simple_impl.cc | 4 ++-- index_tests/multi_file/static.cc | 6 +++--- index_tests/namespaces/method_definition.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 10 ++++----- index_tests/namespaces/namespace_reference.cc | 8 +++---- .../outline/static_function_in_type.cc | 8 +++---- .../func_specialized_template_param.cc | 4 ++-- .../implicit_variable_instantiation.cc | 4 ++-- ...ass_template_func_usage_folded_into_one.cc | 4 ++-- index_tests/templates/specialization.cc | 2 +- .../templates/specialized_func_definition.cc | 4 ++-- ...mplate_class_func_usage_folded_into_one.cc | 4 ++-- ...ass_template_func_usage_folded_into_one.cc | 4 ++-- ...mplate_class_type_usage_folded_into_one.cc | 2 +- ...emplate_class_var_usage_folded_into_one.cc | 2 +- index_tests/unions/union_usage.cc | 4 ++-- .../usage/func_called_from_constructor.cc | 8 +++---- .../usage/func_called_from_macro_argument.cc | 4 ++-- .../usage/func_called_from_template.cc | 21 +++++++++++++++---- .../usage/func_called_implicit_ctor.cc | 8 +++---- index_tests/usage/func_usage_addr_func.cc | 6 +++--- index_tests/usage/func_usage_addr_method.cc | 6 +++--- index_tests/usage/func_usage_call_func.cc | 4 ++-- index_tests/usage/func_usage_call_method.cc | 6 +++--- .../usage/func_usage_class_inline_var_def.cc | 2 +- .../usage/func_usage_forward_decl_func.cc | 4 ++-- .../usage/func_usage_forward_decl_method.cc | 6 +++--- index_tests/usage/func_usage_template_func.cc | 4 ++-- .../usage/type_usage_as_template_parameter.cc | 4 ++-- ...ype_usage_as_template_parameter_complex.cc | 10 ++++----- index_tests/usage/type_usage_declare_field.cc | 4 ++-- index_tests/usage/type_usage_declare_local.cc | 4 ++-- .../usage/type_usage_declare_qualifiers.cc | 2 +- .../usage/type_usage_on_return_type.cc | 6 +++--- index_tests/usage/type_usage_various.cc | 4 ++-- index_tests/usage/usage_inside_of_call.cc | 14 ++++++------- .../usage/usage_inside_of_call_simple.cc | 6 +++--- index_tests/usage/var_usage_call_function.cc | 4 ++-- index_tests/usage/var_usage_class_member.cc | 12 +++++------ .../usage/var_usage_class_member_static.cc | 8 +++---- index_tests/usage/var_usage_cstyle_cast.cc | 4 ++-- index_tests/usage/var_usage_extern.cc | 2 +- index_tests/usage/var_usage_static.cc | 2 +- index_tests/vars/class_member.cc | 2 +- index_tests/vars/class_static_member.cc | 4 ++-- index_tests/vars/deduce_auto_type.cc | 2 +- index_tests/vars/function_local.cc | 2 +- .../vars/type_instance_on_using_type.cc | 2 +- src/indexer.cc | 21 +++++++++++++------ src/messages/ccls_memberHierarchy.cc | 2 +- 69 files changed, 196 insertions(+), 174 deletions(-) diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index c3689b87e..cf764596a 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -26,7 +26,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|15041163540773201510|2|16676", "8:17-8:20|15041163540773201510|2|16676"], + "uses": ["7:7-7:8|4259594751088586730|3|16676", "8:17-8:20|4259594751088586730|3|16676"], "callees": [] }, { "usr": 4259594751088586730, @@ -42,7 +42,7 @@ void foo() { "derived": [], "vars": [10983126130596230582, 17165811951126099095], "uses": [], - "callees": [] + "callees": ["7:7-7:8|3385168158331140247|3|16676", "7:7-7:8|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676"] }], "usr2type": [{ "usr": 15041163540773201510, @@ -60,7 +60,7 @@ void foo() { "funcs": [3385168158331140247], "vars": [], "instances": [10983126130596230582, 17165811951126099095], - "uses": ["3:3-3:6|0|1|4", "7:3-7:6|0|1|4", "8:3-8:6|0|1|4", "8:17-8:20|0|1|4"] + "uses": ["3:3-3:6|15041163540773201510|2|4", "7:3-7:6|4259594751088586730|3|4", "8:3-8:6|4259594751088586730|3|4", "8:17-8:20|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 10983126130596230582, diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 0c4a0c929..f7724c3b8 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -31,7 +31,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|15041163540773201510|2|16676"], + "uses": ["8:7-8:8|4259594751088586730|3|16676"], "callees": [] }, { "usr": 4259594751088586730, @@ -47,7 +47,7 @@ void foo() { "derived": [], "vars": [1893354193220338759], "uses": [], - "callees": [] + "callees": ["8:7-8:8|3385168158331140247|3|16676", "8:7-8:8|3385168158331140247|3|16676"] }, { "usr": 7440261702884428359, "detailed_name": "Foo::~Foo() noexcept", @@ -80,7 +80,7 @@ void foo() { "funcs": [3385168158331140247, 7440261702884428359], "vars": [], "instances": [1893354193220338759], - "uses": ["3:3-3:6|0|1|4", "4:4-4:7|0|1|4", "8:3-8:6|0|1|4"] + "uses": ["3:3-3:6|15041163540773201510|2|4", "4:4-4:7|15041163540773201510|2|4", "8:3-8:6|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 1893354193220338759, diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index 9d934c972..be98be7fd 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -26,7 +26,7 @@ void Make() { "derived": [], "vars": [449111627548814328, 17097499197730163115], "uses": [], - "callees": [] + "callees": ["6:8-6:12|10530961286677896857|3|16676", "6:8-6:12|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676"] }, { "usr": 10530961286677896857, "detailed_name": "Type::Type()", @@ -40,7 +40,7 @@ void Make() { "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|13487927231218873822|2|16676", "7:15-7:19|13487927231218873822|2|16676"], + "uses": ["6:8-6:12|3957104924306079513|3|16676", "7:15-7:19|3957104924306079513|3|16676"], "callees": [] }], "usr2type": [{ @@ -59,7 +59,7 @@ void Make() { "funcs": [10530961286677896857], "vars": [], "instances": [449111627548814328, 17097499197730163115], - "uses": ["2:3-2:7|0|1|4", "6:3-6:7|0|1|4", "7:15-7:19|0|1|4"] + "uses": ["2:3-2:7|13487927231218873822|2|4", "6:3-6:7|3957104924306079513|3|4", "7:15-7:19|3957104924306079513|3|4"] }], "usr2var": [{ "usr": 449111627548814328, diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index b1ea44652..c6c933e13 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -21,7 +21,7 @@ Foo::Foo() {} "storage": 0, "declarations": [], "spell": "4:6-4:9|15041163540773201510|2|1026", - "extent": "4:1-4:11|0|1|0", + "extent": "4:1-4:11|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], @@ -44,7 +44,7 @@ Foo::Foo() {} "funcs": [17319723337446061757], "vars": [], "instances": [], - "uses": ["4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] + "uses": ["4:1-4:4|0|1|4", "4:6-4:9|15041163540773201510|2|4"] }], "usr2var": [] } diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index 04699b41f..e2e3be4ca 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -105,7 +105,7 @@ OUTPUT: make_functions.h "funcs": [], "vars": [], "instances": [], - "uses": ["7:17-7:20|0|1|4", "8:15-8:18|0|1|4"] + "uses": ["7:17-7:20|14935975554338052500|2|4", "8:15-8:18|14935975554338052500|2|4"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", @@ -122,7 +122,7 @@ OUTPUT: make_functions.h "funcs": [13131778807733950299, 13028995015627606181, 3765833212244435302, 17321436359755983845], "vars": [], "instances": [], - "uses": ["5:3-5:9|0|1|4", "6:3-6:9|0|1|4", "7:3-7:9|0|1|4", "8:3-8:9|0|1|4"] + "uses": ["5:3-5:9|14935975554338052500|2|4", "6:3-6:9|14935975554338052500|2|4", "7:3-7:9|14935975554338052500|2|4", "8:3-8:9|14935975554338052500|2|4"] }], "usr2var": [] } @@ -159,7 +159,7 @@ OUTPUT: make_functions.cc "bases": [], "derived": [], "vars": [3908732770590594660], - "uses": ["17:3-17:14|0|1|16420"], + "uses": ["17:3-17:14|2816883305867289955|3|16420"], "callees": [] }, { "usr": 2816883305867289955, @@ -175,7 +175,7 @@ OUTPUT: make_functions.cc "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["14:3-14:13|15793662558620604611|3|16420", "15:3-15:13|15793662558620604611|3|16420", "16:3-16:13|15793662558620604611|3|16420", "17:3-17:14|2532818908869373467|3|16420"] }, { "usr": 11138976705878544996, "detailed_name": "", @@ -215,7 +215,7 @@ OUTPUT: make_functions.cc "bases": [], "derived": [], "vars": [8463700030555379526], - "uses": ["14:3-14:13|0|1|16420", "15:3-15:13|0|1|16420", "16:3-16:13|0|1|16420"], + "uses": ["14:3-14:13|2816883305867289955|3|16420", "15:3-15:13|2816883305867289955|3|16420", "16:3-16:13|2816883305867289955|3|16420"], "callees": [] }], "usr2type": [{ @@ -262,7 +262,7 @@ OUTPUT: make_functions.cc "funcs": [], "vars": [], "instances": [], - "uses": ["16:29-16:32|0|1|4", "17:30-17:33|0|1|4"] + "uses": ["16:29-16:32|2816883305867289955|3|4", "17:30-17:33|2816883305867289955|3|4"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", @@ -277,7 +277,7 @@ OUTPUT: make_functions.cc "funcs": [], "vars": [], "instances": [], - "uses": ["14:14-14:20|0|1|4", "15:14-15:20|0|1|4", "16:14-16:20|0|1|4", "17:15-17:21|0|1|4"] + "uses": ["14:14-14:20|2816883305867289955|3|4", "15:14-15:20|2816883305867289955|3|4", "16:14-16:20|2816883305867289955|3|4", "17:15-17:21|2816883305867289955|3|4"] }], "usr2var": [{ "usr": 180270746871803062, diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 0e5b32227..c0ae1aa75 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -50,7 +50,7 @@ int Foo::foo; "short_name": "foo", "declarations": ["2:14-2:17|15041163540773201510|2|1025"], "spell": "5:10-5:13|15041163540773201510|2|1026", - "extent": "5:1-5:13|0|1|0", + "extent": "5:1-5:13|15041163540773201510|2|0", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index c51fd99e9..18aed73a6 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -46,7 +46,7 @@ void Foo::def() {} "storage": 0, "declarations": ["4:8-4:11|15041163540773201510|2|1025"], "spell": "7:11-7:14|15041163540773201510|2|1026", - "extent": "7:1-7:19|0|1|0", + "extent": "7:1-7:19|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index d7c94e44a..2d602b458 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -39,7 +39,7 @@ Foo x = Foo::A; "spell": "2:3-2:4|16985894625255407295|2|1026", "extent": "2:3-2:4|16985894625255407295|2|0", "type": 0, - "uses": ["6:14-6:15|16985894625255407295|2|4"], + "uses": ["6:14-6:15|0|1|4"], "kind": 22, "storage": 0 }, { diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index cdbe2762d..b1e571d16 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -115,7 +115,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["9:9-9:14|10528472276654770367|2|4"] + "uses": ["9:9-9:14|0|1|4"] }], "usr2var": [{ "usr": 12028309045033782423, diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index 3f797bc1f..e38b20bd8 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -23,7 +23,7 @@ class Derived : public Parent {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:30|0|1|2052"] + "uses": ["2:24-2:30|10963370434658308541|2|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Parent {}", diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 14bedb593..33b80bbbd 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -34,7 +34,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:43-13:51|0|1|2052"] + "uses": ["13:43-13:51|10963370434658308541|2|2052"] }, { "usr": 10651399730831737929, "detailed_name": "class Derived2 : Base2 {}", @@ -51,7 +51,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:56-13:64|0|1|2052"] + "uses": ["13:56-13:64|10963370434658308541|2|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}", @@ -68,7 +68,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:33-13:40|0|1|2052", "13:65-13:72|0|1|2052"] + "uses": ["13:33-13:40|10963370434658308541|2|2052", "13:65-13:72|10963370434658308541|2|2052"] }, { "usr": 11118288764693061434, "detailed_name": "class Base2 {}", @@ -85,7 +85,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:27-13:32|0|1|2052"] + "uses": ["13:27-13:32|10963370434658308541|2|2052"] }, { "usr": 11930058224338108382, "detailed_name": "class Base1 {}", @@ -102,7 +102,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:17-13:22|0|1|2052"] + "uses": ["13:17-13:22|10963370434658308541|2|2052"] }], "usr2var": [] } diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index 18164c614..ee1603b3d 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -25,7 +25,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:28|0|1|2052", "3:24-3:28|0|1|2052"] + "uses": ["2:24-2:28|11863524815063131483|2|2052", "3:24-3:28|14022569716337624303|2|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public MiddleA, public MiddleB {}", @@ -59,7 +59,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:24-4:31|0|1|2052"] + "uses": ["4:24-4:31|10963370434658308541|2|2052"] }, { "usr": 14022569716337624303, "detailed_name": "class MiddleB : public Root {}", @@ -76,7 +76,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:40-4:47|0|1|2052"] + "uses": ["4:40-4:47|10963370434658308541|2|2052"] }], "usr2var": [] } diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 518fb3ba2..982a2cf14 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -55,7 +55,7 @@ class Derived : public Root { "funcs": [9948027785633571339], "vars": [], "instances": [], - "uses": ["4:24-4:28|0|1|2052"] + "uses": ["4:24-4:28|10963370434658308541|2|2052"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Root {}", diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 3ae72322e..dcc0e7814 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -75,7 +75,7 @@ struct Derived : Base0, Base1 { "funcs": [13164726294460837993], "vars": [], "instances": [], - "uses": ["8:4-8:11|0|1|4"] + "uses": ["8:4-8:11|10963370434658308541|2|4"] }, { "usr": 11628904180681204356, "detailed_name": "struct Base0 {}", @@ -92,7 +92,7 @@ struct Derived : Base0, Base1 { "funcs": [16347272523198263017], "vars": [], "instances": [], - "uses": ["2:12-2:17|0|1|4", "7:18-7:23|0|1|2052"] + "uses": ["2:12-2:17|11628904180681204356|2|4", "7:18-7:23|10963370434658308541|2|2052"] }, { "usr": 15826803741381445676, "detailed_name": "struct Base1 {}", @@ -109,7 +109,7 @@ struct Derived : Base0, Base1 { "funcs": [8401779086123965305], "vars": [], "instances": [], - "uses": ["5:12-5:17|0|1|4", "7:25-7:30|0|1|2052"] + "uses": ["5:12-5:17|15826803741381445676|2|4", "7:25-7:30|10963370434658308541|2|2052"] }], "usr2var": [] } diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index f95792761..357d6e321 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -30,7 +30,7 @@ void foo() { "derived": [], "vars": [12666114896600231317, 2981279427664991319], "uses": [], - "callees": [] + "callees": ["9:14-9:15|17926497908620168464|3|16420", "10:14-10:15|17926497908620168464|3|16420", "11:14-11:15|17926497908620168464|3|16420"] }, { "usr": 17926497908620168464, "detailed_name": "inline void foo()::(anon class)::operator()(int y) const", @@ -42,7 +42,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:14-9:15|14635009347499519042|2|16420", "10:14-10:15|14635009347499519042|2|16420", "11:14-11:15|14635009347499519042|2|16420"], + "uses": ["9:14-9:15|4259594751088586730|3|16420", "10:14-10:15|4259594751088586730|3|16420", "11:14-11:15|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [{ @@ -110,9 +110,9 @@ void foo() { "short_name": "y", "declarations": [], "spell": "4:31-4:32|17926497908620168464|3|2", - "extent": "4:27-4:32|17926497908620168464|3|0", + "extent": "4:27-4:32|4259594751088586730|3|0", "type": 0, - "uses": ["6:7-6:8|17926497908620168464|3|28"], + "uses": ["6:7-6:8|4259594751088586730|3|28"], "kind": 253, "storage": 0 }] diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index c943f2c67..1b17ea8e5 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -30,7 +30,7 @@ FOO(make1(), make2); "derived": [], "vars": [], "uses": ["2:7-2:8|0|1|64|0", "3:7-3:8|0|1|64|0"], - "callees": [] + "callees": ["12:5-12:10|14400399977994209582|3|16420"] }, { "usr": 14400399977994209582, "detailed_name": "int make1()", @@ -44,7 +44,7 @@ FOO(make1(), make2); "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|0|1|16420", "12:5-12:10|0|1|64|0"], + "uses": ["12:5-12:10|9720930732776154610|3|16420", "12:5-12:10|0|1|64|0"], "callees": [] }], "usr2type": [{ @@ -73,7 +73,7 @@ FOO(make1(), make2); "spell": "9:11-9:16|0|1|2", "extent": "9:1-9:20|0|1|0", "type": 53, - "uses": ["12:14-12:19|0|1|12", "12:14-12:19|0|1|64|0"], + "uses": ["12:14-12:19|9720930732776154610|3|12", "12:14-12:19|0|1|64|0"], "kind": 13, "storage": 0 }, { diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 7a832595e..c2086d470 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -59,7 +59,7 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:12-5:15|0|1|4", "5:12-5:15|0|1|64|0"] + "uses": ["5:12-5:15|15041163540773201510|2|4", "5:12-5:15|0|1|64|0"] }], "usr2var": [{ "usr": 1569772797058982873, diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 083dbcb33..b79e9ba31 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -18,7 +18,7 @@ void Foo::foo() const {} "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|1025"], "spell": "5:11-5:14|15041163540773201510|2|1026", - "extent": "5:1-5:25|0|1|0", + "extent": "5:1-5:25|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index db74ff21e..cc53dabf6 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -107,7 +107,7 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["5:26-5:30|0|1|2052"] + "uses": ["5:26-5:30|16750616846959666305|2|2052"] }, { "usr": 16750616846959666305, "detailed_name": "struct SameFileDerived : Base {}", @@ -212,11 +212,11 @@ OUTPUT: impl.cc "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["4:3-4:7|11650481237659640387|3|16420"] }, { "usr": 11650481237659640387, - "detailed_name": "void Foo1()", - "qual_name_offset": 5, + "detailed_name": "template<> void Foo1()", + "qual_name_offset": 16, "short_name": "Foo1", "kind": 12, "storage": 0, @@ -224,7 +224,7 @@ OUTPUT: impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:7|0|1|16420"], + "uses": ["4:3-4:7|5817708529036841195|3|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 5109c2a20..df6d723e0 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -47,7 +47,7 @@ OUTPUT: simple_impl.cc "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["4:3-4:9|16236105532929924676|3|16420"] }, { "usr": 16236105532929924676, "detailed_name": "void header()", @@ -59,7 +59,7 @@ OUTPUT: simple_impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:9|0|1|16420"], + "uses": ["4:3-4:9|3373269392705484958|3|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index c0a7267a2..7b255c5d4 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -12,7 +12,7 @@ OUTPUT: static.h "detailed_name": "static void Buffer::CreateSharedBuffer()", "qual_name_offset": 12, "short_name": "CreateSharedBuffer", - "kind": 6, + "kind": 254, "storage": 0, "declarations": ["4:15-4:33|9411323049603567600|2|1025"], "bases": [], @@ -53,11 +53,11 @@ OUTPUT: static.cc "detailed_name": "void Buffer::CreateSharedBuffer()", "qual_name_offset": 5, "short_name": "CreateSharedBuffer", - "kind": 6, + "kind": 254, "storage": 0, "declarations": [], "spell": "3:14-3:32|9411323049603567600|2|1026", - "extent": "3:1-3:37|0|1|0", + "extent": "3:1-3:37|9411323049603567600|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 3774972c6..2506e411c 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -20,7 +20,7 @@ void Foo::foo() {} "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|1025"], "spell": "6:11-6:14|4508214972876735896|2|1026", - "extent": "6:1-6:19|2029211996748007610|2|0", + "extent": "6:1-6:19|4508214972876735896|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 01e27631c..118e20c7e 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -63,7 +63,7 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["9:17-9:20|0|1|4", "12:11-12:14|0|1|4"] + "uses": ["9:17-9:20|0|1|4", "12:11-12:14|10818727483146447186|3|4"] }, { "usr": 11879713791858506216, "detailed_name": "namespace fbz = foo::bar::baz", @@ -78,7 +78,7 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["13:11-13:14|0|1|4"] + "uses": ["13:11-13:14|10818727483146447186|3|4"] }, { "usr": 14450849931009540802, "detailed_name": "namespace foo::bar::baz {\n}", @@ -96,7 +96,7 @@ void func() { "R": -1 }], "instances": [], - "uses": ["9:27-9:30|17805385787823406700|2|4", "12:21-12:24|17805385787823406700|2|4"] + "uses": ["9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] }, { "usr": 17805385787823406700, "detailed_name": "namespace foo::bar {\n}", @@ -111,7 +111,7 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["9:22-9:25|926793467007732869|2|4", "12:16-12:19|926793467007732869|2|4"] + "uses": ["9:22-9:25|0|1|4", "12:16-12:19|10818727483146447186|3|4"] }], "usr2var": [{ "usr": 6030927277961448585, @@ -149,7 +149,7 @@ void func() { "spell": "4:18-4:21|14450849931009540802|2|1026", "extent": "4:14-4:26|14450849931009540802|2|0", "type": 53, - "uses": ["12:26-12:29|14450849931009540802|2|12", "13:16-13:19|14450849931009540802|2|12"], + "uses": ["12:26-12:29|10818727483146447186|3|12", "13:16-13:19|10818727483146447186|3|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 758c39e76..169494038 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -28,7 +28,7 @@ void Runner() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["7:7-7:13|17328473273923617489|3|16420", "9:3-9:9|17328473273923617489|3|16420"] }, { "usr": 17328473273923617489, "detailed_name": "void ns::Accept(int a)", @@ -42,7 +42,7 @@ void Runner() { "bases": [], "derived": [], "vars": [3649375698083002347], - "uses": ["7:7-7:13|11072669167287398027|2|16420", "9:3-9:9|11072669167287398027|2|16420"], + "uses": ["7:7-7:13|631910859630953711|3|16420", "9:3-9:9|631910859630953711|3|16420"], "callees": [] }], "usr2type": [{ @@ -77,7 +77,7 @@ void Runner() { "R": -1 }], "instances": [], - "uses": ["7:3-7:5|0|1|4", "7:14-7:16|0|1|4", "8:19-8:21|0|1|4"] + "uses": ["7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] }], "usr2var": [{ "usr": 3649375698083002347, @@ -100,7 +100,7 @@ void Runner() { "spell": "2:7-2:10|11072669167287398027|2|1026", "extent": "2:3-2:10|11072669167287398027|2|0", "type": 53, - "uses": ["7:18-7:21|11072669167287398027|2|12", "9:10-9:13|11072669167287398027|2|12"], + "uses": ["7:18-7:21|631910859630953711|3|12", "9:10-9:13|631910859630953711|3|12"], "kind": 13, "storage": 0 }] diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index c9caa3bb4..89842296c 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -16,7 +16,7 @@ OUTPUT: static_function_in_type.h "detailed_name": "static void ns::Foo::Register(ns::Manager *)", "qual_name_offset": 12, "short_name": "Register", - "kind": 6, + "kind": 254, "storage": 0, "declarations": ["6:15-6:23|17262466801709381811|2|1025"], "bases": [], @@ -39,7 +39,7 @@ OUTPUT: static_function_in_type.h "funcs": [], "vars": [], "instances": [], - "uses": ["6:24-6:31|11072669167287398027|2|4"] + "uses": ["6:24-6:31|17262466801709381811|2|4"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {\n}", @@ -87,12 +87,12 @@ OUTPUT: static_function_in_type.cc "detailed_name": "void Foo::Register(ns::Manager *m)", "qual_name_offset": 5, "short_name": "Register", - "kind": 6, + "kind": 254, "storage": 0, "comments": "static", "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|1026", - "extent": "5:1-6:2|11072669167287398027|2|0", + "extent": "5:1-6:2|17262466801709381811|2|0", "bases": [], "derived": [], "vars": [13569879755236306838], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 6a3dc6311..7d5f44beb 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -21,7 +21,7 @@ void Foo::Bar(Template&) {} "storage": 0, "declarations": ["5:8-5:11|15041163540773201510|2|1025"], "spell": "8:11-8:14|15041163540773201510|2|1026", - "extent": "8:1-8:36|0|1|0", + "extent": "8:1-8:36|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], @@ -42,7 +42,7 @@ void Foo::Bar(Template&) {} "funcs": [], "vars": [], "instances": [], - "uses": ["5:12-5:20|0|1|4", "8:15-8:23|0|1|4"] + "uses": ["5:12-5:20|15041163540773201510|2|4", "8:15-8:23|0|1|4"] }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 934522e8c..db370e9f6 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -51,7 +51,7 @@ namespace ns { "funcs": [], "vars": [], "instances": [4731849186641714451, 4731849186641714451], - "uses": ["6:22-6:29|11072669167287398027|2|4", "6:44-6:51|11072669167287398027|2|4", "10:18-10:25|11072669167287398027|2|4"] + "uses": ["6:22-6:29|12688716854043726585|2|4", "6:44-6:51|12688716854043726585|2|4", "10:18-10:25|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {\n}", @@ -99,7 +99,7 @@ namespace ns { "hover": "static constexpr ns::VarType ns::Holder::static_var = (VarType)0x0", "declarations": ["6:30-6:40|12688716854043726585|2|1025"], "spell": "10:37-10:47|12688716854043726585|2|1026", - "extent": "9:3-10:47|11072669167287398027|2|0", + "extent": "9:3-10:47|12688716854043726585|2|0", "type": 1532099849728741556, "uses": ["13:26-13:36|11072669167287398027|2|12", "14:27-14:37|11072669167287398027|2|12"], "kind": 13, diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index ba245e898..073ba3447 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -21,7 +21,7 @@ namespace ns { "detailed_name": "static int ns::Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 6, + "kind": 254, "storage": 0, "declarations": [], "spell": "5:16-5:19|14042997404480181958|2|1026", @@ -29,7 +29,7 @@ namespace ns { "bases": [], "derived": [], "vars": [], - "uses": ["10:21-10:24|14042997404480181958|2|36", "11:22-11:25|14042997404480181958|2|36"], + "uses": ["10:21-10:24|11072669167287398027|2|36", "11:22-11:25|11072669167287398027|2|36"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index aba5f2c99..c6345002b 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -436,7 +436,7 @@ void foo(float Value); "spell": "36:3-36:8|9201299975592934124|2|1026", "extent": "36:3-36:8|9201299975592934124|2|0", "type": 0, - "uses": ["43:20-43:25|9201299975592934124|2|4"], + "uses": ["43:20-43:25|0|1|4"], "kind": 22, "storage": 0 }, { diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 68ce9f8b2..07c0d4757 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -31,7 +31,7 @@ void Template::Foo() {} "storage": 0, "declarations": [], "spell": "10:22-10:25|17649312483543982122|2|1026", - "extent": "9:1-10:30|0|1|0", + "extent": "9:1-10:30|17649312483543982122|2|0", "bases": [], "derived": [], "vars": [], @@ -46,7 +46,7 @@ void Template::Foo() {} "storage": 0, "declarations": ["3:8-3:11|17107291254533526269|2|1025"], "spell": "7:19-7:22|17107291254533526269|2|1026", - "extent": "6:1-7:24|0|1|0", + "extent": "6:1-7:24|17107291254533526269|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 0f59f6737..93d129987 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -18,7 +18,7 @@ int b = Foo::foo(); "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 6, + "kind": 254, "storage": 0, "declarations": [], "spell": "3:14-3:17|10528472276654770367|2|1026", @@ -26,7 +26,7 @@ int b = Foo::foo(); "bases": [], "derived": [], "vars": [], - "uses": ["8:19-8:22|10528472276654770367|2|36", "9:20-9:23|10528472276654770367|2|36"], + "uses": ["8:19-8:22|0|1|36", "9:20-9:23|0|1|36"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 034b6ef34..a38322c34 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -19,7 +19,7 @@ int b = Foo::foo(); "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", - "kind": 6, + "kind": 254, "storage": 0, "declarations": [], "spell": "4:14-4:17|10528472276654770367|2|1026", @@ -27,7 +27,7 @@ int b = Foo::foo(); "bases": [], "derived": [], "vars": [], - "uses": ["9:19-9:22|10528472276654770367|2|36", "10:20-10:23|10528472276654770367|2|36"], + "uses": ["9:19-9:22|0|1|36", "10:20-10:23|0|1|36"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index f80e5f0ee..0dbec81c2 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -117,7 +117,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [], - "uses": ["9:9-9:14|10528472276654770367|2|4", "10:9-10:14|10528472276654770367|2|4"] + "uses": ["9:9-9:14|0|1|4", "10:9-10:14|0|1|4"] }, { "usr": 15961308565836244174, "detailed_name": "Inner", diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index 8ab2b8dc0..fd1726719 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -66,7 +66,7 @@ int b = Foo::var; "hover": "static constexpr int Foo::var = 3", "declarations": ["3:24-3:27|10528472276654770367|2|1025"], "type": 53, - "uses": ["6:19-6:22|10528472276654770367|2|12", "7:20-7:23|10528472276654770367|2|12"], + "uses": ["6:19-6:22|0|1|12", "7:20-7:23|0|1|12"], "kind": 13, "storage": 2 }, { diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index eadb06c71..8682aae20 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -95,7 +95,7 @@ void act(Foo*) { "spell": "6:5-6:6|0|1|2", "extent": "6:1-6:6|0|1|0", "type": 8501689086387244262, - "uses": ["9:3-9:4|0|1|4"], + "uses": ["9:3-9:4|13982179977217945200|3|4"], "kind": 13, "storage": 0 }, { @@ -119,7 +119,7 @@ void act(Foo*) { "spell": "2:7-2:8|8501689086387244262|2|1026", "extent": "2:3-2:12|8501689086387244262|2|0", "type": 53, - "uses": ["9:5-9:6|8501689086387244262|2|20"], + "uses": ["9:5-9:6|13982179977217945200|3|20"], "kind": 8, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 9f43fd00d..69269d9e8 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -26,7 +26,7 @@ Foo::Foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|0|1|16420"], + "uses": ["8:3-8:9|3385168158331140247|3|16420"], "callees": [] }, { "usr": 3385168158331140247, @@ -37,12 +37,12 @@ Foo::Foo() { "storage": 0, "declarations": ["4:3-4:6|15041163540773201510|2|1025"], "spell": "7:6-7:9|15041163540773201510|2|1026", - "extent": "7:1-9:2|0|1|0", + "extent": "7:1-9:2|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["8:3-8:9|468307235068920063|3|16420"] }], "usr2type": [{ "usr": 15041163540773201510, @@ -60,7 +60,7 @@ Foo::Foo() { "funcs": [3385168158331140247], "vars": [], "instances": [], - "uses": ["4:3-4:6|0|1|4", "7:1-7:4|0|1|4", "7:6-7:9|0|1|4"] + "uses": ["4:3-4:6|15041163540773201510|2|4", "7:1-7:4|0|1|4", "7:6-7:9|15041163540773201510|2|4"] }], "usr2var": [] } diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index c3bb78d8f..1312ef951 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -22,7 +22,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|0|1|16420", "6:14-6:20|0|1|64|0"], + "uses": ["6:14-6:20|11404881820527069090|3|16420", "6:14-6:20|0|1|64|0"], "callees": [] }, { "usr": 11404881820527069090, @@ -38,7 +38,7 @@ void caller() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["6:14-6:20|3787803219955606747|3|16420"] }], "usr2type": [], "usr2var": [{ diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 34338f343..868cc1b08 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -27,8 +27,21 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|0|1|16420"], + "uses": ["5:3-5:9|10177235824697315808|3|16420", "5:3-5:9|2459767597003442547|3|16420"], "callees": [] + }, { + "usr": 2459767597003442547, + "detailed_name": "", + "qual_name_offset": 0, + "short_name": "", + "kind": 0, + "storage": 0, + "declarations": [], + "bases": [], + "derived": [], + "vars": [], + "uses": [], + "callees": ["5:3-5:9|468307235068920063|3|16420"] }, { "usr": 4259594751088586730, "detailed_name": "void foo()", @@ -43,7 +56,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["9:3-9:9|10177235824697315808|3|16420"] }, { "usr": 10177235824697315808, "detailed_name": "void caller()", @@ -57,8 +70,8 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:3-9:9|0|1|16420"], - "callees": [] + "uses": ["9:3-9:9|4259594751088586730|3|16420"], + "callees": ["5:3-5:9|468307235068920063|3|16420"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index 372c2f127..522158bdf 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -26,7 +26,7 @@ Wrapper caller() { "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|0|1|16420"], + "uses": ["8:10-8:16|11404881820527069090|3|16420"], "callees": [] }, { "usr": 10544127002917214589, @@ -39,7 +39,7 @@ Wrapper caller() { "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|13611487872560323389|2|16676"], + "uses": ["8:10-8:16|11404881820527069090|3|16676"], "callees": [] }, { "usr": 11404881820527069090, @@ -55,7 +55,7 @@ Wrapper caller() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["8:10-8:16|10544127002917214589|3|16676", "8:10-8:16|468307235068920063|3|16420"] }], "usr2type": [{ "usr": 13611487872560323389, @@ -73,7 +73,7 @@ Wrapper caller() { "funcs": [10544127002917214589], "vars": [], "instances": [], - "uses": ["2:3-2:10|0|1|4", "7:1-7:8|0|1|4"] + "uses": ["2:3-2:10|13611487872560323389|2|4", "7:1-7:8|0|1|4"] }], "usr2var": [] } diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 3d163e139..294b6f5e2 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -25,7 +25,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|0|1|132", "7:12-7:16|0|1|132"], + "uses": ["6:18-6:22|9376923949268137283|3|132", "7:12-7:16|9376923949268137283|3|132"], "callees": [] }, { "usr": 9376923949268137283, @@ -41,7 +41,7 @@ void user() { "derived": [], "vars": [16088407831770615719], "uses": [], - "callees": [] + "callees": ["6:18-6:22|5264867802674151787|3|132", "6:18-6:22|5264867802674151787|3|132", "7:3-7:10|12924914488846929470|3|16420", "7:12-7:16|5264867802674151787|3|132"] }, { "usr": 12924914488846929470, "detailed_name": "void consume(void (*)())", @@ -55,7 +55,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["7:3-7:10|0|1|16420"], + "uses": ["7:3-7:10|9376923949268137283|3|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 1953c9cc7..3dfdda35d 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -26,7 +26,7 @@ void user() { "derived": [], "vars": [4636142131003982569], "uses": [], - "callees": [] + "callees": ["6:18-6:22|18417145003926999463|3|132", "6:18-6:22|18417145003926999463|3|132"] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", @@ -38,7 +38,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|15041163540773201510|2|132"], + "uses": ["6:18-6:22|9376923949268137283|3|132"], "callees": [] }], "usr2type": [{ @@ -57,7 +57,7 @@ void user() { "funcs": [18417145003926999463], "vars": [], "instances": [], - "uses": ["6:13-6:16|0|1|4"] + "uses": ["6:13-6:16|9376923949268137283|3|4"] }], "usr2var": [{ "usr": 4636142131003982569, diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 7552f625c..b6d82740a 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -21,7 +21,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["3:3-3:9|0|1|16420"], + "uses": ["3:3-3:9|11404881820527069090|3|16420"], "callees": [] }, { "usr": 11404881820527069090, @@ -37,7 +37,7 @@ void caller() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["3:3-3:9|468307235068920063|3|16420"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index a727815e6..e16be451e 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -26,7 +26,7 @@ void user() { "derived": [], "vars": [14045150712868309451], "uses": [], - "callees": [] + "callees": ["7:6-7:10|18417145003926999463|3|16420"] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", @@ -38,7 +38,7 @@ void user() { "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:10|15041163540773201510|2|16420"], + "uses": ["7:6-7:10|9376923949268137283|3|16420"], "callees": [] }], "usr2type": [{ @@ -57,7 +57,7 @@ void user() { "funcs": [18417145003926999463], "vars": [], "instances": [14045150712868309451], - "uses": ["6:3-6:6|0|1|4"] + "uses": ["6:3-6:6|9376923949268137283|3|4"] }], "usr2var": [{ "usr": 14045150712868309451, diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index fb529c480..413923852 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -24,7 +24,7 @@ class Foo { "bases": [], "derived": [], "vars": [], - "uses": ["6:11-6:17|0|1|36"], + "uses": ["6:11-6:17|15041163540773201510|2|36"], "callees": [] }], "usr2type": [{ diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 503465bc4..775595fd8 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -19,7 +19,7 @@ void usage() { "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:6|0|1|16420"], + "uses": ["4:3-4:6|6767773193109753523|3|16420"], "callees": [] }, { "usr": 6767773193109753523, @@ -35,7 +35,7 @@ void usage() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["4:3-4:6|4259594751088586730|3|16420"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 2fbc2f9c9..d27dadecb 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -25,7 +25,7 @@ void usage() { "derived": [], "vars": [16229832321010999607], "uses": [], - "callees": [] + "callees": ["7:6-7:9|17922201480358737771|3|16420"] }, { "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", @@ -37,7 +37,7 @@ void usage() { "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:9|15041163540773201510|2|16420"], + "uses": ["7:6-7:9|6767773193109753523|3|16420"], "callees": [] }], "usr2type": [{ @@ -56,7 +56,7 @@ void usage() { "funcs": [17922201480358737771], "vars": [], "instances": [16229832321010999607], - "uses": ["6:3-6:6|0|1|4"] + "uses": ["6:3-6:6|6767773193109753523|3|4"] }], "usr2var": [{ "usr": 16229832321010999607, diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index a70dcf5f2..422d59523 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -25,7 +25,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["5:3-5:9|10585861037135727329|3|16420", "6:3-6:9|10585861037135727329|3|16420"] }, { "usr": 10585861037135727329, "detailed_name": "void accept(T)", @@ -37,7 +37,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|0|1|16420", "6:3-6:9|0|1|16420"], + "uses": ["5:3-5:9|4259594751088586730|3|16420", "6:3-6:9|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index da797cfaf..74d2c0257 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -47,7 +47,7 @@ unique_ptr* return_type() { "funcs": [], "vars": [], "instances": [], - "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|0|1|4"] + "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|16359708726068806331|3|4"] }, { "usr": 4186953406371619898, "detailed_name": "unique_ptr", @@ -81,7 +81,7 @@ unique_ptr* return_type() { "funcs": [], "vars": [], "instances": [], - "uses": ["7:19-7:20|0|1|4", "9:12-9:13|0|1|4", "10:14-10:15|0|1|4"] + "uses": ["7:19-7:20|0|1|4", "9:12-9:13|0|1|4", "10:14-10:15|16359708726068806331|3|4"] }, { "usr": 16848604152578034754, "detailed_name": "unique_ptr", diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 97c57d7c4..7b5ebc54c 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -122,7 +122,7 @@ unique_ptr* Foo::foo() { return nullptr; } "storage": 0, "declarations": ["65:23-65:26|15041163540773201510|2|1025"], "spell": "79:26-79:29|15041163540773201510|2|1026", - "extent": "79:1-79:51|0|1|0", + "extent": "79:1-79:51|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], @@ -158,7 +158,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|0|1|4", "65:14-65:16|0|1|4", "79:12-79:14|0|1|4"] + "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|18320186404467436976|3|4", "65:14-65:16|15041163540773201510|2|4", "79:12-79:14|0|1|4"] }, { "usr": 7147635971744144194, "detailed_name": "template<> class unique_ptr", @@ -173,7 +173,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:19-15:29|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:14-54:24|0|1|4", "65:3-65:13|0|1|4", "79:1-79:11|0|1|4"] + "uses": ["15:19-15:29|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:14-54:24|18320186404467436976|3|4", "65:3-65:13|15041163540773201510|2|4", "79:1-79:11|0|1|4"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", @@ -188,7 +188,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:34-15:36|0|1|4", "15:39-15:41|0|1|4", "33:27-33:29|0|1|4", "33:32-33:34|0|1|4", "33:67-33:69|0|1|4", "54:29-54:31|0|1|4", "54:34-54:36|0|1|4", "65:18-65:20|0|1|4", "79:16-79:18|0|1|4"] + "uses": ["15:34-15:36|0|1|4", "15:39-15:41|0|1|4", "33:27-33:29|0|1|4", "33:32-33:34|0|1|4", "33:67-33:69|0|1|4", "54:29-54:31|18320186404467436976|3|4", "54:34-54:36|18320186404467436976|3|4", "65:18-65:20|15041163540773201510|2|4", "79:16-79:18|0|1|4"] }, { "usr": 14209198335088845323, "detailed_name": "class unique_ptr", @@ -237,7 +237,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [2933643612409209903, 500112618220246], - "uses": ["15:8-15:18|0|1|4", "33:1-33:11|0|1|4", "54:3-54:13|0|1|4"] + "uses": ["15:8-15:18|0|1|4", "33:1-33:11|0|1|4", "54:3-54:13|18320186404467436976|3|4"] }], "usr2var": [{ "usr": 500112618220246, diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index bd1323e95..60b3c7b7f 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -28,7 +28,7 @@ struct Foo { "funcs": [], "vars": [], "instances": [14727441168849658842], - "uses": ["6:3-6:18|0|1|4"] + "uses": ["6:3-6:18|15041163540773201510|2|4"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", @@ -43,7 +43,7 @@ struct Foo { "funcs": [], "vars": [], "instances": [14314859014962085433], - "uses": ["5:3-5:14|0|1|4"] + "uses": ["5:3-5:14|15041163540773201510|2|4"] }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 848ab490d..726dc8a26 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -43,7 +43,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [2580122838476012357], - "uses": ["6:3-6:18|0|1|4"] + "uses": ["6:3-6:18|4654328188330986029|3|4"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", @@ -58,7 +58,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [16374832544037266261], - "uses": ["5:3-5:14|0|1|4"] + "uses": ["5:3-5:14|4654328188330986029|3|4"] }], "usr2var": [{ "usr": 2580122838476012357, diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index e5c12bf9a..41dfc3250 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -43,7 +43,7 @@ void foo(Type& a0, const Type& a1) { "funcs": [], "vars": [], "instances": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], - "uses": ["3:10-3:14|0|1|4", "3:26-3:30|0|1|4", "4:3-4:7|0|1|4", "5:3-5:7|0|1|4", "6:9-6:13|0|1|4", "7:9-7:13|0|1|4"] + "uses": ["3:10-3:14|0|1|4", "3:26-3:30|0|1|4", "4:3-4:7|16858540520096802573|3|4", "5:3-5:7|16858540520096802573|3|4", "6:9-6:13|16858540520096802573|3|4", "7:9-7:13|16858540520096802573|3|4"] }], "usr2var": [{ "usr": 5004072032239834773, diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index bf825b69f..04e848602 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -31,7 +31,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["9:8-9:13|15041163540773201510|2|1025"], "spell": "13:11-13:16|15041163540773201510|2|1026", - "extent": "13:1-13:21|0|1|0", + "extent": "13:1-13:21|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], @@ -74,7 +74,7 @@ static Type* bar() { return nullptr; } "storage": 0, "declarations": ["8:9-8:12|15041163540773201510|2|1025"], "spell": "12:12-12:15|15041163540773201510|2|1026", - "extent": "12:1-12:40|0|1|0", + "extent": "12:1-12:40|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], @@ -110,7 +110,7 @@ static Type* bar() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["3:1-3:5|0|1|4", "4:1-4:5|0|1|4", "5:1-5:5|0|1|4", "8:3-8:7|0|1|4", "12:1-12:5|0|1|4", "15:14-15:18|0|1|4", "17:8-17:12|0|1|4", "18:8-18:12|0|1|4"] + "uses": ["3:1-3:5|0|1|4", "4:1-4:5|0|1|4", "5:1-5:5|0|1|4", "8:3-8:7|15041163540773201510|2|4", "12:1-12:5|0|1|4", "15:14-15:18|0|1|4", "17:8-17:12|0|1|4", "18:8-18:12|0|1|4"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index c313d4361..fead6f19a 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -23,7 +23,7 @@ extern Foo foo; "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|1025"], "spell": "5:11-5:15|15041163540773201510|2|1026", - "extent": "5:1-8:2|0|1|0", + "extent": "5:1-8:2|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [16380484338511689669], @@ -46,7 +46,7 @@ extern Foo foo; "funcs": [9488177941273031343], "vars": [], "instances": [16380484338511689669, 14455976355866885943], - "uses": ["2:3-2:6|0|1|4", "5:1-5:4|0|1|4", "5:6-5:9|0|1|4", "6:3-6:6|0|1|4", "10:8-10:11|0|1|4"] + "uses": ["2:3-2:6|15041163540773201510|2|4", "5:1-5:4|0|1|4", "5:6-5:9|0|1|4", "6:3-6:6|9488177941273031343|3|4", "10:8-10:11|0|1|4"] }], "usr2var": [{ "usr": 14455976355866885943, diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 78c2c340b..036671a40 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -33,7 +33,7 @@ void foo() { "derived": [], "vars": [8039186520399841081], "uses": [], - "callees": [] + "callees": ["14:3-14:9|18319417758892371313|3|16420", "14:14-14:17|11404602816585117695|3|16420"] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", @@ -45,7 +45,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:14-14:17|0|1|16420"], + "uses": ["14:14-14:17|4259594751088586730|3|16420"], "callees": [] }, { "usr": 18319417758892371313, @@ -58,7 +58,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|0|1|16420"], + "uses": ["14:3-14:9|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [{ @@ -95,7 +95,7 @@ void foo() { "R": 0 }], "instances": [], - "uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"] + "uses": ["10:5-10:8|0|1|4", "14:22-14:25|4259594751088586730|3|4", "14:40-14:43|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 8039186520399841081, @@ -119,7 +119,7 @@ void foo() { "spell": "7:7-7:16|15041163540773201510|2|1026", "extent": "7:3-7:16|15041163540773201510|2|0", "type": 53, - "uses": ["14:28-14:37|15041163540773201510|2|12"], + "uses": ["14:28-14:37|4259594751088586730|3|12"], "kind": 8, "storage": 0 }, { @@ -129,9 +129,9 @@ void foo() { "short_name": "static_var", "declarations": ["6:14-6:24|15041163540773201510|2|1025"], "spell": "10:10-10:20|15041163540773201510|2|1026", - "extent": "10:1-10:24|0|1|0", + "extent": "10:1-10:24|15041163540773201510|2|0", "type": 53, - "uses": ["14:45-14:55|0|1|12"], + "uses": ["14:45-14:55|4259594751088586730|3|12"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 0dc7dcd85..9bb67ba9c 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -25,7 +25,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["6:3-6:9|18319417758892371313|3|16420", "6:10-6:13|11404602816585117695|3|16420", "6:18-6:21|11404602816585117695|3|16420"] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", @@ -39,7 +39,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:10-6:13|0|1|16420", "6:18-6:21|0|1|16420"], + "uses": ["6:10-6:13|4259594751088586730|3|16420", "6:18-6:21|4259594751088586730|3|16420"], "callees": [] }, { "usr": 18319417758892371313, @@ -52,7 +52,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:9|0|1|16420"], + "uses": ["6:3-6:9|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index ee39a73ca..5ac9d0fad 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -25,7 +25,7 @@ void caller() { "bases": [], "derived": [], "vars": [], - "uses": ["4:13-4:19|0|1|132", "7:3-7:9|0|1|16420"], + "uses": ["4:13-4:19|11404881820527069090|3|132", "7:3-7:9|11404881820527069090|3|16420"], "callees": [] }, { "usr": 11404881820527069090, @@ -41,7 +41,7 @@ void caller() { "derived": [], "vars": [9121974011454213596], "uses": [], - "callees": [] + "callees": ["4:13-4:19|468307235068920063|3|132", "4:13-4:19|468307235068920063|3|132", "7:3-7:9|468307235068920063|3|16420"] }], "usr2type": [], "usr2var": [{ diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 0433edb32..93667b6d7 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -36,7 +36,7 @@ void foo() { "derived": [], "vars": [14669930844300034456], "uses": [], - "callees": [] + "callees": ["14:3-14:9|17175780305784503374|3|16420", "15:3-15:9|17175780305784503374|3|16420", "16:3-16:9|12086644540399881766|3|16420", "17:3-17:9|17175780305784503374|3|16420"] }, { "usr": 12086644540399881766, "detailed_name": "void accept(int *)", @@ -48,7 +48,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["16:3-16:9|0|1|16420"], + "uses": ["16:3-16:9|4259594751088586730|3|16420"], "callees": [] }, { "usr": 17175780305784503374, @@ -61,7 +61,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|0|1|16420", "15:3-15:9|0|1|16420", "17:3-17:9|0|1|16420"], + "uses": ["14:3-14:9|4259594751088586730|3|16420", "15:3-15:9|4259594751088586730|3|16420", "17:3-17:9|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [{ @@ -101,7 +101,7 @@ void foo() { "R": 32 }], "instances": [14669930844300034456], - "uses": ["11:3-11:6|0|1|4"] + "uses": ["11:3-11:6|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 3873837747174060388, @@ -112,7 +112,7 @@ void foo() { "spell": "4:7-4:8|15041163540773201510|2|1026", "extent": "4:3-4:8|15041163540773201510|2|0", "type": 53, - "uses": ["17:12-17:13|15041163540773201510|2|12"], + "uses": ["17:12-17:13|4259594751088586730|3|12"], "kind": 8, "storage": 0 }, { @@ -124,7 +124,7 @@ void foo() { "spell": "3:7-3:8|15041163540773201510|2|1026", "extent": "3:3-3:8|15041163540773201510|2|0", "type": 53, - "uses": ["12:5-12:6|15041163540773201510|2|20", "13:5-13:6|15041163540773201510|2|4", "14:12-14:13|15041163540773201510|2|12", "15:12-15:13|15041163540773201510|2|12", "16:13-16:14|15041163540773201510|2|132"], + "uses": ["12:5-12:6|4259594751088586730|3|20", "13:5-13:6|4259594751088586730|3|4", "14:12-14:13|4259594751088586730|3|12", "15:12-15:13|4259594751088586730|3|12", "16:13-16:14|4259594751088586730|3|132"], "kind": 8, "storage": 0 }, { diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 28e6da571..6f2eee7d4 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -27,7 +27,7 @@ void foo() { "derived": [], "vars": [], "uses": [], - "callees": [] + "callees": ["8:3-8:9|17175780305784503374|3|16420"] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", @@ -39,7 +39,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|0|1|16420"], + "uses": ["8:3-8:9|4259594751088586730|3|16420"], "callees": [] }], "usr2type": [{ @@ -73,7 +73,7 @@ void foo() { "funcs": [], "vars": [], "instances": [], - "uses": ["8:10-8:13|0|1|4"] + "uses": ["8:10-8:13|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 8599782646965457351, @@ -82,7 +82,7 @@ void foo() { "short_name": "x", "declarations": ["2:14-2:15|15041163540773201510|2|1025"], "type": 53, - "uses": ["8:15-8:16|15041163540773201510|2|12"], + "uses": ["8:15-8:16|4259594751088586730|3|12"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 1f2bcb068..1233becc1 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -29,7 +29,7 @@ const VarType Holder::static_var; "funcs": [], "vars": [], "instances": [7057400933868440116, 7057400933868440116], - "uses": ["4:20-4:27|0|1|4", "4:42-4:49|0|1|4", "7:7-7:14|0|1|4"] + "uses": ["4:20-4:27|10028537921178202800|2|4", "4:42-4:49|10028537921178202800|2|4", "7:7-7:14|0|1|4"] }, { "usr": 10028537921178202800, "detailed_name": "struct Holder {}", @@ -56,7 +56,7 @@ const VarType Holder::static_var; "hover": "static constexpr VarType Holder::static_var = (VarType)0x0", "declarations": ["4:28-4:38|10028537921178202800|2|1025"], "spell": "7:23-7:33|10028537921178202800|2|1026", - "extent": "7:1-7:33|0|1|0", + "extent": "7:1-7:33|10028537921178202800|2|0", "type": 5792006888140599735, "uses": [], "kind": 13, diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index fe5c928f7..09442598c 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -47,7 +47,7 @@ void foo() { "short_name": "a", "declarations": ["1:12-1:13|0|1|1"], "type": 53, - "uses": ["4:3-4:4|0|1|20"], + "uses": ["4:3-4:4|4259594751088586730|3|20"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 873fc5dbd..5000ec776 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -50,7 +50,7 @@ void foo() { "spell": "1:12-1:13|0|1|2", "extent": "1:1-1:13|0|1|0", "type": 53, - "uses": ["4:3-4:4|0|1|20"], + "uses": ["4:3-4:4|4259594751088586730|3|20"], "kind": 13, "storage": 2 }] diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 7eb364a58..4b3925a73 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -26,7 +26,7 @@ class Foo { "R": 0 }], "instances": [13799811842374292251], - "uses": ["2:3-2:6|0|1|4"] + "uses": ["2:3-2:6|15041163540773201510|2|4"] }], "usr2var": [{ "usr": 13799811842374292251, diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index b4c4784d0..1dcb0699e 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -25,7 +25,7 @@ Foo* Foo::member = nullptr; "funcs": [], "vars": [], "instances": [5844987037615239736, 5844987037615239736], - "uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] + "uses": ["2:10-2:13|15041163540773201510|2|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] }], "usr2var": [{ "usr": 5844987037615239736, @@ -34,7 +34,7 @@ Foo* Foo::member = nullptr; "short_name": "member", "declarations": ["2:15-2:21|15041163540773201510|2|1025"], "spell": "4:11-4:17|15041163540773201510|2|1026", - "extent": "4:1-4:27|0|1|0", + "extent": "4:1-4:27|15041163540773201510|2|0", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 2212b9afe..3823df908 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -41,7 +41,7 @@ void f() { "funcs": [], "vars": [], "instances": [10601729374837386290, 18422884837902130475], - "uses": ["3:16-3:19|0|1|4", "4:17-4:20|0|1|4"] + "uses": ["3:16-3:19|880549676430489861|3|4", "4:17-4:20|880549676430489861|3|4"] }], "usr2var": [{ "usr": 10601729374837386290, diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 8090f1cdf..b6197c40b 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -39,7 +39,7 @@ void foo() { "funcs": [], "vars": [], "instances": [13198746475679542317], - "uses": ["4:3-4:6|0|1|4"] + "uses": ["4:3-4:6|4259594751088586730|3|4"] }], "usr2var": [{ "usr": 13198746475679542317, diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 229959d52..7a6ebcf6b 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -60,7 +60,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [6975456769752895964], - "uses": ["4:3-4:4|0|1|4"] + "uses": ["4:3-4:4|4654328188330986029|3|4"] }], "usr2var": [{ "usr": 6975456769752895964, diff --git a/src/indexer.cc b/src/indexer.cc index c8a00bd53..b7c908508 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -495,6 +495,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); + Twine Static("static "); Twine T = Buf.count('\n') <= kInitializerMaxLines - 1 ? def.detailed_name + (Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) @@ -502,7 +503,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { : def.detailed_name; def.hover = def.storage == SC_Static && strncmp(def.detailed_name, "static ", 7) - ? Intern(("static " + T).str()) + ? Intern((Static + T).str()) : Intern(T.str()); } } @@ -594,7 +595,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { const Decl* OrigD = ASTNode.OrigD; const DeclContext *SemDC = OrigD->getDeclContext(); - const DeclContext *LexDC = OrigD->getLexicalDeclContext(); + const DeclContext *LexDC = ASTNode.ContainerDC; Role role = static_cast(Roles); db->language = std::max(db->language, GetDeclLanguage(OrigD)); @@ -642,9 +643,14 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (func->def.detailed_name[0] == '\0') SetName(OrigD, info->short_name, info->qualified, func->def); if (is_def || is_decl) { - const Decl* DC = cast(SemDC); + const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) db->ToType(GetUsr(DC)).def.funcs.push_back(usr); + } else { + const Decl *DC = cast(LexDC); + if (GetSymbolKind(DC) == SymbolKind::Func) + db->ToFunc(GetUsr(DC)) + .def.callees.push_back({{loc, usr, SymbolKind::Func, role}}); } break; case SymbolKind::Type: @@ -673,7 +679,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { else if (auto *FD = dyn_cast(D)) T = FD->getType(); if (is_def || is_decl) { - const Decl* DC = cast(SemDC); + const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Func) db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); else if (auto *ND = dyn_cast(SemDC)) @@ -866,8 +872,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::Function: func->def.kind = lsSymbolKind::Function; break; - case Decl::CXXMethod: - func->def.kind = lsSymbolKind::Method; + case Decl::CXXMethod: { + const auto *MD = cast(D); + func->def.kind = + MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method; if (is_def || is_decl) { if (auto *ND = dyn_cast(D)) { SmallVector OverDecls; @@ -880,6 +888,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } break; + } case Decl::CXXConstructor: case Decl::CXXConversion: func->def.kind = lsSymbolKind::Constructor; diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index e40244c40..03cfcca3e 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -207,7 +207,7 @@ struct Handler_CclsMemberHierarchy Out_CclsMemberHierarchy::Entry entry; // Not type, |id| is invalid. - entry.name = std::string(def->Name(qualified)); + entry.name = def->Name(qualified); if (def->spell) { if (std::optional loc = GetLsLocation(db, working_files, *def->spell)) From 8b4a8d2d485295d4e2eea8501dc8f601c517e84f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 22 Jul 2018 20:10:04 -0700 Subject: [PATCH 158/378] Fix Twine; index TypedefNameDecl to specialization; anonymous RecordDecl fields --- index_tests/types/anonymous_struct.cc | 10 +++- .../type_usage_typedef_and_using_template.cc | 2 +- src/indexer.cc | 51 +++++++++++++------ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index ef3810131..8a75ecf95 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -65,11 +65,17 @@ union vector3 { "types": [1428566502523368801], "funcs": [], "vars": [{ - "L": 12549098950381705776, + "L": 1963212417280098348, "R": 0 }, { - "L": 1963212417280098348, + "L": 3348817847649945564, "R": 0 + }, { + "L": 4821094820988543895, + "R": 32 + }, { + "L": 15292551660437765731, + "R": 64 }], "instances": [], "uses": [] diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index 5e958e455..c93284777 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -81,7 +81,7 @@ typedef Foo Foo2; "declarations": [], "spell": "5:19-5:23|0|1|2", "extent": "5:1-5:23|0|1|0", - "alias_of": 0, + "alias_of": 14491685842684954828, "bases": [], "derived": [], "types": [], diff --git a/src/indexer.cc b/src/indexer.cc index b7c908508..f4398f6fd 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -207,7 +207,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) { return BaseType; } -const Decl* GetTypeDecl(QualType T) { +const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { Decl *D = nullptr; T = GetBaseType(T.getUnqualifiedType(), true); const Type* TP = T.getTypePtrOrNull(); @@ -233,6 +233,8 @@ const Decl* GetTypeDecl(QualType T) { D = cast(TP)->getDecl(); break; case Type::TemplateSpecialization: + if (specialization) + *specialization = true; if (const RecordType *Record = TP->getAs()) D = Record->getDecl(); else @@ -495,15 +497,14 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); - Twine Static("static "); - Twine T = Buf.count('\n') <= kInitializerMaxLines - 1 - ? def.detailed_name + (Buf.size() && Buf[0] == ':' - ? Twine(" ", Buf) - : Twine(" = ", Buf)) - : def.detailed_name; + Twine Init = Buf.count('\n') <= kInitializerMaxLines - 1 + ? Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) + : Twine(" = ", Buf) + : Twine(); + Twine T = def.detailed_name + Init; def.hover = def.storage == SC_Static && strncmp(def.detailed_name, "static ", 7) - ? Intern((Static + T).str()) + ? Intern(("static " + T).str()) : Intern(T.str()); } } @@ -814,11 +815,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; if (is_def) { - bool can_get_offset = - RD->isCompleteDefinition() && !RD->isDependentType(); - for (FieldDecl *FD : RD->fields()) - type->def.vars.emplace_back( - GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); + SmallVector, 2> Stack{{RD, 0}}; + while (Stack.size()) { + int offset; + std::tie(RD, offset) = Stack.back(); + Stack.pop_back(); + if (!RD->isCompleteDefinition() || RD->isDependentType()) + offset = -1; + for (FieldDecl *FD : RD->fields()) { + int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; + if (FD->getIdentifier()) + type->def.vars.emplace_back(GetUsr(FD), offset1); + else if (const auto *RT1 = FD->getType()->getAs()) + Stack.push_back({RT1->getDecl(), offset1}); + } + } } } break; @@ -854,11 +865,19 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::UnresolvedUsingTypename: type->def.kind = lsSymbolKind::TypeAlias; if (auto *TD = dyn_cast(D)) { + bool specialization = false; QualType T = TD->getUnderlyingType(); - if (const Decl* D1 = GetTypeDecl(T)) { + if (const Decl *D1 = GetTypeDecl(T, &specialization)) { Usr usr1 = GetUsr(D1); - if (db->usr2type.count(usr1)) - type->def.alias_of = usr1; + IndexType &type1 = db->ToType(usr1); + type->def.alias_of = usr1; + // Not visited template struct B {typedef A t;}; + if (specialization) { + const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); + SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); + Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); + type1.uses.push_back(GetUse(db, loc1, LexDC, Role::Reference)); + } } } break; From ff102c9b7eb0e4f11c85041fd03ba99d76d7efae Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Wed, 25 Jul 2018 11:08:00 +0800 Subject: [PATCH 159/378] Fix preload completion session. --- src/clang_complete.cc | 3 +-- src/messages/textDocument_didOpen.cc | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 1fa09840b..15656eb29 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -368,8 +368,7 @@ void TryEnsureDocumentParsed(ClangCompleteManager *manager, WorkingFiles::Snapshot snapshot = session->working_files->AsSnapshot( {StripFileType(session->file.filename)}); - LOG_S(INFO) << "Creating completion session with arguments " - << StringJoin(args, " "); + LOG_S(INFO) << "create completion session for " << session->file.filename; *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot, diagnostic); } diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 70ae716b6..9f6eea539 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -50,9 +50,6 @@ struct Handler_TextDocumentDidOpen } include_complete->AddFile(working_file->filename); - clang_complete->NotifyView(path); - if (g_config->diagnostics.onParse) - clang_complete->DiagnosticsUpdate({params.textDocument.uri}); if (params.args.size()) project->SetFlagsForFile(params.args, path); @@ -64,6 +61,10 @@ struct Handler_TextDocumentDidOpen clang_complete->FlushSession(entry.filename); } + + clang_complete->NotifyView(path); + if (g_config->diagnostics.onParse) + clang_complete->DiagnosticsUpdate({params.textDocument.uri}); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); From 03aa024fe636aafda41fa00b1f49a541ae1fdc23 Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Wed, 25 Jul 2018 11:25:13 +0800 Subject: [PATCH 160/378] Misc. --- CMakeLists.txt | 7 ++----- src/match.cc | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a901f763..19af412f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,15 +123,12 @@ endif() ### Definitions target_compile_definitions(ccls PRIVATE - LOGURU_WITH_STREAMS=1 - LOGURU_FILENAME_WIDTH=18 - LOGURU_THREADNAME_WIDTH=13 DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}") ### Includes -target_include_directories(ccls PRIVATE - src +target_include_directories(ccls PRIVATE src) +target_include_directories(ccls SYSTEM PRIVATE third_party third_party/rapidjson/include) diff --git a/src/match.cc b/src/match.cc index 58a6f73d0..5dd467272 100644 --- a/src/match.cc +++ b/src/match.cc @@ -25,7 +25,7 @@ std::optional Matcher::Create(const std::string& search) { // std::regex_constants::nosubs ); return m; - } catch (std::exception e) { + } catch (const std::exception& e) { Out_ShowLogMessage out; out.display_type = Out_ShowLogMessage::DisplayType::Show; out.params.type = lsMessageType::Error; From 122eda1c53edf49cf2dbf912b127796d86603800 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 25 Jul 2018 10:36:30 -0700 Subject: [PATCH 161/378] Improve comment and outline --- index_tests/macros/complex.cc | 2 +- index_tests/macros/foo.cc | 2 +- index_tests/multi_file/funky_enum.h | 2 +- src/indexer.cc | 13 ++++++++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 1b17ea8e5..a74be500b 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -25,7 +25,7 @@ FOO(make1(), make2); "storage": 0, "declarations": ["12:1-12:20|0|1|1"], "spell": "12:1-12:20|0|1|2", - "extent": "1:1-1:1|0|1|0", + "extent": "12:1-12:20|0|1|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index c2086d470..9c034cd2f 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -21,7 +21,7 @@ int x = A; "storage": 0, "declarations": [], "spell": "5:12-5:15|15041163540773201510|2|1026", - "extent": "1:1-1:1|15041163540773201510|2|0", + "extent": "5:12-5:15|15041163540773201510|2|0", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/multi_file/funky_enum.h b/index_tests/multi_file/funky_enum.h index b11cc4419..1acdf0566 100644 --- a/index_tests/multi_file/funky_enum.h +++ b/index_tests/multi_file/funky_enum.h @@ -3,4 +3,4 @@ A, B, -C \ No newline at end of file +C diff --git a/src/indexer.cc b/src/indexer.cc index f4398f6fd..1325cf6ff 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -338,7 +338,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { p++; if (p < E && *p == ' ') p++; - pad = int(p - begin); + if (p + 1 == q) + p++; + else + pad = int(p - begin); } else { // Other lines, skip |pad| bytes int prefix = pad; @@ -614,9 +617,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto do_def_decl = [&](auto *entity) { if (is_def) { entity->def.spell = GetUse(db, loc, SemDC, role); + SourceRange R = OrigD->getSourceRange(); entity->def.extent = - GetUse(db, FromTokenRange(SM, Lang, OrigD->getSourceRange()), LexDC, - Role::None); + GetUse(db, + R.getBegin().isFileID() + ? FromTokenRange(SM, Lang, OrigD->getSourceRange()) + : loc, + LexDC, Role::None); } else if (is_decl) { entity->declarations.push_back(GetUse(db, loc, LexDC, role)); } else { From b95b47540d09a522bafefa4f95eb9bea8c04e9be Mon Sep 17 00:00:00 2001 From: Chao Shen Date: Fri, 27 Jul 2018 11:08:22 +0800 Subject: [PATCH 162/378] Fix diagnostics on MacOS and duplicated bases. --- index_tests/namespaces/namespace_alias.cc | 4 ++-- src/clang_tu.cc | 3 ++- src/indexer.cc | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 118e20c7e..b659f5533 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -87,7 +87,7 @@ void func() { "kind": 3, "declarations": ["3:20-3:23|17805385787823406700|2|1025"], "alias_of": 0, - "bases": [17805385787823406700, 17805385787823406700, 17805385787823406700, 17805385787823406700], + "bases": [17805385787823406700], "derived": [], "types": [], "funcs": [], @@ -105,7 +105,7 @@ void func() { "kind": 3, "declarations": ["2:15-2:18|926793467007732869|2|1025"], "alias_of": 0, - "bases": [926793467007732869, 926793467007732869, 926793467007732869, 926793467007732869], + "bases": [926793467007732869], "derived": [14450849931009540802], "types": [14450849931009540802], "funcs": [], diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 64c4a4ece..bc40e4043 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -85,7 +85,8 @@ std::unique_ptr ClangTranslationUnit::Create( Unit.reset(ASTUnit::LoadFromCommandLine( Args.data(), Args.data() + Args.size(), /*PCHContainerOpts=*/ret->PCHCO, Diags, - /*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false, + /*ResourceFilePath=*/g_config->clang.resourceDir, + /*OnlyLocalDecls=*/false, /*CaptureDiagnostics=*/diagnostic, Remapped, /*RemappedFilesKeepOriginalName=*/true, 1, diagnostic ? TU_Complete : TU_Prefix, diff --git a/src/indexer.cc b/src/indexer.cc index 1325cf6ff..809998629 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1221,6 +1221,7 @@ std::vector> Index( Uniquify(it.second.derived); Uniquify(it.second.uses); // e.g. declaration + out-of-line definition + Uniquify(it.second.def.bases); Uniquify(it.second.def.funcs); } for (auto& it : entry->usr2var) From c71047189f48daf6b844d9d97b4ba1d452dc3028 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 27 Jul 2018 00:21:57 -0700 Subject: [PATCH 163/378] Misc --- index_tests/macros/foo.cc | 2 +- ...espace_template_type_usage_folded_into_one.cc | 4 ++-- index_tests/templates/specialization.cc | 2 +- .../template_type_usage_folded_into_one.cc | 2 +- index_tests/unions/union_decl.cc | 4 ++-- index_tests/unions/union_usage.cc | 4 ++-- index_tests/usage/type_usage_declare_extern.cc | 2 +- index_tests/usage/type_usage_declare_field.cc | 4 ++-- index_tests/usage/type_usage_declare_local.cc | 2 +- index_tests/usage/type_usage_declare_static.cc | 2 +- index_tests/usage/var_usage_static.cc | 2 +- src/include_complete.cc | 10 +++++----- src/indexer.cc | 16 +++++++++++++--- src/project.cc | 7 +++++-- 14 files changed, 38 insertions(+), 25 deletions(-) diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 9c034cd2f..7b7c8b047 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -92,7 +92,7 @@ int x = A; "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", - "hover": "int x = ", + "hover": "int x = A", "declarations": [], "spell": "8:5-8:6|0|1|2", "extent": "8:1-1:1|0|1|0", diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 8563a02e7..5b141b398 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -87,8 +87,8 @@ namespace ns { }], "usr2var": [{ "usr": 3182917058194750998, - "detailed_name": "Foo b", - "qual_name_offset": 4, + "detailed_name": "Foo ns::b", + "qual_name_offset": 10, "short_name": "b", "declarations": [], "spell": "6:13-6:14|11072669167287398027|2|1026", diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index c6345002b..f5ca0f26a 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -367,7 +367,7 @@ void foo(float Value); }, { "usr": 2933643612409209903, "detailed_name": "function f", - "qual_name_offset": 0, + "qual_name_offset": 21, "short_name": "f", "declarations": [], "spell": "7:21-7:22|0|1|2", diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 863998925..0c83f7d8c 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -65,7 +65,7 @@ Foo b; "usr2var": [{ "usr": 12028309045033782423, "detailed_name": "Foo b", - "qual_name_offset": 4, + "qual_name_offset": 10, "short_name": "b", "declarations": [], "spell": "5:11-5:12|0|1|2", diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 9a3ae5f98..83b94e90f 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -65,8 +65,8 @@ union Foo { }], "usr2var": [{ "usr": 8804696910588009104, - "detailed_name": "Foo::bool b", - "qual_name_offset": 0, + "detailed_name": "bool Foo::b", + "qual_name_offset": 5, "short_name": "b", "declarations": [], "spell": "3:8-3:9|8501689086387244262|2|1026", diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 8682aae20..253c4a345 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -100,8 +100,8 @@ void act(Foo*) { "storage": 0 }, { "usr": 8804696910588009104, - "detailed_name": "Foo::bool b : 3", - "qual_name_offset": 0, + "detailed_name": "bool Foo::b : 3", + "qual_name_offset": 5, "short_name": "b", "declarations": [], "spell": "3:8-3:9|8501689086387244262|2|1026", diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index f03978d73..2fd672160 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -28,7 +28,7 @@ extern T t; "usr2var": [{ "usr": 1346710425945444872, "detailed_name": "extern T t", - "qual_name_offset": 0, + "qual_name_offset": 9, "short_name": "t", "declarations": ["3:10-3:11|0|1|1"], "type": 5673439900521455039, diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 60b3c7b7f..114d6a860 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -70,8 +70,8 @@ struct Foo { }], "usr2var": [{ "usr": 14314859014962085433, - "detailed_name": "ForwFoo::ardType *a", - "qual_name_offset": 0, + "detailed_name": "ForwardType *Foo::a", + "qual_name_offset": 13, "short_name": "a", "declarations": [], "spell": "5:16-5:17|15041163540773201510|2|1026", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 726dc8a26..0b037bc5b 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -75,7 +75,7 @@ void Foo() { }, { "usr": 16374832544037266261, "detailed_name": "ForwardType *a", - "qual_name_offset": 0, + "qual_name_offset": 13, "short_name": "a", "declarations": [], "spell": "5:16-5:17|4654328188330986029|3|2", diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index 55225b5e1..102c156af 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -27,7 +27,7 @@ static Type t; "usr2var": [{ "usr": 6601831367240627080, "detailed_name": "static Type t", - "qual_name_offset": 0, + "qual_name_offset": 12, "short_name": "t", "declarations": [], "spell": "2:13-2:14|0|1|2", diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 5000ec776..9c8258305 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -44,7 +44,7 @@ void foo() { "usr2var": [{ "usr": 11823161916242867318, "detailed_name": "static int a", - "qual_name_offset": 0, + "qual_name_offset": 11, "short_name": "a", "declarations": [], "spell": "1:12-1:13|0|1|2", diff --git a/src/include_complete.cc b/src/include_complete.cc index 89c082c8e..7412f6b11 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -162,16 +162,16 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets) { directory = NormalizePath(directory); EnsureEndsInSlash(directory); - if (match_ && !match_->IsMatch(directory)) { - // Don't even enter the directory if it fails the patterns. + if (match_ && !match_->IsMatch(directory)) return; - } + bool include_cpp = directory.find("include/c++") != std::string::npos; std::vector results; GetFilesInFolder( directory, true /*recursive*/, false /*add_folder_to_path*/, - [&](const std::string& path) { - if (!EndsWithAny(path, g_config->completion.includeSuffixWhitelist)) + [&](const std::string &path) { + if (!include_cpp && + !EndsWithAny(path, g_config->completion.includeSuffixWhitelist)) return; if (match_ && !match_->IsMatch(directory + path)) return; diff --git a/src/indexer.cc b/src/indexer.cc index 809998629..1274518f3 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -434,6 +434,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { std::string name = OS.str(); SimplifyAnonymous(name); auto i = name.find(short_name); + if (short_name.size()) + while (i != std::string::npos && ((i && isalnum(name[i - 1])) || + isalnum(name[i + short_name.size()]))) + i = name.find(short_name, i + short_name.size()); if (i == std::string::npos) { // e.g. operator type-parameter-1 i = 0; @@ -495,7 +499,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (init) { SourceManager &SM = Ctx->getSourceManager(); const LangOptions& Lang = Ctx->getLangOpts(); - SourceRange R = init->getSourceRange(); + SourceRange R = SM.getExpansionRange(init->getSourceRange()) +#if LLVM_VERSION_MAJOR >= 7 + .getAsRange() +#endif + ; SourceLocation L = D->getLocation(); if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; @@ -882,8 +890,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (specialization) { const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); - Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); - type1.uses.push_back(GetUse(db, loc1, LexDC, Role::Reference)); + if (SM.getFileID(L1) == LocFID) { + Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); + type1.uses.push_back(GetUse(db, loc1, LexDC, Role::Reference)); + } } } } diff --git a/src/project.cc b/src/project.cc index b564b591e..3b1b0b1dc 100644 --- a/src/project.cc +++ b/src/project.cc @@ -17,6 +17,7 @@ using namespace ccls; #include #include #include +#include #include using namespace clang; using namespace llvm; @@ -296,14 +297,16 @@ std::vector LoadCompilationEntriesFromDirectory( LOG_S(INFO) << "loaded " << Path.c_str(); + StringSet<> Seen; std::vector result; for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { CompileCommandsEntry entry; entry.directory = std::move(Cmd.Directory); entry.file = entry.ResolveIfRelative(Cmd.Filename); entry.args = std::move(Cmd.CommandLine); - result.push_back( - GetCompilationEntryFromCompileCommandEntry(project, entry)); + auto entry1 = GetCompilationEntryFromCompileCommandEntry(project, entry); + if (Seen.insert(entry1.filename).second) + result.push_back(entry1); } return result; } From 0bb311ac56ad107f2241ee26128a7fd0455c8533 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 28 Jul 2018 21:32:41 -0700 Subject: [PATCH 164/378] Add textDocument/codeAction for clang FixIt What do you think of the challenge ccls-fringe in Real World CTF? --- CMakeLists.txt | 1 + src/clang_complete.cc | 5 +- src/clang_tu.cc | 23 ++++---- src/clang_tu.h | 5 ++ src/indexer.cc | 9 +-- src/messages/textDocument_codeAction.cc | 77 +++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 src/messages/textDocument_codeAction.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 19af412f1..776fa8b89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,7 @@ target_sources(ccls PRIVATE src/messages/exit.cc src/messages/initialize.cc src/messages/shutdown.cc + src/messages/textDocument_codeAction.cc src/messages/textDocument_codeLens.cc src/messages/textDocument_completion.cc src/messages/textDocument_definition.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 15656eb29..2f1a019b5 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -368,7 +368,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager *manager, WorkingFiles::Snapshot snapshot = session->working_files->AsSnapshot( {StripFileType(session->file.filename)}); - LOG_S(INFO) << "create completion session for " << session->file.filename; + LOG_S(INFO) << "create " << (diagnostic ? "diagnostic" : "completion") + << " TU for " << session->file.filename; *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot, diagnostic); } @@ -541,7 +542,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { for (const FixItHint &FixIt : I->getFixIts()) { lsTextEdit edit; edit.newText = FixIt.CodeToInsert; - r = FromCharRange(SM, LangOpts, FixIt.RemoveRange.getAsRange()); + r = FromCharSourceRange(SM, LangOpts, FixIt.RemoveRange); edit.range = lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; ls_diag.fixits_.push_back(edit); diff --git a/src/clang_tu.cc b/src/clang_tu.cc index bc40e4043..ab43e81e1 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -12,13 +12,13 @@ using namespace clang; #include #include -Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, llvm::sys::fs::UniqueID *UniqueID, - bool token) { +Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts, + CharSourceRange R, + llvm::sys::fs::UniqueID *UniqueID) { SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); std::pair BInfo = SM.getDecomposedLoc(BLoc); std::pair EInfo = SM.getDecomposedLoc(ELoc); - if (token) + if (R.isTokenRange()) EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1, c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1, @@ -42,15 +42,15 @@ Range FromSourceRange(const SourceManager &SM, const LangOptions &LangOpts, } Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, - llvm::sys::fs::UniqueID *UniqueID) { - return FromSourceRange(SM, LangOpts, R, UniqueID, false); + SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { + return FromCharSourceRange(SM, LangOpts, CharSourceRange::getCharRange(R), + UniqueID); } Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, - SourceRange R, - llvm::sys::fs::UniqueID *UniqueID) { - return FromSourceRange(SM, LangOpts, R, UniqueID, true); + SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { + return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R), + UniqueID); } std::vector @@ -70,8 +70,9 @@ std::unique_ptr ClangTranslationUnit::Create( std::vector Args; for (auto& arg : args) Args.push_back(arg.c_str()); - Args.push_back("-fno-spell-checking"); Args.push_back("-fallow-editor-placeholders"); + if (!diagnostic) + Args.push_back("-fno-spell-checking"); auto ret = std::make_unique(); IntrusiveRefCntPtr Diags( diff --git a/src/clang_tu.h b/src/clang_tu.h index a20ad74e7..c92538780 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -14,6 +14,11 @@ std::vector GetRemapped(const WorkingFiles::Snapshot &snapshot); +Range FromCharSourceRange(const clang::SourceManager &SM, + const clang::LangOptions &LangOpts, + clang::CharSourceRange R, + llvm::sys::fs::UniqueID *UniqueID = nullptr); + Range FromCharRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); diff --git a/src/indexer.cc b/src/indexer.cc index 1274518f3..523c04afd 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -596,7 +596,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) : SM.getExpansionRange(Loc); #endif - loc = FromTokenRange(SM, Lang, R.getAsRange()); + loc = FromCharSourceRange(SM, Lang, R); LocFID = SM.getFileID(R.getBegin()); FE = SM.getFileEntryForID(LocFID); if (!FE) @@ -995,9 +995,10 @@ class IndexPPCallbacks : public PPCallbacks { if (!File) return; llvm::sys::fs::UniqueID UniqueID; - SourceRange R = FilenameRange.getAsRange(); - auto spell = FromCharRange(SM, param.Ctx->getLangOpts(), R, &UniqueID); - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + auto spell = FromCharSourceRange(SM, param.Ctx->getLangOpts(), + FilenameRange, &UniqueID); + const FileEntry *FE = + SM.getFileEntryForID(SM.getFileID(FilenameRange.getBegin())); if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc new file mode 100644 index 000000000..2832cfca0 --- /dev/null +++ b/src/messages/textDocument_codeAction.cc @@ -0,0 +1,77 @@ +#include "message_handler.h" +#include "pipeline.hh" +#include "working_files.h" +using namespace ccls; + +struct CommandArgs { + lsDocumentUri textDocumentUri; + std::vector edits; +}; +MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(CommandArgs, textDocumentUri, edits); + +namespace { +MethodType kMethodType = "textDocument/codeAction"; + +struct In_TextDocumentCodeAction : public RequestInMessage { + MethodType GetMethodType() const override { return kMethodType; } + + // Contains additional diagnostic information about the context in which + // a code action is run. + struct lsCodeActionContext { + // An array of diagnostics. + std::vector diagnostics; + }; + // Params for the CodeActionRequest + struct lsCodeActionParams { + // The document in which the command was invoked. + lsTextDocumentIdentifier textDocument; + // The range for which the command was invoked. + lsRange range; + // Context carrying additional information. + lsCodeActionContext context; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, + diagnostics); +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, + textDocument, + range, + context); +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); + +struct Out_TextDocumentCodeAction + : public lsOutMessage { + lsRequestId id; + std::vector> result; +}; +MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result); + +struct Handler_TextDocumentCodeAction + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + + void Run(In_TextDocumentCodeAction* request) override { + const auto ¶ms = request->params; + WorkingFile *wfile = + working_files->GetFileByFilename(params.textDocument.uri.GetPath()); + if (!wfile) + return; + Out_TextDocumentCodeAction out; + out.id = request->id; + std::vector diagnostics; + working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); + for (lsDiagnostic &diag : diagnostics) + if (diag.fixits_.size()) { + lsCommand command; + command.title = "FixIt: " + diag.message; + command.command = "ccls._applyFixIt"; + command.arguments.textDocumentUri = params.textDocument.uri; + command.arguments.edits = diag.fixits_; + out.result.push_back(command); + } + pipeline::WriteStdout(kMethodType, out); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); +} From b4aa0705a1c421d16c0c3f98a2542f6f6285dae0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 29 Jul 2018 15:17:59 -0700 Subject: [PATCH 165/378] cmake: for -DSYSTEM_CLANG=off, 6.0.0 -> 6.0.1 --- CMakeLists.txt | 149 +++++++++--------- .../LLVM-6.0.0-win64.exe.SHA256 | 1 - .../LLVM-6.0.1-win64.exe.SHA256 | 1 + ...0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 | 1 - ...86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 - ...86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 - ....0.1-amd64-unknown-freebsd10.tar.xz.SHA256 | 1 + ...86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 + cmake/DownloadAndExtractClang.cmake | 45 +++--- cmake/FindClang.cmake | 6 +- 10 files changed, 108 insertions(+), 99 deletions(-) delete mode 100644 clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 create mode 100644 clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 diff --git a/CMakeLists.txt b/CMakeLists.txt index 776fa8b89..b3306340b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,6 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) # Required Clang version -set(CLANG_VERSION 6.0.0 CACHE STRING "Clang version") set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} CACHE STRING "Downloaded Clang location") option(SYSTEM_CLANG "Use system installation of Clang instead of \ @@ -42,18 +41,20 @@ target_compile_options(ccls PRIVATE -fno-rtti) if(MSVC) # Common MSVC/Clang(Windows) options target_compile_options(ccls PRIVATE - /nologo - /EHsc - /W3 # roughly -Wall - /wd4996 # disable loguru unsafe warnings - /wd4722 # ignores warning C4722 - # (destructor never returns) in loguru - /wd4267 # ignores warning C4267 - # (conversion from 'size_t' to 'type'), - # roughly -Wno-sign-compare - /wd4800 - $<$:/FS> - ) + /nologo + /EHsc + /D_CRT_SECURE_NO_WARNINGS # don't try to use MSVC std replacements + /W3 # roughly -Wall + /wd4996 # disable loguru unsafe warnings + /wd4722 # ignores warning C4722 + # (destructor never returns) in loguru + /wd4267 # ignores warning C4267 + # (conversion from 'size_t' to 'type'), + # roughly -Wno-sign-compare + /wd4800 + /wd4068 # Disable unknown pragma warning + $<$:/FS> + ) else() # Common GCC/Clang(Linux) options target_compile_options(ccls PRIVATE @@ -83,7 +84,7 @@ if(NOT SYSTEM_CLANG) message(STATUS "Using downloaded Clang") include(DownloadAndExtractClang) - download_and_extract_clang(${CLANG_VERSION} ${CLANG_DOWNLOAD_LOCATION}) + download_and_extract_clang(${CLANG_DOWNLOAD_LOCATION}) # Used by FindClang set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) @@ -105,7 +106,7 @@ endif() ### Libraries # See cmake/FindClang.cmake -find_package(Clang ${CLANG_VERSION} REQUIRED) +find_package(Clang 6.0.0) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support @@ -136,7 +137,6 @@ target_include_directories(ccls SYSTEM PRIVATE install(TARGETS ccls RUNTIME DESTINATION bin) -# TODO: install libclang.dll on Windows as well if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) @@ -174,63 +174,64 @@ file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h target_sources(ccls PRIVATE third_party/siphash.cc) target_sources(ccls PRIVATE - src/clang_complete.cc - src/clang_tu.cc - src/clang_utils.cc - src/config.cc - src/file_consumer.cc - src/filesystem.cc - src/fuzzy_match.cc - src/main.cc - src/include_complete.cc - src/indexer.cc - src/method.cc - src/language.cc - src/log.cc - src/lsp.cc - src/match.cc - src/message_handler.cc - src/pipeline.cc - src/platform_posix.cc - src/platform_win.cc - src/position.cc - src/project.cc - src/query_utils.cc - src/query.cc - src/serializer.cc - src/test.cc - src/utils.cc - src/working_files.cc) + src/clang_complete.cc + src/clang_tu.cc + src/clang_utils.cc + src/config.cc + src/file_consumer.cc + src/filesystem.cc + src/fuzzy_match.cc + src/main.cc + src/include_complete.cc + src/indexer.cc + src/method.cc + src/language.cc + src/log.cc + src/lsp.cc + src/match.cc + src/message_handler.cc + src/pipeline.cc + src/platform_posix.cc + src/platform_win.cc + src/position.cc + src/project.cc + src/query_utils.cc + src/query.cc + src/serializer.cc + src/test.cc + src/utils.cc + src/working_files.cc +) target_sources(ccls PRIVATE - src/messages/ccls_base.cc - src/messages/ccls_callHierarchy.cc - src/messages/ccls_callers.cc - src/messages/ccls_fileInfo.cc - src/messages/ccls_freshenIndex.cc - src/messages/ccls_inheritanceHierarchy.cc - src/messages/ccls_memberHierarchy.cc - src/messages/ccls_vars.cc - src/messages/exit.cc - src/messages/initialize.cc - src/messages/shutdown.cc - src/messages/textDocument_codeAction.cc - src/messages/textDocument_codeLens.cc - src/messages/textDocument_completion.cc - src/messages/textDocument_definition.cc - src/messages/textDocument_didChange.cc - src/messages/textDocument_didClose.cc - src/messages/textDocument_didOpen.cc - src/messages/textDocument_didSave.cc - src/messages/textDocument_documentHighlight.cc - src/messages/textDocument_documentSymbol.cc - src/messages/textDocument_hover.cc - src/messages/textDocument_implementation.cc - src/messages/textDocument_references.cc - src/messages/textDocument_rename.cc - src/messages/textDocument_signatureHelp.cc - src/messages/textDocument_typeDefinition.cc - src/messages/workspace_didChangeConfiguration.cc - src/messages/workspace_didChangeWatchedFiles.cc - src/messages/workspace_symbol.cc - ) + src/messages/ccls_base.cc + src/messages/ccls_callHierarchy.cc + src/messages/ccls_callers.cc + src/messages/ccls_fileInfo.cc + src/messages/ccls_freshenIndex.cc + src/messages/ccls_inheritanceHierarchy.cc + src/messages/ccls_memberHierarchy.cc + src/messages/ccls_vars.cc + src/messages/exit.cc + src/messages/initialize.cc + src/messages/shutdown.cc + src/messages/textDocument_codeAction.cc + src/messages/textDocument_codeLens.cc + src/messages/textDocument_completion.cc + src/messages/textDocument_definition.cc + src/messages/textDocument_didChange.cc + src/messages/textDocument_didClose.cc + src/messages/textDocument_didOpen.cc + src/messages/textDocument_didSave.cc + src/messages/textDocument_documentHighlight.cc + src/messages/textDocument_documentSymbol.cc + src/messages/textDocument_hover.cc + src/messages/textDocument_implementation.cc + src/messages/textDocument_references.cc + src/messages/textDocument_rename.cc + src/messages/textDocument_signatureHelp.cc + src/messages/textDocument_typeDefinition.cc + src/messages/workspace_didChangeConfiguration.cc + src/messages/workspace_didChangeWatchedFiles.cc + src/messages/workspace_symbol.cc +) diff --git a/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 b/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 deleted file mode 100644 index ce28c29ad..000000000 --- a/clang_archive_hashes/LLVM-6.0.0-win64.exe.SHA256 +++ /dev/null @@ -1 +0,0 @@ -2501887b2f638d3f65b0336f354b96f8108b563522d81e841d5c88c34af283dd diff --git a/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 b/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 new file mode 100644 index 000000000..5d218384a --- /dev/null +++ b/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 @@ -0,0 +1 @@ +780276221635aa08120187ffc2c72ff7873dee37f5609455ee7bba6fcdd91d79 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 deleted file mode 100644 index 0cbc9d405..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -fee8352f5dee2e38fa2bb80ab0b5ef9efef578cbc6892e5c724a1187498119b7 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 deleted file mode 100644 index e58383173..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -114e78b2f6db61aaee314c572e07b0d635f653adc5d31bd1cd0bf31a3db4a6e5 diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 deleted file mode 100644 index 18b5a60ea..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -cc99fda45b4c740f35d0a367985a2bf55491065a501e2dd5d1ad3f97dcac89da diff --git a/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 new file mode 100644 index 000000000..9a7df3246 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 @@ -0,0 +1 @@ +6d1f67c9e7c3481106d5c9bfcb8a75e3876eb17a446a14c59c13cafd000c21d2 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 new file mode 100644 index 000000000..671a75e2f --- /dev/null +++ b/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 @@ -0,0 +1 @@ +7ea204ecd78c39154d72dfc0d4a79f7cce1b2264da2551bb2eef10e266d54d91 \ No newline at end of file diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake index 5c4e3d976..d7c11755a 100644 --- a/cmake/DownloadAndExtractClang.cmake +++ b/cmake/DownloadAndExtractClang.cmake @@ -4,17 +4,21 @@ # Returns the extracted Clang archive directory in DOWNLOADED_CLANG_DIR # # Downloads 7-Zip to extract Clang if it isn't available in the PATH -function(download_and_extract_clang CLANG_VERSION CLANG_DOWNLOAD_LOCATION) +function(download_and_extract_clang CLANG_DOWNLOAD_LOCATION) +set(CLANG_VERSION 6.0.1) set(CLANG_ARCHIVE_EXT .tar.xz) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + # Default to Ubuntu 16.04 set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-16.04) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + # No Darwin binaries were released for LLVM 6.0.1 + set(CLANG_VERSION 6.0.0) set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) @@ -24,11 +28,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - if(${CLANG_VERSION} STREQUAL 6.0.0) - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10) - else() - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) - endif() + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) endif() @@ -92,8 +92,11 @@ if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) include(DownloadAndExtract7zip) download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION}) - find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH - PATHS ${DOWNLOADED_7ZIP_DIR}) + find_program(7ZIP_EXECUTABLE + NAMES 7z + NO_DEFAULT_PATH + PATHS ${DOWNLOADED_7ZIP_DIR} + ) else() message(STATUS "7-Zip found in PATH") endif() @@ -101,22 +104,26 @@ if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) message(STATUS "Extracting downloaded Clang with 7-Zip ...") # Avoid running the Clang installer by extracting the exe with 7-Zip - execute_process(COMMAND ${7ZIP_EXECUTABLE} x - -o${CLANG_ARCHIVE_EXTRACT_DIR} - -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} - WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} - OUTPUT_QUIET) + execute_process( + COMMAND ${7ZIP_EXECUTABLE} x + -o${CLANG_ARCHIVE_EXTRACT_DIR} + -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} + WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} + OUTPUT_QUIET + ) elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz) message(STATUS "Extracting downloaded Clang with CMake built-in tar ...") # CMake has builtin support for tar via the -E flag - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} - # Specify working directory to allow running cmake from - # everywhere - # (example: cmake -H"$HOME/ccls" -B"$home/ccls/build") - WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} - OUTPUT_QUIET) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} + # Specify working directory to allow running cmake from + # everywhere + # (example: cmake -H"$HOME/cquery" -B"$home/cquery/build") + WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} + OUTPUT_QUIET + ) endif() set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 87ab72b54..6c4f41530 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -114,8 +114,10 @@ executable. Output:\n ${_Clang_FIND_RESOURCE_DIR_ERROR}") # Find Clang version set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - execute_process(COMMAND ${Clang_EXECUTABLE} --version - OUTPUT_VARIABLE Clang_VERSION) + execute_process( + COMMAND ${Clang_EXECUTABLE} --version + OUTPUT_VARIABLE Clang_VERSION + ) string(REGEX MATCH ${_Clang_VERSION_REGEX} Clang_VERSION ${Clang_VERSION}) endif() From 924fedbb02be07e19fd2a5372a09e89779973d41 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 30 Jul 2018 18:00:43 -0700 Subject: [PATCH 166/378] Uniquify textDocument/references There can be duplicates with template instantiation. --- src/indexer.cc | 2 -- src/indexer.h | 5 +++-- src/messages/textDocument_references.cc | 4 +++- src/query.cc | 3 --- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 523c04afd..f29099735 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1113,8 +1113,6 @@ std::string IndexFile::ToString() { return ccls::Serialize(SerializeFormat::Json, *this); } -MAKE_HASHABLE(Use, t.range, t.file_id) - template void Uniquify(std::vector& a) { std::unordered_set seen; diff --git a/src/indexer.h b/src/indexer.h index 146ff5b43..e43cfc5f6 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -61,10 +61,11 @@ struct Use : Reference { // |file| is used in Query* but not in Index* int file_id = -1; bool operator==(const Use& o) const { - return range == o.range && usr == o.usr && kind == o.kind && - role == o.role && file_id == o.file_id; + // lexical container info is ignored. + return range == o.range && file_id == o.file_id; } }; +MAKE_HASHABLE(Use, t.range, t.file_id) void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 479a72ef7..b11c50738 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -63,6 +63,7 @@ struct Handler_TextDocumentReferences Out_TextDocumentReferences out; out.id = request->id; bool container = g_config->xref.container; + std::unordered_set seen_uses; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { // Found symbol. Return references. @@ -76,7 +77,8 @@ struct Handler_TextDocumentReferences stack.pop_back(); auto fn = [&](Use use, lsSymbolKind parent_kind) { if (Role(use.role & params.context.role) == params.context.role && - !(use.role & params.context.excludeRole)) + !(use.role & params.context.excludeRole) && + seen_uses.insert(use).second) if (std::optional ls_loc = GetLsLocationEx(db, working_files, use, container)) { if (container) diff --git a/src/query.cc b/src/query.cc index 7e49c6871..a5757e2f9 100644 --- a/src/query.cc +++ b/src/query.cc @@ -12,9 +12,6 @@ #include #include -// Used by |REMOVE_ADD| so only |range| is needed. -MAKE_HASHABLE(Use, t.range, t.file_id); - namespace { void AssignFileId(const Lid2file_id &, int file_id, SymbolRef &ref) { From b5c2a48bb06635ae6b501a949b9e20024742e91e Mon Sep 17 00:00:00 2001 From: Damon Kwok Date: Sat, 4 Aug 2018 00:37:31 +0800 Subject: [PATCH 167/378] rapidjson url (#43) --- .gitmodules | 2 +- third_party/rapidjson | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index b8c34ed07..ff65b1dbb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "third_party/rapidjson"] path = third_party/rapidjson - url = https://github.com/miloyip/rapidjson + url = https://github.com/Tencent/rapidjson diff --git a/third_party/rapidjson b/third_party/rapidjson index daabb88e0..6a905f931 160000 --- a/third_party/rapidjson +++ b/third_party/rapidjson @@ -1 +1 @@ -Subproject commit daabb88e001f562e1f7df5f44d7fed32a0c107c2 +Subproject commit 6a905f9311f82d306da77bd963ec5aa5da07da9c From 39319514066449fed7203d86e5a65d1f92038e8e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 3 Aug 2018 16:11:32 -0700 Subject: [PATCH 168/378] Validate RecordDecl --- .../usage/func_called_from_template.cc | 2 +- src/indexer.cc | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 868cc1b08..becca51b9 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -27,7 +27,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|10177235824697315808|3|16420", "5:3-5:9|2459767597003442547|3|16420"], + "uses": ["5:3-5:9|10177235824697315808|3|16420"], "callees": [] }, { "usr": 2459767597003442547, diff --git a/src/indexer.cc b/src/indexer.cc index f29099735..280cf3a2f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -301,6 +301,19 @@ const Decl* GetSpecialized(const Decl* D) { return Template; } +bool ValidateRecord(const RecordDecl *RD) { + for (const auto *I : RD->fields()){ + QualType FQT = I->getType(); + if (FQT->isIncompleteType() || FQT->isDependentType()) + return false; + if (const RecordType *ChildType = I->getType()->getAs()) + if (const RecordDecl *Child = ChildType->getDecl()) + if (!ValidateRecord(Child)) + return false; + } + return true; +} + class IndexDataConsumer : public index::IndexDataConsumer { public: ASTContext *Ctx; @@ -831,18 +844,24 @@ class IndexDataConsumer : public index::IndexDataConsumer { : lsSymbolKind::Class; if (is_def) { SmallVector, 2> Stack{{RD, 0}}; + llvm::DenseSet Seen; + Seen.insert(RD); while (Stack.size()) { int offset; std::tie(RD, offset) = Stack.back(); Stack.pop_back(); - if (!RD->isCompleteDefinition() || RD->isDependentType()) + if (!RD->isCompleteDefinition() || RD->isDependentType() || + !ValidateRecord(RD)) offset = -1; for (FieldDecl *FD : RD->fields()) { int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; if (FD->getIdentifier()) type->def.vars.emplace_back(GetUsr(FD), offset1); - else if (const auto *RT1 = FD->getType()->getAs()) - Stack.push_back({RT1->getDecl(), offset1}); + else if (const auto *RT1 = FD->getType()->getAs()) { + if (const RecordDecl *RD1 = RT1->getDecl()) + if (Seen.insert(RD1).second) + Stack.push_back({RD1, offset1}); + } } } } From b9e1c2ee0739d36cb0ca5f30e67750a9ee5148b1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 3 Aug 2018 23:01:01 -0700 Subject: [PATCH 169/378] Add flat to $ccls/inheritanceHierarchy --- src/messages/ccls_inheritanceHierarchy.cc | 40 +++++++++++++++-------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index 3d477fa60..f21d7de7d 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -1,8 +1,9 @@ #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; +#include #include namespace { @@ -24,18 +25,12 @@ struct In_CclsInheritanceHierarchy : public RequestInMessage { bool derived = false; bool qualified = true; int levels = 1; - }; - Params params; + bool flat = false; + } params; }; -MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, - textDocument, - position, - id, - kind, - derived, - qualified, - levels); +MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, textDocument, position, + id, kind, derived, qualified, levels, flat); MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); @@ -159,7 +154,7 @@ struct Handler_CclsInheritanceHierarchy Out_CclsInheritanceHierarchy out; out.id = request->id; - if (params.id.size()) { + if (!params.flat && params.id.size()) { try { params.usr = std::stoull(params.id); } catch (...) { @@ -189,7 +184,26 @@ struct Handler_CclsInheritanceHierarchy } } - pipeline::WriteStdout(kMethodType, out); + if (!params.flat) { + pipeline::WriteStdout(kMethodType, out); + return; + } + Out_LocationList out1; + out1.id = request->id; + if (out.result) { + std::queue q; + for (auto &entry1 : out.result->children) + q.push(&entry1); + while (q.size()) { + auto *entry = q.front(); + q.pop(); + if (entry->location.uri.raw_uri.size()) + out1.result.push_back({entry->location}); + for (auto &entry1 : entry->children) + q.push(&entry1); + } + } + pipeline::WriteStdout(kMethodType, out1); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); From 344ade0420a49b7f42c8854e0f8314f1c70b5fb4 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Mon, 6 Aug 2018 15:45:04 +0800 Subject: [PATCH 170/378] Fix compile on Windows + MSYS2-MinGW64 (#46) 1. libClangDriver.a shipped by MSYS2 needs -lversion which is not included in CMAKE_CXX_STANDARD_LIBRARIES by default. 2. Use string literal for DEFAULT_RESOURCE_DIRECTORY to support backslashes in path. --- CMakeLists.txt | 2 +- cmake/FindClang.cmake | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3306340b..faa640b12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ endif() ### Definitions target_compile_definitions(ccls PRIVATE - DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}") + DEFAULT_RESOURCE_DIRECTORY=R"\(${Clang_RESOURCE_DIR}\)") ### Includes diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 6c4f41530..e4286d51f 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -137,4 +137,7 @@ if(Clang_FOUND AND NOT TARGET Clang::Clang) find_package(Curses REQUIRED) find_package(ZLIB REQUIRED) set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES};${ZLIB_LIBRARIES}") + if(MINGW) + set_property(TARGET Clang::Clang APPEND_STRING PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES ";version") + endif() endif() From 8cbb317dc2113d82ea0a1a77c0da393c7a51a3ce Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 9 Aug 2018 10:08:14 -0700 Subject: [PATCH 171/378] clang-format DEF CON 26 CTF --- src/clang_complete.cc | 366 +++++++++--------- src/clang_complete.h | 59 ++- src/clang_tu.cc | 7 +- src/clang_tu.h | 10 +- src/clang_utils.cc | 4 +- src/clang_utils.h | 4 +- src/config.cc | 2 +- src/config.h | 56 +-- src/file_consumer.cc | 41 +- src/file_consumer.h | 31 +- src/filesystem.cc | 8 +- src/fuzzy_match.cc | 6 +- src/fuzzy_match.h | 4 +- src/include_complete.cc | 53 +-- src/include_complete.h | 14 +- src/indexer.cc | 250 ++++++------ src/indexer.h | 101 ++--- src/language.cc | 2 +- src/language.h | 2 +- src/log.cc | 15 +- src/lru_cache.h | 38 +- src/lsp.cc | 43 +- src/lsp.h | 75 ++-- src/lsp_completion.h | 19 +- src/lsp_diagnostic.h | 5 +- src/main.cc | 24 +- src/match.cc | 34 +- src/match.h | 12 +- src/maybe.h | 33 +- src/message_handler.cc | 13 +- src/message_handler.h | 73 ++-- src/messages/ccls_base.cc | 12 +- src/messages/ccls_callHierarchy.cc | 78 ++-- src/messages/ccls_callers.cc | 10 +- src/messages/ccls_fileInfo.cc | 16 +- src/messages/ccls_freshenIndex.cc | 24 +- src/messages/ccls_inheritanceHierarchy.cc | 52 +-- src/messages/ccls_memberHierarchy.cc | 119 +++--- src/messages/ccls_vars.cc | 45 +-- src/messages/exit.cc | 6 +- src/messages/initialize.cc | 99 ++--- src/messages/shutdown.cc | 4 +- src/messages/textDocument_codeAction.cc | 10 +- src/messages/textDocument_codeLens.cc | 236 ++++++----- src/messages/textDocument_completion.cc | 91 +++-- src/messages/textDocument_definition.cc | 59 ++- src/messages/textDocument_didChange.cc | 6 +- src/messages/textDocument_didClose.cc | 4 +- src/messages/textDocument_didOpen.cc | 14 +- src/messages/textDocument_didSave.cc | 8 +- .../textDocument_documentHighlight.cc | 8 +- src/messages/textDocument_documentSymbol.cc | 12 +- src/messages/textDocument_hover.cc | 27 +- src/messages/textDocument_implementation.cc | 14 +- src/messages/textDocument_references.cc | 37 +- src/messages/textDocument_rename.cc | 33 +- src/messages/textDocument_signatureHelp.cc | 22 +- src/messages/textDocument_typeDefinition.cc | 46 +-- .../workspace_didChangeConfiguration.cc | 6 +- .../workspace_didChangeWatchedFiles.cc | 28 +- src/messages/workspace_executeCommand.cc | 8 +- src/messages/workspace_symbol.cc | 38 +- src/method.cc | 7 +- src/method.h | 14 +- src/pipeline.cc | 116 +++--- src/platform.h | 4 +- src/platform_posix.cc | 16 +- src/platform_win.cc | 6 +- src/position.cc | 16 +- src/position.h | 25 +- src/project.cc | 110 +++--- src/project.h | 15 +- src/query.cc | 213 +++++----- src/query.h | 42 +- src/query_utils.cc | 198 +++++----- src/query_utils.h | 111 +++--- src/serializer.cc | 312 +++++++-------- src/serializer.h | 226 +++++------ src/serializers/binary.h | 50 +-- src/serializers/json.h | 36 +- src/test.cc | 68 ++-- src/test.h | 2 +- src/threaded_queue.h | 54 ++- src/utils.cc | 49 ++- src/utils.h | 59 ++- src/working_files.cc | 94 +++-- src/working_files.h | 45 +-- 87 files changed, 2075 insertions(+), 2389 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 2f1a019b5..5425361c7 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -20,7 +20,7 @@ using namespace llvm; namespace { -std::string StripFileType(const std::string& path) { +std::string StripFileType(const std::string &path) { SmallString<128> Ret; sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path)); return Ret.str(); @@ -41,93 +41,93 @@ unsigned GetCompletionPriority(const CodeCompletionString &CCS, lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { - case CXCursor_UnexposedDecl: - return lsCompletionItemKind::Text; - - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - return lsCompletionItemKind::Struct; - case CXCursor_ClassDecl: - return lsCompletionItemKind::Class; - case CXCursor_EnumDecl: - return lsCompletionItemKind::Enum; - case CXCursor_FieldDecl: - return lsCompletionItemKind::Field; - case CXCursor_EnumConstantDecl: - return lsCompletionItemKind::EnumMember; - case CXCursor_FunctionDecl: - return lsCompletionItemKind::Function; - case CXCursor_VarDecl: - case CXCursor_ParmDecl: - return lsCompletionItemKind::Variable; - case CXCursor_ObjCInterfaceDecl: - return lsCompletionItemKind::Interface; - - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_CXXMethod: - case CXCursor_ObjCClassMethodDecl: - return lsCompletionItemKind::Method; - - case CXCursor_FunctionTemplate: - return lsCompletionItemKind::Function; - - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - return lsCompletionItemKind::Constructor; - - case CXCursor_ObjCIvarDecl: - return lsCompletionItemKind::Variable; - - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_UsingDeclaration: - case CXCursor_TypedefDecl: - case CXCursor_TypeAliasDecl: - case CXCursor_TypeAliasTemplateDecl: - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_ObjCCategoryImplDecl: - return lsCompletionItemKind::Class; - - case CXCursor_ObjCPropertyDecl: - return lsCompletionItemKind::Property; - - case CXCursor_MacroInstantiation: - case CXCursor_MacroDefinition: - return lsCompletionItemKind::Interface; - - case CXCursor_Namespace: - case CXCursor_NamespaceAlias: - case CXCursor_NamespaceRef: - return lsCompletionItemKind::Module; - - case CXCursor_MemberRef: - case CXCursor_TypeRef: - case CXCursor_ObjCSuperClassRef: - case CXCursor_ObjCProtocolRef: - case CXCursor_ObjCClassRef: - return lsCompletionItemKind::Reference; - - // return lsCompletionItemKind::Unit; - // return lsCompletionItemKind::Value; - // return lsCompletionItemKind::Keyword; - // return lsCompletionItemKind::Snippet; - // return lsCompletionItemKind::Color; - // return lsCompletionItemKind::File; - - case CXCursor_NotImplemented: - case CXCursor_OverloadCandidate: - return lsCompletionItemKind::Text; - - case CXCursor_TemplateTypeParameter: - case CXCursor_TemplateTemplateParameter: - return lsCompletionItemKind::TypeParameter; - - default: - LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; - return lsCompletionItemKind::Text; + case CXCursor_UnexposedDecl: + return lsCompletionItemKind::Text; + + case CXCursor_StructDecl: + case CXCursor_UnionDecl: + return lsCompletionItemKind::Struct; + case CXCursor_ClassDecl: + return lsCompletionItemKind::Class; + case CXCursor_EnumDecl: + return lsCompletionItemKind::Enum; + case CXCursor_FieldDecl: + return lsCompletionItemKind::Field; + case CXCursor_EnumConstantDecl: + return lsCompletionItemKind::EnumMember; + case CXCursor_FunctionDecl: + return lsCompletionItemKind::Function; + case CXCursor_VarDecl: + case CXCursor_ParmDecl: + return lsCompletionItemKind::Variable; + case CXCursor_ObjCInterfaceDecl: + return lsCompletionItemKind::Interface; + + case CXCursor_ObjCInstanceMethodDecl: + case CXCursor_CXXMethod: + case CXCursor_ObjCClassMethodDecl: + return lsCompletionItemKind::Method; + + case CXCursor_FunctionTemplate: + return lsCompletionItemKind::Function; + + case CXCursor_Constructor: + case CXCursor_Destructor: + case CXCursor_ConversionFunction: + return lsCompletionItemKind::Constructor; + + case CXCursor_ObjCIvarDecl: + return lsCompletionItemKind::Variable; + + case CXCursor_ClassTemplate: + case CXCursor_ClassTemplatePartialSpecialization: + case CXCursor_UsingDeclaration: + case CXCursor_TypedefDecl: + case CXCursor_TypeAliasDecl: + case CXCursor_TypeAliasTemplateDecl: + case CXCursor_ObjCCategoryDecl: + case CXCursor_ObjCProtocolDecl: + case CXCursor_ObjCImplementationDecl: + case CXCursor_ObjCCategoryImplDecl: + return lsCompletionItemKind::Class; + + case CXCursor_ObjCPropertyDecl: + return lsCompletionItemKind::Property; + + case CXCursor_MacroInstantiation: + case CXCursor_MacroDefinition: + return lsCompletionItemKind::Interface; + + case CXCursor_Namespace: + case CXCursor_NamespaceAlias: + case CXCursor_NamespaceRef: + return lsCompletionItemKind::Module; + + case CXCursor_MemberRef: + case CXCursor_TypeRef: + case CXCursor_ObjCSuperClassRef: + case CXCursor_ObjCProtocolRef: + case CXCursor_ObjCClassRef: + return lsCompletionItemKind::Reference; + + // return lsCompletionItemKind::Unit; + // return lsCompletionItemKind::Value; + // return lsCompletionItemKind::Keyword; + // return lsCompletionItemKind::Snippet; + // return lsCompletionItemKind::Color; + // return lsCompletionItemKind::File; + + case CXCursor_NotImplemented: + case CXCursor_OverloadCandidate: + return lsCompletionItemKind::Text; + + case CXCursor_TemplateTypeParameter: + case CXCursor_TemplateTemplateParameter: + return lsCompletionItemKind::TypeParameter; + + default: + LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; + return lsCompletionItemKind::Text; } } @@ -144,50 +144,50 @@ void BuildCompletionItemTexts(std::vector &out, CodeCompletionString::ChunkKind Kind = Chunk.Kind; std::string text; switch (Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_Informative: - if (Chunk.Text) - text = Chunk.Text; - for (auto i = out_first; i < out.size(); i++) { - // first TypedText is used for filtering - if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) - out[i].filterText = text; - if (Kind == CodeCompletionString::CK_Placeholder) - out[i].parameters_.push_back(text); - } - break; - case CodeCompletionString::CK_ResultType: - if (Chunk.Text) - result_type = Chunk.Text; - continue; - case CodeCompletionString::CK_CurrentParameter: - // We have our own parsing logic for active parameter. This doesn't seem - // to be very reliable. - continue; - case CodeCompletionString::CK_Optional: { - // duplicate last element, the recursive call will complete it - out.push_back(out.back()); - BuildCompletionItemTexts(out, *Chunk.Optional, include_snippets); - continue; + case CodeCompletionString::CK_TypedText: + case CodeCompletionString::CK_Text: + case CodeCompletionString::CK_Placeholder: + case CodeCompletionString::CK_Informative: + if (Chunk.Text) + text = Chunk.Text; + for (auto i = out_first; i < out.size(); i++) { + // first TypedText is used for filtering + if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) + out[i].filterText = text; + if (Kind == CodeCompletionString::CK_Placeholder) + out[i].parameters_.push_back(text); } - // clang-format off - case CodeCompletionString::CK_LeftParen: text = '('; break; - case CodeCompletionString::CK_RightParen: text = ')'; break; - case CodeCompletionString::CK_LeftBracket: text = '['; break; - case CodeCompletionString::CK_RightBracket: text = ']'; break; - case CodeCompletionString::CK_LeftBrace: text = '{'; break; - case CodeCompletionString::CK_RightBrace: text = '}'; break; - case CodeCompletionString::CK_LeftAngle: text = '<'; break; - case CodeCompletionString::CK_RightAngle: text = '>'; break; - case CodeCompletionString::CK_Comma: text = ", "; break; - case CodeCompletionString::CK_Colon: text = ':'; break; - case CodeCompletionString::CK_SemiColon: text = ';'; break; - case CodeCompletionString::CK_Equal: text = '='; break; - case CodeCompletionString::CK_HorizontalSpace: text = ' '; break; - case CodeCompletionString::CK_VerticalSpace: text = ' '; break; - // clang-format on + break; + case CodeCompletionString::CK_ResultType: + if (Chunk.Text) + result_type = Chunk.Text; + continue; + case CodeCompletionString::CK_CurrentParameter: + // We have our own parsing logic for active parameter. This doesn't seem + // to be very reliable. + continue; + case CodeCompletionString::CK_Optional: { + // duplicate last element, the recursive call will complete it + out.push_back(out.back()); + BuildCompletionItemTexts(out, *Chunk.Optional, include_snippets); + continue; + } + // clang-format off + case CodeCompletionString::CK_LeftParen: text = '('; break; + case CodeCompletionString::CK_RightParen: text = ')'; break; + case CodeCompletionString::CK_LeftBracket: text = '['; break; + case CodeCompletionString::CK_RightBracket: text = ']'; break; + case CodeCompletionString::CK_LeftBrace: text = '{'; break; + case CodeCompletionString::CK_RightBrace: text = '}'; break; + case CodeCompletionString::CK_LeftAngle: text = '<'; break; + case CodeCompletionString::CK_RightAngle: text = '>'; break; + case CodeCompletionString::CK_Comma: text = ", "; break; + case CodeCompletionString::CK_Colon: text = ':'; break; + case CodeCompletionString::CK_SemiColon: text = ';'; break; + case CodeCompletionString::CK_Equal: text = '='; break; + case CodeCompletionString::CK_HorizontalSpace: text = ' '; break; + case CodeCompletionString::CK_VerticalSpace: text = ' '; break; + // clang-format on } if (Kind != CodeCompletionString::CK_Informative) @@ -197,8 +197,9 @@ void BuildCompletionItemTexts(std::vector &out, continue; if (Kind == CodeCompletionString::CK_Placeholder) { - out[i].insertText += - "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; + out[i].insertText += "${" + + std::to_string(out[i].parameters_.size()) + ":" + + text + "}"; out[i].insertTextFormat = lsInsertTextFormat::Snippet; } else { out[i].insertText += text; @@ -223,7 +224,7 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, for (unsigned i = 0, num_chunks = CCS.size(); i < num_chunks; ++i) { const CodeCompletionString::Chunk &Chunk = CCS[i]; CodeCompletionString::ChunkKind Kind = Chunk.Kind; - const char* text = nullptr; + const char *text = nullptr; switch (Kind) { case CodeCompletionString::CK_TypedText: item.label = Chunk.Text; @@ -238,7 +239,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, item.detail += Chunk.Text; // Add parameter declarations as snippets if enabled if (include_snippets) { - item.insertText += "${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}"; + item.insertText += + "${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}"; item.insertTextFormat = lsInsertTextFormat::Snippet; } else do_insert = false; @@ -250,8 +252,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, case CodeCompletionString::CK_Optional: { // Do not add text to insert string if we're in angle brackets. bool should_insert = do_insert && angle_stack == 0; - BuildDetailString(*Chunk.Optional, item, should_insert, - parameters, include_snippets, angle_stack); + BuildDetailString(*Chunk.Optional, item, should_insert, parameters, + include_snippets, angle_stack); break; } case CodeCompletionString::CK_ResultType: @@ -298,10 +300,9 @@ class CaptureCompletionResults : public CodeCompleteConsumer { Alloc(std::make_shared()), CCTUInfo(Alloc) {} - void ProcessCodeCompleteResults(Sema &S, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) override { + void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override { ls_items.reserve(NumResults); for (unsigned i = 0; i != NumResults; i++) { CodeCompletionString *CCS = Results[i].CreateCodeCompletionString( @@ -312,7 +313,7 @@ class CaptureCompletionResults : public CodeCompleteConsumer { lsCompletionItem ls_item; ls_item.kind = GetCompletionKind(Results[i].CursorKind); - if (const char* brief = CCS->getBriefComment()) + if (const char *brief = CCS->getBriefComment()) ls_item.documentation = brief; // label/detail/filterText/insertText/priority @@ -334,8 +335,7 @@ class CaptureCompletionResults : public CodeCompleteConsumer { } else { bool do_insert = true; int angle_stack = 0; - BuildDetailString(*CCS, ls_item, do_insert, - &ls_item.parameters_, + BuildDetailString(*CCS, ls_item, do_insert, &ls_item.parameters_, g_config->client.snippetSupport, angle_stack); if (g_config->client.snippetSupport && ls_item.insertTextFormat == lsInsertTextFormat::Snippet) @@ -353,7 +353,7 @@ class CaptureCompletionResults : public CodeCompleteConsumer { CodeCompletionAllocator &getAllocator() override { return *Alloc; } - CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;} + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } }; void TryEnsureDocumentParsed(ClangCompleteManager *manager, @@ -374,7 +374,7 @@ void TryEnsureDocumentParsed(ClangCompleteManager *manager, diagnostic); } -void CompletionPreloadMain(ClangCompleteManager* completion_manager) { +void CompletionPreloadMain(ClangCompleteManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. auto request = completion_manager->preload_requests_.Dequeue(); @@ -390,7 +390,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) { // Note: we only preload completion. We emit diagnostics for the // completion preload though. - CompletionSession::Tu* tu = &session->completion; + CompletionSession::Tu *tu = &session->completion; // If we've parsed it more recently than the request time, don't bother // reparsing. @@ -407,7 +407,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) { } } -void CompletionQueryMain(ClangCompleteManager* completion_manager) { +void CompletionQueryMain(ClangCompleteManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. std::unique_ptr request = @@ -427,11 +427,12 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { true /*create_if_needed*/); std::lock_guard lock(session->completion.lock); - TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, false); + TryEnsureDocumentParsed(completion_manager, session, + &session->completion.tu, false); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. - if (ClangTranslationUnit* tu = session->completion.tu.get()) { + if (ClangTranslationUnit *tu = session->completion.tu.get()) { WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); IntrusiveRefCntPtr FileMgr(&tu->Unit->getFileManager()); @@ -464,7 +465,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr, *FileMgr, Diagnostics, TemporaryBuffers); request->on_complete(capture.ls_items, false /*is_cached_result*/); - // completion_manager->on_diagnostic_(session->file.filename, Diags.take()); + // completion_manager->on_diagnostic_(session->file.filename, + // Diags.take()); } } } @@ -487,7 +489,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. - ClangTranslationUnit* tu = session->diagnostics.tu.get(); + ClangTranslationUnit *tu = session->diagnostics.tu.get(); if (!tu) continue; @@ -509,7 +511,8 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { if (!FLoc.isValid()) // why? continue; const FileEntry *FE = FLoc.getFileEntry(); - if (!FE || FileName(*FE) != path) continue; + if (!FE || FileName(*FE) != path) + continue; const auto &SM = FLoc.getManager(); SourceRange R; for (const auto &CR : I->getRanges()) { @@ -553,45 +556,46 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { } } -} // namespace +} // namespace -ClangCompleteManager::ClangCompleteManager(Project* project, - WorkingFiles* working_files, +ClangCompleteManager::ClangCompleteManager(Project *project, + WorkingFiles *working_files, OnDiagnostic on_diagnostic, OnDropped on_dropped) - : project_(project), - working_files_(working_files), - on_diagnostic_(on_diagnostic), - on_dropped_(on_dropped), + : project_(project), working_files_(working_files), + on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { std::thread([&]() { set_thread_name("comp-query"); CompletionQueryMain(this); - }).detach(); + }) + .detach(); std::thread([&]() { set_thread_name("comp-preload"); CompletionPreloadMain(this); - }).detach(); + }) + .detach(); std::thread([&]() { set_thread_name("diag-query"); DiagnosticQueryMain(this); - }).detach(); + }) + .detach(); } void ClangCompleteManager::CodeComplete( - const lsRequestId& id, - const lsTextDocumentPositionParams& completion_location, - const OnComplete& on_complete) { + const lsRequestId &id, + const lsTextDocumentPositionParams &completion_location, + const OnComplete &on_complete) { completion_request_.PushBack(std::make_unique( id, completion_location.textDocument, completion_location.position, on_complete)); } void ClangCompleteManager::DiagnosticsUpdate( - const lsTextDocumentIdentifier& document) { + const lsTextDocumentIdentifier &document) { bool has = false; - diagnostic_request_.Iterate([&](const DiagnosticRequest& request) { + diagnostic_request_.Iterate([&](const DiagnosticRequest &request) { if (request.document.uri == document.uri) has = true; }); @@ -600,7 +604,7 @@ void ClangCompleteManager::DiagnosticsUpdate( true /*priority*/); } -void ClangCompleteManager::NotifyView(const std::string& filename) { +void ClangCompleteManager::NotifyView(const std::string &filename) { // // On view, we reparse only if the file has not been parsed. The existence of // a CompletionSession instance implies the file is already parsed or will be @@ -612,7 +616,7 @@ void ClangCompleteManager::NotifyView(const std::string& filename) { preload_requests_.PushBack(PreloadRequest(filename), true); } -void ClangCompleteManager::NotifyEdit(const std::string& filename) { +void ClangCompleteManager::NotifyEdit(const std::string &filename) { // // We treat an edit like a view, because the completion logic will handle // moving the CompletionSession instance from preloaded to completion @@ -622,7 +626,7 @@ void ClangCompleteManager::NotifyEdit(const std::string& filename) { NotifyView(filename); } -void ClangCompleteManager::NotifySave(const std::string& filename) { +void ClangCompleteManager::NotifySave(const std::string &filename) { // // On save, always reparse. // @@ -631,7 +635,7 @@ void ClangCompleteManager::NotifySave(const std::string& filename) { preload_requests_.PushBack(PreloadRequest(filename), true); } -void ClangCompleteManager::NotifyClose(const std::string& filename) { +void ClangCompleteManager::NotifyClose(const std::string &filename) { // // On close, we clear any existing CompletionSession instance. // @@ -652,7 +656,7 @@ void ClangCompleteManager::NotifyClose(const std::string& filename) { } bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( - const std::string& filename) { + const std::string &filename) { std::lock_guard lock(sessions_lock_); // Check for an existing CompletionSession. @@ -668,10 +672,10 @@ bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( return true; } -std::shared_ptr ClangCompleteManager::TryGetSession( - const std::string& filename, - bool mark_as_completion, - bool create_if_needed) { +std::shared_ptr +ClangCompleteManager::TryGetSession(const std::string &filename, + bool mark_as_completion, + bool create_if_needed) { std::lock_guard lock(sessions_lock_); // Try to find a preloaded session. @@ -701,11 +705,11 @@ std::shared_ptr ClangCompleteManager::TryGetSession( return completion_session; } -void ClangCompleteManager::FlushSession(const std::string& filename) { - std::lock_guard lock(sessions_lock_); +void ClangCompleteManager::FlushSession(const std::string &filename) { + std::lock_guard lock(sessions_lock_); - preloaded_sessions_.TryTake(filename); - completion_sessions_.TryTake(filename); + preloaded_sessions_.TryTake(filename); + completion_sessions_.TryTake(filename); } void ClangCompleteManager::FlushAllSessions() { diff --git a/src/clang_complete.h b/src/clang_complete.h index 8633ddced..bfcb9407f 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -26,39 +26,34 @@ struct CompletionSession }; Project::Entry file; - WorkingFiles* working_files; + WorkingFiles *working_files; Tu completion; Tu diagnostics; - CompletionSession(const Project::Entry& file, WorkingFiles* wfiles) + CompletionSession(const Project::Entry &file, WorkingFiles *wfiles) : file(file), working_files(wfiles) {} }; struct ClangCompleteManager { - using OnDiagnostic = - std::function diagnostics)>; - using OnComplete = - std::function& results, - bool is_cached_result)>; + using OnDiagnostic = std::function diagnostics)>; + using OnComplete = std::function &results, bool is_cached_result)>; using OnDropped = std::function; struct PreloadRequest { - PreloadRequest(const std::string& path) + PreloadRequest(const std::string &path) : request_time(std::chrono::high_resolution_clock::now()), path(path) {} std::chrono::time_point request_time; std::string path; }; struct CompletionRequest { - CompletionRequest(const lsRequestId& id, - const lsTextDocumentIdentifier& document, - const lsPosition& position, - const OnComplete& on_complete) - : id(id), - document(document), - position(position), + CompletionRequest(const lsRequestId &id, + const lsTextDocumentIdentifier &document, + const lsPosition &position, const OnComplete &on_complete) + : id(id), document(document), position(position), on_complete(on_complete) {} lsRequestId id; @@ -70,42 +65,40 @@ struct ClangCompleteManager { lsTextDocumentIdentifier document; }; - ClangCompleteManager(Project* project, - WorkingFiles* working_files, - OnDiagnostic on_diagnostic, - OnDropped on_dropped); + ClangCompleteManager(Project *project, WorkingFiles *working_files, + OnDiagnostic on_diagnostic, OnDropped on_dropped); // Start a code completion at the given location. |on_complete| will run when // completion results are available. |on_complete| may run on any thread. - void CodeComplete(const lsRequestId& request_id, - const lsTextDocumentPositionParams& completion_location, - const OnComplete& on_complete); + void CodeComplete(const lsRequestId &request_id, + const lsTextDocumentPositionParams &completion_location, + const OnComplete &on_complete); // Request a diagnostics update. - void DiagnosticsUpdate(const lsTextDocumentIdentifier& document); + void DiagnosticsUpdate(const lsTextDocumentIdentifier &document); // Notify the completion manager that |filename| has been viewed and we // should begin preloading completion data. - void NotifyView(const std::string& filename); + void NotifyView(const std::string &filename); // Notify the completion manager that |filename| has been edited. - void NotifyEdit(const std::string& filename); + void NotifyEdit(const std::string &filename); // Notify the completion manager that |filename| has been saved. This // triggers a reparse. - void NotifySave(const std::string& filename); + void NotifySave(const std::string &filename); // Notify the completion manager that |filename| has been closed. Any existing // completion session will be dropped. - void NotifyClose(const std::string& filename); + void NotifyClose(const std::string &filename); // Ensures there is a completion or preloaded session. Returns true if a new // session was created. - bool EnsureCompletionOrCreatePreloadSession(const std::string& filename); + bool EnsureCompletionOrCreatePreloadSession(const std::string &filename); // Tries to find an edit session for |filename|. This will move the session // from view to edit. - std::shared_ptr TryGetSession(const std::string& filename, + std::shared_ptr TryGetSession(const std::string &filename, bool mark_as_completion, bool create_if_needed); // Flushes all saved sessions with the supplied filename - void FlushSession(const std::string& filename); + void FlushSession(const std::string &filename); // Flushes all saved sessions void FlushAllSessions(void); @@ -114,8 +107,8 @@ struct ClangCompleteManager { const int kMaxCompletionSessions = 5; // Global state. - Project* project_; - WorkingFiles* working_files_; + Project *project_; + WorkingFiles *working_files_; OnDiagnostic on_diagnostic_; OnDropped on_dropped_; diff --git a/src/clang_tu.cc b/src/clang_tu.cc index ab43e81e1..ec767f998 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -68,7 +68,7 @@ std::unique_ptr ClangTranslationUnit::Create( const std::string &filepath, const std::vector &args, const WorkingFiles::Snapshot &snapshot, bool diagnostic) { std::vector Args; - for (auto& arg : args) + for (auto &arg : args) Args.push_back(arg.c_str()); Args.push_back("-fallow-editor-placeholders"); if (!diagnostic) @@ -103,9 +103,8 @@ std::unique_ptr ClangTranslationUnit::Create( ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); }; if (!CRC.RunSafely(parse)) { - LOG_S(ERROR) - << "clang crashed for " << filepath << "\n" - << StringJoin(args, " ") + " -fsyntax-only"; + LOG_S(ERROR) << "clang crashed for " << filepath << "\n" + << StringJoin(args, " ") + " -fsyntax-only"; return {}; } if (!Unit && !ErrUnit) diff --git a/src/clang_tu.h b/src/clang_tu.h index c92538780..47fe26aae 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -7,9 +7,9 @@ #include #include +#include #include #include -#include std::vector GetRemapped(const WorkingFiles::Snapshot &snapshot); @@ -19,12 +19,12 @@ Range FromCharSourceRange(const clang::SourceManager &SM, clang::CharSourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); -Range FromCharRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, - clang::SourceRange R, +Range FromCharRange(const clang::SourceManager &SM, + const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); -Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, - clang::SourceRange R, +Range FromTokenRange(const clang::SourceManager &SM, + const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); struct ClangTranslationUnit { diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 8ed4c2016..3a062b6c3 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -10,7 +10,7 @@ using namespace clang; using namespace llvm; -std::string FileName(const FileEntry& file) { +std::string FileName(const FileEntry &file) { StringRef Name = file.tryGetRealPathName(); if (Name.empty()) Name = file.getName(); @@ -25,7 +25,7 @@ std::string FileName(const FileEntry& file) { } // clang::BuiltinType::getName without PrintingPolicy -const char* ClangBuiltinTypeName(int kind) { +const char *ClangBuiltinTypeName(int kind) { switch (BuiltinType::Kind(kind)) { case BuiltinType::Void: return "void"; diff --git a/src/clang_utils.h b/src/clang_utils.h index 6bf5d04e3..5fcc182e3 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -5,6 +5,6 @@ #include // Returns the absolute path to |file|. -std::string FileName(const clang::FileEntry& file); +std::string FileName(const clang::FileEntry &file); -const char* ClangBuiltinTypeName(int); +const char *ClangBuiltinTypeName(int); diff --git a/src/config.cc b/src/config.cc index 27fac9c44..9f0c64cf8 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,4 +1,4 @@ #include "config.h" -Config* g_config; +Config *g_config; thread_local int g_thread_id; diff --git a/src/config.h b/src/config.h index 13379fbf6..44450b43a 100644 --- a/src/config.h +++ b/src/config.h @@ -218,49 +218,23 @@ struct Config { MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); -MAKE_REFLECT_STRUCT(Config::Completion, - caseSensitivity, - dropOldRequests, - detailedLabel, - filterAndSort, - includeBlacklist, - includeMaxPathSize, - includeSuffixWhitelist, +MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, + detailedLabel, filterAndSort, includeBlacklist, + includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); -MAKE_REFLECT_STRUCT(Config::Diagnostics, - blacklist, - frequencyMs, - onParse, - onType, - whitelist) +MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onParse, + onType, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) -MAKE_REFLECT_STRUCT(Config::Index, - attributeMakeCallsToCtor, - blacklist, - comments, - enabled, - onDidChange, - reparseForDependency, - threads, - whitelist); +MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist, + comments, enabled, onDidChange, reparseForDependency, + threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); -MAKE_REFLECT_STRUCT(Config, - compilationDatabaseCommand, - compilationDatabaseDirectory, - cacheDirectory, - cacheFormat, - - clang, - client, - codeLens, - completion, - diagnostics, - highlight, - index, - largeFileSize, - workspaceSymbol, - xref); - -extern Config* g_config; +MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, + compilationDatabaseDirectory, cacheDirectory, cacheFormat, + + clang, client, codeLens, completion, diagnostics, highlight, + index, largeFileSize, workspaceSymbol, xref); + +extern Config *g_config; thread_local extern int g_thread_id; diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 4f2726069..e26a714a8 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -8,9 +8,9 @@ namespace { -std::optional GetFileContents( - const std::string& path, - std::unordered_map* file_contents) { +std::optional +GetFileContents(const std::string &path, + std::unordered_map *file_contents) { auto it = file_contents->find(path); if (it == file_contents->end()) { std::optional content = ReadContent(path); @@ -21,9 +21,9 @@ std::optional GetFileContents( return it->second.content; } -} // namespace +} // namespace -FileContents::FileContents(const std::string& path, const std::string& content) +FileContents::FileContents(const std::string &path, const std::string &content) : path(path), content(content) { line_offsets_.push_back(0); for (size_t i = 0; i < content.size(); i++) { @@ -43,13 +43,13 @@ std::optional FileContents::ToOffset(Position p) const { std::optional FileContents::ContentsInRange(Range range) const { std::optional start_offset = ToOffset(range.start), - end_offset = ToOffset(range.end); + end_offset = ToOffset(range.end); if (start_offset && end_offset && *start_offset < *end_offset) return content.substr(*start_offset, *end_offset - *start_offset); return std::nullopt; } -VFS::State VFS::Get(const std::string& file) { +VFS::State VFS::Get(const std::string &file) { std::lock_guard lock(mutex); auto it = state.find(file); if (it != state.end()) @@ -57,9 +57,9 @@ VFS::State VFS::Get(const std::string& file) { return {0, 0, 0}; } -bool VFS::Mark(const std::string& file, int owner, int stage) { +bool VFS::Mark(const std::string &file, int owner, int stage) { std::lock_guard lock(mutex); - State& st = state[file]; + State &st = state[file]; if (st.stage < stage) { st.owner = owner; st.stage = stage; @@ -68,9 +68,9 @@ bool VFS::Mark(const std::string& file, int owner, int stage) { return false; } -bool VFS::Stamp(const std::string& file, int64_t ts) { +bool VFS::Stamp(const std::string &file, int64_t ts) { std::lock_guard lock(mutex); - State& st = state[file]; + State &st = state[file]; if (st.timestamp < ts) { st.timestamp = ts; return true; @@ -78,23 +78,23 @@ bool VFS::Stamp(const std::string& file, int64_t ts) { return false; } -void VFS::ResetLocked(const std::string& file) { - State& st = state[file]; +void VFS::ResetLocked(const std::string &file) { + State &st = state[file]; if (st.owner == 0 || st.owner == g_thread_id) st.stage = 0; } -void VFS::Reset(const std::string& file) { +void VFS::Reset(const std::string &file) { std::lock_guard lock(mutex); ResetLocked(file); } -FileConsumer::FileConsumer(VFS* vfs, const std::string& parse_file) +FileConsumer::FileConsumer(VFS *vfs, const std::string &parse_file) : vfs_(vfs), parse_file_(parse_file), thread_id_(g_thread_id) {} -IndexFile* FileConsumer::TryConsumeFile( - const clang::FileEntry& File, - std::unordered_map* file_contents_map) { +IndexFile *FileConsumer::TryConsumeFile( + const clang::FileEntry &File, + std::unordered_map *file_contents_map) { auto UniqueID = File.getUniqueID(); auto it = local_.find(UniqueID); if (it != local_.end()) @@ -115,13 +115,14 @@ IndexFile* FileConsumer::TryConsumeFile( return nullptr; // Build IndexFile instance. - local_[UniqueID] = std::make_unique(UniqueID, file_name, *contents); + local_[UniqueID] = + std::make_unique(UniqueID, file_name, *contents); return local_[UniqueID].get(); } std::vector> FileConsumer::TakeLocalState() { std::vector> result; - for (auto& entry : local_) { + for (auto &entry : local_) { if (entry.second) result.push_back(std::move(entry.second)); } diff --git a/src/file_consumer.h b/src/file_consumer.h index 2dcb9622e..3d4759e4c 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -14,7 +14,7 @@ struct IndexFile; struct FileContents { FileContents() = default; - FileContents(const std::string& path, const std::string& content); + FileContents(const std::string &path, const std::string &content); std::optional ToOffset(Position p) const; std::optional ContentsInRange(Range range) const; @@ -34,23 +34,22 @@ struct VFS { mutable std::unordered_map state; mutable std::mutex mutex; - State Get(const std::string& file); - bool Mark(const std::string& file, int owner, int stage); - bool Stamp(const std::string& file, int64_t ts); - void ResetLocked(const std::string& file); - void Reset(const std::string& file); + State Get(const std::string &file); + bool Mark(const std::string &file, int owner, int stage); + bool Stamp(const std::string &file, int64_t ts); + void ResetLocked(const std::string &file); + void Reset(const std::string &file); }; namespace std { -template <> -struct hash { +template <> struct hash { std::size_t operator()(llvm::sys::fs::UniqueID ID) const { size_t ret = ID.getDevice(); hash_combine(ret, ID.getFile()); return ret; } }; -} +} // namespace std // FileConsumer is used by the indexer. When it encouters a file, it tries to // take ownership over it. If the indexer has ownership over a file, it will @@ -60,7 +59,7 @@ struct hash { // The indexer does this because header files do not have their own translation // units but we still want to index them. struct FileConsumer { - FileConsumer(VFS* vfs, const std::string& parse_file); + FileConsumer(VFS *vfs, const std::string &parse_file); // Returns IndexFile for the file or nullptr. |is_first_ownership| is set // to true iff the function just took ownership over the file. Otherwise it @@ -68,15 +67,17 @@ struct FileConsumer { // // note: file_contents is passed as a parameter instead of as a member // variable since it is large and we do not want to copy it. - IndexFile* TryConsumeFile(const clang::FileEntry& file, - std::unordered_map* file_contents); + IndexFile * + TryConsumeFile(const clang::FileEntry &file, + std::unordered_map *file_contents); // Returns and passes ownership of all local state. std::vector> TakeLocalState(); - private: - std::unordered_map> local_; - VFS* vfs_; +private: + std::unordered_map> + local_; + VFS *vfs_; std::string parse_file_; int thread_id_; }; diff --git a/src/filesystem.cc b/src/filesystem.cc index 7ff90c851..55a68db99 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -6,10 +6,8 @@ using namespace llvm; #include #include -void GetFilesInFolder(std::string folder, - bool recursive, - bool dir_prefix, - const std::function& handler) { +void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix, + const std::function &handler) { EnsureEndsInSlash(folder); sys::fs::file_status Status; if (sys::fs::status(folder, Status, true)) @@ -20,7 +18,7 @@ void GetFilesInFolder(std::string folder, std::set seen{Status.getUniqueID()}; while (curr.size() || succ.size()) { if (curr.empty()) { - for (auto& it : succ) + for (auto &it : succ) if (!seen.count(it.second.getUniqueID())) curr.push_back(std::move(it.first)); succ.clear(); diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 187d91c4a..81c281837 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -1,8 +1,8 @@ #include "fuzzy_match.h" +#include #include #include -#include #include enum CharClass { Other, Lower, Upper }; @@ -17,7 +17,7 @@ CharClass GetCharClass(int c) { return Other; } -void CalculateRoles(std::string_view s, int roles[], int* class_set) { +void CalculateRoles(std::string_view s, int roles[], int *class_set) { if (s.empty()) { *class_set = 0; return; @@ -41,7 +41,7 @@ void CalculateRoles(std::string_view s, int roles[], int* class_set) { } roles[s.size() - 1] = fn(); } -} // namespace +} // namespace int FuzzyMatcher::MissScore(int j, bool last) { int s = -3; diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 9dd132efd..c92476d29 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -5,7 +5,7 @@ #include class FuzzyMatcher { - public: +public: constexpr static int kMaxPat = 100; constexpr static int kMaxText = 200; // Negative but far from INT_MIN so that intermediate results are hard to @@ -15,7 +15,7 @@ class FuzzyMatcher { FuzzyMatcher(std::string_view pattern, int case_sensitivity); int Match(std::string_view text); - private: +private: int case_sensitivity; std::string pat; std::string_view text; diff --git a/src/include_complete.cc b/src/include_complete.cc index 7412f6b11..a24de5f4c 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -19,7 +19,7 @@ struct CompletionCandidate { lsCompletionItem completion_item; }; -std::string ElideLongPath(const std::string& path) { +std::string ElideLongPath(const std::string &path) { if (g_config->completion.includeMaxPathSize <= 0) return path; @@ -30,8 +30,8 @@ std::string ElideLongPath(const std::string& path) { return ".." + path.substr(start + 2); } -size_t TrimCommonPathPrefix(const std::string& result, - const std::string& trimmer) { +size_t TrimCommonPathPrefix(const std::string &result, + const std::string &trimmer) { #ifdef _WIN32 std::string s = result, t = trimmer; std::transform(s.begin(), s.end(), s.begin(), ::tolower); @@ -46,16 +46,15 @@ size_t TrimCommonPathPrefix(const std::string& result, } // Returns true iff angle brackets should be used. -bool TrimPath(Project* project, - const std::string& project_root, - std::string* insert_path) { +bool TrimPath(Project *project, const std::string &project_root, + std::string *insert_path) { size_t start = TrimCommonPathPrefix(*insert_path, project_root); bool angle = false; - for (auto& include_dir : project->quote_include_directories) + for (auto &include_dir : project->quote_include_directories) start = std::max(start, TrimCommonPathPrefix(*insert_path, include_dir)); - for (auto& include_dir : project->angle_include_directories) { + for (auto &include_dir : project->angle_include_directories) { auto len = TrimCommonPathPrefix(*insert_path, include_dir); if (len > start) { start = len; @@ -67,12 +66,11 @@ bool TrimPath(Project* project, return angle; } -lsCompletionItem BuildCompletionItem(const std::string& path, - bool use_angle_brackets, - bool is_stl) { +lsCompletionItem BuildCompletionItem(const std::string &path, + bool use_angle_brackets, bool is_stl) { lsCompletionItem item; item.label = ElideLongPath(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; @@ -87,9 +85,9 @@ lsCompletionItem BuildCompletionItem(const std::string& path, return item; } -} // namespace +} // namespace -IncludeComplete::IncludeComplete(Project* project) +IncludeComplete::IncludeComplete(Project *project) : is_scanning(false), project_(project) {} void IncludeComplete::Rescan() { @@ -102,8 +100,9 @@ void IncludeComplete::Rescan() { if (!match_ && (g_config->completion.includeWhitelist.size() || g_config->completion.includeBlacklist.size())) - match_ = std::make_unique(g_config->completion.includeWhitelist, - g_config->completion.includeBlacklist); + match_ = + std::make_unique(g_config->completion.includeWhitelist, + g_config->completion.includeBlacklist); is_scanning = true; std::thread([this]() { @@ -111,17 +110,18 @@ void IncludeComplete::Rescan() { Timer timer("include", "scan include paths"); TimeRegion region(timer); - for (const std::string& dir : project_->quote_include_directories) + for (const std::string &dir : project_->quote_include_directories) InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); - for (const std::string& dir : project_->angle_include_directories) + for (const std::string &dir : project_->angle_include_directories) InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/); is_scanning = false; - }).detach(); + }) + .detach(); } -void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, - lsCompletionItem&& item) { +void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, + lsCompletionItem &&item) { if (inserted_paths.insert({item.detail, inserted_paths.size()}).second) { completion_items.push_back(item); // insert if not found or with shorter include path @@ -132,7 +132,7 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, completion_items.size() - 1; } } else { - lsCompletionItem& inserted_item = + lsCompletionItem &inserted_item = completion_items[inserted_paths[item.detail]]; // Update |use_angle_brackets_|, prefer quotes. if (!item.use_angle_brackets_) @@ -140,7 +140,7 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path, } } -void IncludeComplete::AddFile(const std::string& absolute_path) { +void IncludeComplete::AddFile(const std::string &absolute_path) { if (!EndsWithAny(absolute_path, g_config->completion.includeSuffixWhitelist)) return; if (match_ && !match_->IsMatch(absolute_path)) @@ -184,13 +184,14 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, }); std::lock_guard lock(completion_items_mutex); - for (CompletionCandidate& result : results) + for (CompletionCandidate &result : results) InsertCompletionItem(result.absolute_path, std::move(result.completion_item)); } -std::optional IncludeComplete::FindCompletionItemForAbsolutePath( - const std::string& absolute_path) { +std::optional +IncludeComplete::FindCompletionItemForAbsolutePath( + const std::string &absolute_path) { std::lock_guard lock(completion_items_mutex); auto it = absolute_path_to_completion_item.find(absolute_path); diff --git a/src/include_complete.h b/src/include_complete.h index c45c25622..692658021 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -10,26 +10,26 @@ struct GroupMatch; struct Project; struct IncludeComplete { - IncludeComplete(Project* project); + IncludeComplete(Project *project); // Starts scanning directories. Clears existing cache. void Rescan(); // Ensures the one-off file is inside |completion_items|. - void AddFile(const std::string& absolute_path); + void AddFile(const std::string &absolute_path); // Scans the given directory and inserts all includes from this. This is a // blocking function and should be run off the querydb thread. void InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets); - std::optional FindCompletionItemForAbsolutePath( - const std::string& absolute_path); + std::optional + FindCompletionItemForAbsolutePath(const std::string &absolute_path); // Insert item to |completion_items|. // Update |absolute_path_to_completion_item| and |inserted_paths|. - void InsertCompletionItem(const std::string& absolute_path, - lsCompletionItem&& item); + void InsertCompletionItem(const std::string &absolute_path, + lsCompletionItem &&item); // Guards |completion_items| when |is_scanning| is true. std::mutex completion_items_mutex; @@ -44,6 +44,6 @@ struct IncludeComplete { std::unordered_map inserted_paths; // Cached references - Project* project_; + Project *project_; std::unique_ptr match_; }; diff --git a/src/indexer.cc b/src/indexer.cc index 280cf3a2f..d37e56b40 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -21,9 +21,9 @@ using ccls::Intern; using namespace clang; using llvm::Timer; +#include #include #include -#include #include #include @@ -40,14 +40,14 @@ struct IndexParam { std::string short_name; std::string qualified; }; - std::unordered_map Decl2Info; + std::unordered_map Decl2Info; - ASTUnit& Unit; - ASTContext* Ctx; + ASTUnit &Unit; + ASTContext *Ctx; - FileConsumer* file_consumer = nullptr; + FileConsumer *file_consumer = nullptr; - IndexParam(ASTUnit& Unit, FileConsumer* file_consumer) + IndexParam(ASTUnit &Unit, FileConsumer *file_consumer) : Unit(Unit), file_consumer(file_consumer) {} IndexFile *ConsumeFile(const FileEntry &File) { @@ -63,7 +63,7 @@ struct IndexParam { // Set modification time. std::optional write_time = LastWriteTime(file_name); LOG_IF_S(ERROR, !write_time) - << "failed to fetch write time for " << file_name; + << "failed to fetch write time for " << file_name; if (write_time) file2write_time[file_name] = *write_time; } @@ -81,12 +81,13 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, StringRef Buf = SM.getBufferData(BInfo.first, &invalid); if (invalid) return ""; - return Buf.substr(BInfo.second, EInfo.second + Lexer::MeasureTokenLength( - ELoc, SM, LangOpts) - - BInfo.second); + return Buf.substr(BInfo.second, + EInfo.second + + Lexer::MeasureTokenLength(ELoc, SM, LangOpts) - + BInfo.second); } -SymbolKind GetSymbolKind(const Decl* D) { +SymbolKind GetSymbolKind(const Decl *D) { switch (D->getKind()) { case Decl::TranslationUnit: return SymbolKind::File; @@ -136,46 +137,46 @@ SymbolKind GetSymbolKind(const Decl* D) { LanguageId GetDeclLanguage(const Decl *D) { switch (D->getKind()) { - default: - return LanguageId::C; - case Decl::ImplicitParam: - case Decl::ObjCAtDefsField: - case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: - case Decl::ObjCCompatibleAlias: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCIvar: - case Decl::ObjCMethod: - case Decl::ObjCProperty: - case Decl::ObjCPropertyImpl: - case Decl::ObjCProtocol: - case Decl::ObjCTypeParam: - return LanguageId::ObjC; - case Decl::CXXConstructor: - case Decl::CXXConversion: - case Decl::CXXDestructor: - case Decl::CXXMethod: - case Decl::CXXRecord: - case Decl::ClassTemplate: - case Decl::ClassTemplatePartialSpecialization: - case Decl::ClassTemplateSpecialization: - case Decl::Friend: - case Decl::FriendTemplate: - case Decl::FunctionTemplate: - case Decl::LinkageSpec: - case Decl::Namespace: - case Decl::NamespaceAlias: - case Decl::NonTypeTemplateParm: - case Decl::StaticAssert: - case Decl::TemplateTemplateParm: - case Decl::TemplateTypeParm: - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - case Decl::Using: - case Decl::UsingDirective: - case Decl::UsingShadow: - return LanguageId::Cpp; + default: + return LanguageId::C; + case Decl::ImplicitParam: + case Decl::ObjCAtDefsField: + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCCompatibleAlias: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCIvar: + case Decl::ObjCMethod: + case Decl::ObjCProperty: + case Decl::ObjCPropertyImpl: + case Decl::ObjCProtocol: + case Decl::ObjCTypeParam: + return LanguageId::ObjC; + case Decl::CXXConstructor: + case Decl::CXXConversion: + case Decl::CXXDestructor: + case Decl::CXXMethod: + case Decl::CXXRecord: + case Decl::ClassTemplate: + case Decl::ClassTemplatePartialSpecialization: + case Decl::ClassTemplateSpecialization: + case Decl::Friend: + case Decl::FriendTemplate: + case Decl::FunctionTemplate: + case Decl::LinkageSpec: + case Decl::Namespace: + case Decl::NamespaceAlias: + case Decl::NonTypeTemplateParm: + case Decl::StaticAssert: + case Decl::TemplateTemplateParm: + case Decl::TemplateTypeParm: + case Decl::UnresolvedUsingTypename: + case Decl::UnresolvedUsingValue: + case Decl::Using: + case Decl::UsingDirective: + case Decl::UsingShadow: + return LanguageId::Cpp; } } @@ -187,7 +188,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) { BaseType = PTy->getPointeeType(); else if (const BlockPointerType *BPy = BaseType->getAs()) BaseType = BPy->getPointeeType(); - else if (const ArrayType* ATy = dyn_cast(BaseType)) + else if (const ArrayType *ATy = dyn_cast(BaseType)) BaseType = ATy->getElementType(); else if (const VectorType *VTy = BaseType->getAs()) BaseType = VTy->getElementType(); @@ -200,8 +201,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) { BaseType = ATy->getDeducedType(); else break; - } - else + } else break; } return BaseType; @@ -210,7 +210,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) { const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { Decl *D = nullptr; T = GetBaseType(T.getUnqualifiedType(), true); - const Type* TP = T.getTypePtrOrNull(); + const Type *TP = T.getTypePtrOrNull(); if (!TP) return nullptr; @@ -254,7 +254,7 @@ const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { D = cast(TP)->getDecl(); break; - // FIXME: Template type parameters! + // FIXME: Template type parameters! case Type::Elaborated: TP = cast(TP)->getNamedType().getTypePtrOrNull(); @@ -266,19 +266,19 @@ const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { return D; } -const Decl* GetSpecialized(const Decl* D) { +const Decl *GetSpecialized(const Decl *D) { if (!D) return D; Decl *Template = nullptr; if (const CXXRecordDecl *CXXRecord = dyn_cast(D)) { - if (const ClassTemplatePartialSpecializationDecl *PartialSpec - = dyn_cast(CXXRecord)) + if (const ClassTemplatePartialSpecializationDecl *PartialSpec = + dyn_cast(CXXRecord)) Template = PartialSpec->getSpecializedTemplate(); - else if (const ClassTemplateSpecializationDecl *ClassSpec - = dyn_cast(CXXRecord)) { + else if (const ClassTemplateSpecializationDecl *ClassSpec = + dyn_cast(CXXRecord)) { llvm::PointerUnion Result - = ClassSpec->getSpecializedTemplateOrPartial(); + ClassTemplatePartialSpecializationDecl *> + Result = ClassSpec->getSpecializedTemplateOrPartial(); if (Result.is()) Template = Result.get(); else @@ -293,8 +293,8 @@ const Decl* GetSpecialized(const Decl* D) { } else if (const VarDecl *Var = dyn_cast(D)) { if (Var->isStaticDataMember()) Template = Var->getInstantiatedFromStaticDataMember(); - } else if (const RedeclarableTemplateDecl *Tmpl - = dyn_cast(D)) + } else if (const RedeclarableTemplateDecl *Tmpl = + dyn_cast(D)) Template = Tmpl->getInstantiatedFromMemberTemplate(); else return nullptr; @@ -302,7 +302,7 @@ const Decl* GetSpecialized(const Decl* D) { } bool ValidateRecord(const RecordDecl *RD) { - for (const auto *I : RD->fields()){ + for (const auto *I : RD->fields()) { QualType FQT = I->getType(); if (FQT->isIncompleteType() || FQT->isDependentType()) return false; @@ -317,12 +317,13 @@ bool ValidateRecord(const RecordDecl *RD) { class IndexDataConsumer : public index::IndexDataConsumer { public: ASTContext *Ctx; - IndexParam& param; + IndexParam ¶m; - std::string GetComment(const Decl* D) { + std::string GetComment(const Decl *D) { SourceManager &SM = Ctx->getSourceManager(); const RawComment *RC = Ctx->getRawCommentForAnyRedecl(D); - if (!RC) return ""; + if (!RC) + return ""; StringRef Raw = RC->getRawText(Ctx->getSourceManager()); SourceRange R = RC->getSourceRange(); std::pair BInfo = SM.getDecomposedLoc(R.getBegin()); @@ -425,7 +426,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { return PP; } - static void SimplifyAnonymous(std::string& name) { + static void SimplifyAnonymous(std::string &name) { for (std::string::size_type i = 0;;) { if ((i = name.find("(anonymous ", i)) == std::string::npos) break; @@ -479,7 +480,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { void SetVarName(const Decl *D, std::string_view short_name, std::string_view qualified, IndexVar::Def &def) { QualType T; - const Expr* init = nullptr; + const Expr *init = nullptr; bool binding = false; if (auto *VD = dyn_cast(D)) { T = VD->getType(); @@ -499,7 +500,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { PrintingPolicy PP = GetDefaultPolicy(); T.print(OS, PP); if (Str.size() && - (Str.back() != ' ' && Str.back() != '*' && Str.back() != '&')) + (Str.back() != ' ' && Str.back() != '*' && Str.back() != '&')) Str += ' '; def.qual_name_offset = Str.size(); def.short_name_offset = Str.size() + qualified.size() - short_name.size(); @@ -511,7 +512,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { } if (init) { SourceManager &SM = Ctx->getSourceManager(); - const LangOptions& Lang = Ctx->getLangOpts(); + const LangOptions &Lang = Ctx->getLangOpts(); SourceRange R = SM.getExpansionRange(init->getSourceRange()) #if LLVM_VERSION_MAJOR >= 7 .getAsRange() @@ -536,7 +537,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, SourceLocation Spell) const { const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); - if (!FE) return; + if (!FE) + return; auto UID = FE->getUniqueID(); auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID); if (inserted) { @@ -568,10 +570,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { } public: - IndexDataConsumer(IndexParam& param) : param(param) {} - void initialize(ASTContext &Ctx) override { - this->Ctx = param.Ctx = &Ctx; - } + IndexDataConsumer(IndexParam ¶m) : param(param) {} + void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, #if LLVM_VERSION_MAJOR >= 7 @@ -618,7 +618,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!db) return true; - const Decl* OrigD = ASTNode.OrigD; + const Decl *OrigD = ASTNode.OrigD; const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *LexDC = ASTNode.ContainerDC; Role role = static_cast(Roles); @@ -632,7 +632,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexType *type = nullptr; IndexVar *var = nullptr; SymbolKind kind = GetSymbolKind(D); - IndexParam::DeclInfo* info; + IndexParam::DeclInfo *info; Usr usr = GetUsr(D, &info); auto do_def_decl = [&](auto *entity) { @@ -690,7 +690,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (type->def.detailed_name[0] == '\0') SetName(OrigD, info->short_name, info->qualified, type->def); if (is_def || is_decl) { - const Decl* DC = cast(SemDC); + const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) db->ToType(GetUsr(DC)).def.types.push_back(usr); } @@ -720,7 +720,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { db->ToType(usr1).instances.push_back(usr); } else { for (const Decl *D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { - IndexParam::DeclInfo* info1; + IndexParam::DeclInfo *info1; Usr usr1 = GetUsr(D1, &info1); auto it = db->usr2type.find(usr1); if (it != db->usr2type.end()) { @@ -728,10 +728,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { it->second.instances.push_back(usr); break; } - // e.g. TemplateTypeParmDecl is not handled by handleDeclOccurence. + // e.g. TemplateTypeParmDecl is not handled by + // handleDeclOccurence. SourceRange R1 = D1->getSourceRange(); if (SM.getFileID(R1.getBegin()) == LocFID) { - IndexType& type1 = db->ToType(usr1); + IndexType &type1 = db->ToType(usr1); SourceLocation L1 = D1->getLocation(); type1.def.spell = GetUse(db, FromTokenRange(SM, Lang, {L1, L1}), SemDC, Role::Definition); @@ -935,7 +936,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (auto *ND = dyn_cast(D)) { SmallVector OverDecls; Ctx->getOverriddenMethods(ND, OverDecls); - for (const auto* ND1 : OverDecls) { + for (const auto *ND1 : OverDecls) { Usr usr1 = GetUsr(ND1); func->def.bases.push_back(usr1); db->ToFunc(usr1).derived.push_back(usr); @@ -988,10 +989,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { }; class IndexPPCallbacks : public PPCallbacks { - SourceManager& SM; - IndexParam& param; + SourceManager &SM; + IndexParam ¶m; - std::pair GetMacro(const Token& Tok) const { + std::pair GetMacro(const Token &Tok) const { StringRef Name = Tok.getIdentifierInfo()->getName(); SmallString<256> USR("@macro@"); USR += Name; @@ -1028,13 +1029,13 @@ class IndexPPCallbacks : public PPCallbacks { } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { llvm::sys::fs::UniqueID UniqueID; - const LangOptions& Lang = param.Ctx->getLangOpts(); + const LangOptions &Lang = param.Ctx->getLangOpts(); SourceLocation L = MD->getLocation(); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { - auto[Name, usr] = GetMacro(Tok); + auto [Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); var.def.kind = lsSymbolKind::Macro; @@ -1056,15 +1057,15 @@ class IndexPPCallbacks : public PPCallbacks { } } } - void MacroExpands(const Token &Tok, const MacroDefinition &MD, - SourceRange R, const MacroArgs *Args) override { + void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R, + const MacroArgs *Args) override { llvm::sys::fs::UniqueID UniqueID; SourceLocation L = SM.getSpellingLoc(R.getBegin()); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { - auto[Name, usr] = GetMacro(Tok); + auto [Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); var.uses.push_back( {{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), 0, @@ -1088,17 +1089,19 @@ class IndexPPCallbacks : public PPCallbacks { }; class IndexFrontendAction : public ASTFrontendAction { - IndexParam& param; + IndexParam ¶m; + public: - IndexFrontendAction(IndexParam& param) : param(param) {} + IndexFrontendAction(IndexParam ¶m) : param(param) {} std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { Preprocessor &PP = CI.getPreprocessor(); - PP.addPPCallbacks(std::make_unique(PP.getSourceManager(), param)); + PP.addPPCallbacks( + std::make_unique(PP.getSourceManager(), param)); return std::make_unique(); } }; -} +} // namespace const int IndexFile::kMajorVersion = 17; const int IndexFile::kMinorVersion = 1; @@ -1107,21 +1110,21 @@ IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) : UniqueID(UniqueID), path(path), file_contents(contents) {} -IndexFunc& IndexFile::ToFunc(Usr usr) { +IndexFunc &IndexFile::ToFunc(Usr usr) { auto [it, inserted] = usr2func.try_emplace(usr); if (inserted) it->second.usr = usr; return it->second; } -IndexType& IndexFile::ToType(Usr usr) { +IndexType &IndexFile::ToType(Usr usr) { auto [it, inserted] = usr2type.try_emplace(usr); if (inserted) it->second.usr = usr; return it->second; } -IndexVar& IndexFile::ToVar(Usr usr) { +IndexVar &IndexFile::ToVar(Usr usr) { auto [it, inserted] = usr2var.try_emplace(usr); if (inserted) it->second.usr = usr; @@ -1132,8 +1135,7 @@ std::string IndexFile::ToString() { return ccls::Serialize(SerializeFormat::Json, *this); } -template -void Uniquify(std::vector& a) { +template void Uniquify(std::vector &a) { std::unordered_set seen; size_t n = 0; for (size_t i = 0; i < a.size(); i++) @@ -1143,21 +1145,19 @@ void Uniquify(std::vector& a) { } namespace ccls::idx { -std::vector> Index( - VFS* vfs, - const std::string& opt_wdir, - const std::string& file, - const std::vector& args, - const std::vector& file_contents) { +std::vector> +Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, + const std::vector &args, + const std::vector &file_contents) { if (!g_config->index.enabled) return {}; std::vector Args; - for (auto& arg: args) + for (auto &arg : args) Args.push_back(arg.c_str()); auto PCHCO = std::make_shared(); - IntrusiveRefCntPtr - Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + IntrusiveRefCntPtr Diags( + CompilerInstance::createDiagnostics(new DiagnosticOptions)); std::shared_ptr CI = createInvocationFromCommandLine(Args, Diags); if (!CI) @@ -1225,34 +1225,34 @@ std::vector> Index( return {}; } - const SourceManager& SM = Unit->getSourceManager(); - const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); - IndexFile* main_file = param.ConsumeFile(*FE); + const SourceManager &SM = Unit->getSourceManager(); + const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID()); + IndexFile *main_file = param.ConsumeFile(*FE); std::unordered_map inc_to_line; if (main_file) - for (auto& inc : main_file->includes) + for (auto &inc : main_file->includes) inc_to_line[inc.resolved_path] = inc.line; auto result = param.file_consumer->TakeLocalState(); - for (std::unique_ptr& entry : result) { + for (std::unique_ptr &entry : result) { entry->import_file = file; entry->args = args; for (auto &[_, it] : entry->uid2lid_and_path) entry->lid2path.emplace_back(it.first, std::move(it.second)); entry->uid2lid_and_path.clear(); - for (auto& it : entry->usr2func) { + for (auto &it : entry->usr2func) { // e.g. declaration + out-of-line definition Uniquify(it.second.derived); Uniquify(it.second.uses); } - for (auto& it : entry->usr2type) { + for (auto &it : entry->usr2type) { Uniquify(it.second.derived); Uniquify(it.second.uses); // e.g. declaration + out-of-line definition Uniquify(it.second.def.bases); Uniquify(it.second.def.funcs); } - for (auto& it : entry->usr2var) + for (auto &it : entry->usr2var) Uniquify(it.second.uses); if (main_file) { @@ -1283,7 +1283,7 @@ std::vector> Index( return result; } -} +} // namespace ccls::idx // |SymbolRef| is serialized this way. // |Use| also uses this though it has an extra field |file|, @@ -1319,10 +1319,10 @@ void Reflect(Writer &vis, Reference &v) { } } -void Reflect(Reader& vis, Use& v) { +void Reflect(Reader &vis, Use &v) { if (vis.Format() == SerializeFormat::Json) { std::string t = vis.GetString(); - char* s = const_cast(t.c_str()); + char *s = const_cast(t.c_str()); v.range = Range::FromString(s); s = strchr(s, '|'); v.usr = strtoull(s + 1, &s, 10); @@ -1331,11 +1331,11 @@ void Reflect(Reader& vis, Use& v) { if (*s == '|') v.file_id = static_cast(strtol(s + 1, &s, 10)); } else { - Reflect(vis, static_cast(v)); + Reflect(vis, static_cast(v)); Reflect(vis, v.file_id); } } -void Reflect(Writer& vis, Use& v) { +void Reflect(Writer &vis, Use &v) { if (vis.Format() == SerializeFormat::Json) { char buf[99]; if (v.file_id == -1) @@ -1348,7 +1348,7 @@ void Reflect(Writer& vis, Use& v) { std::string s(buf); Reflect(vis, s); } else { - Reflect(vis, static_cast(v)); + Reflect(vis, static_cast(v)); Reflect(vis, v.file_id); } } diff --git a/src/indexer.h b/src/indexer.h index e43cfc5f6..ff1e1e7be 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -14,9 +14,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -27,10 +27,10 @@ struct SymbolIdx { Usr usr; SymbolKind kind; - bool operator==(const SymbolIdx& o) const { + bool operator==(const SymbolIdx &o) const { return usr == o.usr && kind == o.kind; } - bool operator<(const SymbolIdx& o) const { + bool operator<(const SymbolIdx &o) const { return usr != o.usr ? usr < o.usr : kind < o.kind; } }; @@ -47,8 +47,8 @@ struct Reference { std::tuple ToTuple() const { return std::make_tuple(range, usr, 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. @@ -60,22 +60,21 @@ MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role); struct Use : Reference { // |file| is used in Query* but not in Index* int file_id = -1; - bool operator==(const Use& o) const { + bool operator==(const Use &o) const { // lexical container info is ignored. return range == o.range && file_id == o.file_id; } }; MAKE_HASHABLE(Use, t.range, t.file_id) -void Reflect(Reader& visitor, Reference& value); -void Reflect(Writer& visitor, Reference& value); -void Reflect(Reader& visitor, Use& value); -void Reflect(Writer& visitor, Use& value); +void Reflect(Reader &visitor, Reference &value); +void Reflect(Writer &visitor, Reference &value); +void Reflect(Reader &visitor, Use &value); +void Reflect(Writer &visitor, Use &value); -template -struct NameMixin { +template struct NameMixin { std::string_view Name(bool qualified) const { - auto self = static_cast(this); + auto self = static_cast(this); return qualified ? std::string_view(self->detailed_name + self->qual_name_offset, self->short_name_offset - @@ -88,9 +87,9 @@ struct NameMixin { struct FuncDef : NameMixin { // General metadata. - const char* detailed_name = ""; - const char* hover = ""; - const char* comments = ""; + const char *detailed_name = ""; + const char *hover = ""; + const char *comments = ""; Maybe spell; Maybe extent; @@ -112,20 +111,9 @@ struct FuncDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(FuncDef, - detailed_name, - qual_name_offset, - short_name_offset, - short_name_size, - kind, - storage, - hover, - comments, - spell, - extent, - bases, - vars, - callees); +MAKE_REFLECT_STRUCT(FuncDef, detailed_name, qual_name_offset, short_name_offset, + short_name_size, kind, storage, hover, comments, spell, + extent, bases, vars, callees); struct IndexFunc : NameMixin { using Def = FuncDef; @@ -137,9 +125,9 @@ struct IndexFunc : NameMixin { }; struct TypeDef : NameMixin { - const char* detailed_name = ""; - const char* hover = ""; - const char* comments = ""; + const char *detailed_name = ""; + const char *hover = ""; + const char *comments = ""; Maybe spell; Maybe extent; @@ -163,21 +151,9 @@ struct TypeDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(TypeDef, - detailed_name, - qual_name_offset, - short_name_offset, - short_name_size, - kind, - hover, - comments, - spell, - extent, - alias_of, - bases, - types, - funcs, - vars); +MAKE_REFLECT_STRUCT(TypeDef, detailed_name, qual_name_offset, short_name_offset, + short_name_size, kind, hover, comments, spell, extent, + alias_of, bases, types, funcs, vars); struct IndexType { using Def = TypeDef; @@ -191,9 +167,9 @@ struct IndexType { struct VarDef : NameMixin { // General metadata. - const char* detailed_name = ""; - const char* hover = ""; - const char* comments = ""; + const char *detailed_name = ""; + const char *hover = ""; + const char *comments = ""; Maybe spell; Maybe extent; @@ -217,17 +193,8 @@ struct VarDef : NameMixin { std::vector GetBases() const { return {}; } }; -MAKE_REFLECT_STRUCT(VarDef, - detailed_name, - qual_name_offset, - short_name_offset, - short_name_size, - hover, - comments, - spell, - extent, - type, - kind, +MAKE_REFLECT_STRUCT(VarDef, detailed_name, qual_name_offset, short_name_offset, + short_name_size, hover, comments, spell, extent, type, kind, storage); struct IndexVar { @@ -289,9 +256,9 @@ struct IndexFile { IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents); - IndexFunc& ToFunc(Usr usr); - IndexType& ToType(Usr usr); - IndexVar& ToVar(Usr usr); + IndexFunc &ToFunc(Usr usr); + IndexType &ToType(Usr usr); + IndexVar &ToVar(Usr usr); std::string ToString(); }; @@ -299,6 +266,6 @@ struct IndexFile { namespace ccls::idx { std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, - const std::vector &args, - const std::vector &file_contents); + const std::vector &args, + const std::vector &file_contents); } diff --git a/src/language.cc b/src/language.cc index ee749fcf1..de64e69ed 100644 --- a/src/language.cc +++ b/src/language.cc @@ -14,7 +14,7 @@ LanguageId SourceFileLanguage(std::string_view path) { return LanguageId::Unknown; } -const char* LanguageIdentifier(LanguageId lang) { +const char *LanguageIdentifier(LanguageId lang) { switch (lang) { case LanguageId::C: return "c"; diff --git a/src/language.h b/src/language.h index c2bc335cb..4a34152fe 100644 --- a/src/language.h +++ b/src/language.h @@ -11,4 +11,4 @@ enum class LanguageId { Unknown = 0, C = 1, Cpp = 2, ObjC = 3, ObjCpp = 4 }; MAKE_REFLECT_TYPE_PROXY(LanguageId); LanguageId SourceFileLanguage(std::string_view path); -const char* LanguageIdentifier(LanguageId lang); +const char *LanguageIdentifier(LanguageId lang); diff --git a/src/log.cc b/src/log.cc index 573f9184e..377dc79ce 100644 --- a/src/log.cc +++ b/src/log.cc @@ -3,18 +3,18 @@ #include #include +#include +#include #include #include #include -#include -#include namespace ccls::log { static std::mutex mtx; -FILE* file; +FILE *file; Verbosity verbosity; -Message::Message(Verbosity verbosity, const char* file, int line) +Message::Message(Verbosity verbosity, const char *file, int line) : verbosity_(verbosity) { using namespace llvm; time_t tim = time(NULL); @@ -32,7 +32,7 @@ Message::Message(Verbosity verbosity, const char* file, int line) stream_ << std::left << std::setw(13) << Name.c_str(); } { - const char* p = strrchr(file, '/'); + const char *p = strrchr(file, '/'); if (p) file = p + 1; stream_ << std::right << std::setw(15) << file << ':' << std::left @@ -52,11 +52,12 @@ Message::Message(Verbosity verbosity, const char* file, int line) } Message::~Message() { - if (!file) return; + if (!file) + return; std::lock_guard lock(mtx); stream_ << '\n'; fputs(stream_.str().c_str(), file); if (verbosity_ == Verbosity_FATAL) abort(); } -} +} // namespace ccls::log diff --git a/src/lru_cache.h b/src/lru_cache.h index c6e3d9c4b..b52c3bfb3 100644 --- a/src/lru_cache.h +++ b/src/lru_cache.h @@ -8,31 +8,29 @@ // Cache that evicts old entries which have not been used recently. Implemented // using array/linear search so this works well for small array sizes. -template -struct LruCache { +template struct LruCache { explicit LruCache(int max_entries); // Fetches an entry for |key|. If it does not exist, |allocator| will be // invoked to create one. template - std::shared_ptr Get(const TKey& key, TAllocator allocator); + std::shared_ptr Get(const TKey &key, TAllocator allocator); // Fetches the entry for |filename| and updates it's usage so it is less // likely to be evicted. - std::shared_ptr TryGet(const TKey& key); + std::shared_ptr TryGet(const TKey &key); // TryGetEntry, except the entry is removed from the cache. - std::shared_ptr TryTake(const TKey& key); + std::shared_ptr TryTake(const TKey &key); // Inserts an entry. Evicts the oldest unused entry if there is no space. - void Insert(const TKey& key, const std::shared_ptr& value); + void Insert(const TKey &key, const std::shared_ptr &value); // Call |func| on existing entries. If |func| returns false iteration // temrinates early. - template - void IterateValues(TFunc func); + template void IterateValues(TFunc func); // Empties the cache void Clear(void); - private: +private: // There is a global score counter, when we access an element we increase // its score to the current global value, so it has the highest overall // score. This means that the oldest/least recently accessed value has the @@ -43,7 +41,7 @@ struct LruCache { uint32_t score = 0; TKey key; std::shared_ptr value; - bool operator<(const Entry& other) const { return score < other.score; } + bool operator<(const Entry &other) const { return score < other.score; } }; void IncrementScore(); @@ -60,7 +58,7 @@ LruCache::LruCache(int max_entries) : max_entries_(max_entries) { template template -std::shared_ptr LruCache::Get(const TKey& key, +std::shared_ptr LruCache::Get(const TKey &key, TAllocator allocator) { std::shared_ptr result = TryGet(key); if (!result) @@ -69,9 +67,9 @@ std::shared_ptr LruCache::Get(const TKey& key, } template -std::shared_ptr LruCache::TryGet(const TKey& key) { +std::shared_ptr LruCache::TryGet(const TKey &key) { // Assign new score. - for (Entry& entry : entries_) { + for (Entry &entry : entries_) { if (entry.key == key) { entry.score = next_score_; IncrementScore(); @@ -83,7 +81,7 @@ std::shared_ptr LruCache::TryGet(const TKey& key) { } template -std::shared_ptr LruCache::TryTake(const TKey& key) { +std::shared_ptr LruCache::TryTake(const TKey &key) { for (size_t i = 0; i < entries_.size(); ++i) { if (entries_[i].key == key) { std::shared_ptr copy = entries_[i].value; @@ -96,8 +94,8 @@ std::shared_ptr LruCache::TryTake(const TKey& key) { } template -void LruCache::Insert(const TKey& key, - const std::shared_ptr& value) { +void LruCache::Insert(const TKey &key, + const std::shared_ptr &value) { if ((int)entries_.size() >= max_entries_) entries_.erase(std::min_element(entries_.begin(), entries_.end())); @@ -112,7 +110,7 @@ void LruCache::Insert(const TKey& key, template template void LruCache::IterateValues(TFunc func) { - for (Entry& entry : entries_) { + for (Entry &entry : entries_) { if (!func(entry.value)) break; } @@ -123,13 +121,13 @@ void LruCache::IncrementScore() { // Overflow. if (++next_score_ == 0) { std::sort(entries_.begin(), entries_.end()); - for (Entry& entry : entries_) + for (Entry &entry : entries_) entry.score = next_score_++; } } template void LruCache::Clear(void) { - entries_.clear(); - next_score_ = 0; + entries_.clear(); + next_score_ = 0; } diff --git a/src/lsp.cc b/src/lsp.cc index 2968c399b..a931e3054 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -7,7 +7,7 @@ #include -MessageRegistry* MessageRegistry::instance_ = nullptr; +MessageRegistry *MessageRegistry::instance_ = nullptr; lsTextDocumentIdentifier lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { @@ -17,8 +17,8 @@ lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { } // Reads a JsonRpc message. |read| returns the next input character. -std::optional ReadJsonRpcContentFrom( - std::function()> read) { +std::optional +ReadJsonRpcContentFrom(std::function()> read) { // Read the content length. It is terminated by the "\r\n" sequence. int exit_seq = 0; std::string stringified_content_length; @@ -37,7 +37,7 @@ std::optional ReadJsonRpcContentFrom( stringified_content_length += c; } - const char* kContentLengthStart = "Content-Length: "; + const char *kContentLengthStart = "Content-Length: "; assert(StartsWith(stringified_content_length, kContentLengthStart)); int content_length = atoi(stringified_content_length.c_str() + strlen(kContentLengthStart)); @@ -78,8 +78,8 @@ std::optional ReadCharFromStdinBlocking() { return std::nullopt; } -std::optional MessageRegistry::ReadMessageFromStdin( - std::unique_ptr* message) { +std::optional +MessageRegistry::ReadMessageFromStdin(std::unique_ptr *message) { std::optional content = ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking); if (!content) { @@ -95,9 +95,8 @@ std::optional MessageRegistry::ReadMessageFromStdin( return Parse(json_reader, message); } -std::optional MessageRegistry::Parse( - Reader& visitor, - std::unique_ptr* message) { +std::optional +MessageRegistry::Parse(Reader &visitor, std::unique_ptr *message) { if (!visitor.HasMember("jsonrpc") || std::string(visitor["jsonrpc"]->GetString()) != "2.0") { LOG_S(FATAL) << "Bad or missing jsonrpc version"; @@ -111,20 +110,20 @@ std::optional MessageRegistry::Parse( return std::string("Unable to find registered handler for method '") + method + "'"; - Allocator& allocator = allocators[method]; + Allocator &allocator = allocators[method]; try { allocator(visitor, message); return std::nullopt; - } catch (std::invalid_argument& e) { + } catch (std::invalid_argument &e) { // *message is partially deserialized but some field (e.g. |id|) are likely // available. return std::string("Fail to parse '") + method + "' " + - static_cast(visitor).GetPath() + ", expected " + + static_cast(visitor).GetPath() + ", expected " + e.what(); } } -MessageRegistry* MessageRegistry::instance() { +MessageRegistry *MessageRegistry::instance() { if (!instance_) instance_ = new MessageRegistry(); @@ -133,7 +132,7 @@ MessageRegistry* MessageRegistry::instance() { lsBaseOutMessage::~lsBaseOutMessage() = default; -void lsBaseOutMessage::Write(std::ostream& out) { +void lsBaseOutMessage::Write(std::ostream &out) { rapidjson::StringBuffer output; rapidjson::Writer writer(output); JsonWriter json_writer{&writer}; @@ -144,8 +143,8 @@ void lsBaseOutMessage::Write(std::ostream& out) { out.flush(); } -void lsResponseError::Write(Writer& visitor) { - auto& value = *this; +void lsResponseError::Write(Writer &visitor) { + auto &value = *this; int code2 = static_cast(this->code); visitor.StartObject(); @@ -154,22 +153,22 @@ void lsResponseError::Write(Writer& visitor) { visitor.EndObject(); } -lsDocumentUri lsDocumentUri::FromPath(const std::string& path) { +lsDocumentUri lsDocumentUri::FromPath(const std::string &path) { lsDocumentUri result; result.SetPath(path); return result; } -bool lsDocumentUri::operator==(const lsDocumentUri& other) const { +bool lsDocumentUri::operator==(const lsDocumentUri &other) const { return raw_uri == other.raw_uri; } -void lsDocumentUri::SetPath(const std::string& path) { +void lsDocumentUri::SetPath(const std::string &path) { // file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests raw_uri = path; size_t index = raw_uri.find(":"); - if (index == 1) { // widows drive letters must always be 1 char + if (index == 1) { // widows drive letters must always be 1 char raw_uri.replace(raw_uri.begin() + index, raw_uri.begin() + index + 1, "%3A"); } @@ -231,11 +230,11 @@ std::string lsPosition::ToString() const { return std::to_string(line) + ":" + std::to_string(character); } -bool lsTextEdit::operator==(const lsTextEdit& that) { +bool lsTextEdit::operator==(const lsTextEdit &that) { return range == that.range && newText == that.newText; } -void Reflect(Writer& visitor, lsMarkedString& value) { +void Reflect(Writer &visitor, lsMarkedString &value) { // If there is a language, emit a `{language:string, value:string}` object. If // not, emit a string. if (value.language) { diff --git a/src/lsp.h b/src/lsp.h index 84fbf2e1d..6533d6e01 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -8,52 +8,50 @@ #include #include -#define REGISTER_IN_MESSAGE(type) \ +#define REGISTER_IN_MESSAGE(type) \ static MessageRegistryRegister type##message_handler_instance_; struct MessageRegistry { - static MessageRegistry* instance_; - static MessageRegistry* instance(); + static MessageRegistry *instance_; + static MessageRegistry *instance(); using Allocator = - std::function*)>; + std::function *)>; std::unordered_map allocators; - std::optional ReadMessageFromStdin( - std::unique_ptr* message); - std::optional Parse(Reader& visitor, - std::unique_ptr* message); + std::optional + ReadMessageFromStdin(std::unique_ptr *message); + std::optional Parse(Reader &visitor, + std::unique_ptr *message); }; -template -struct MessageRegistryRegister { +template struct MessageRegistryRegister { MessageRegistryRegister() { T dummy; std::string method_name = dummy.GetMethodType(); MessageRegistry::instance()->allocators[method_name] = - [](Reader& visitor, std::unique_ptr* message) { + [](Reader &visitor, std::unique_ptr *message) { *message = std::make_unique(); // Reflect may throw and *message will be partially deserialized. - Reflect(visitor, static_cast(**message)); + Reflect(visitor, static_cast(**message)); }; } }; struct lsBaseOutMessage { virtual ~lsBaseOutMessage(); - virtual void ReflectWriter(Writer&) = 0; + virtual void ReflectWriter(Writer &) = 0; // Send the message to the language client by writing it to stdout. - void Write(std::ostream& out); + void Write(std::ostream &out); }; -template -struct lsOutMessage : lsBaseOutMessage { +template struct lsOutMessage : lsBaseOutMessage { // All derived types need to reflect on the |jsonrpc| member. std::string jsonrpc = "2.0"; - void ReflectWriter(Writer& writer) override { - Reflect(writer, static_cast(*this)); + void ReflectWriter(Writer &writer) override { + Reflect(writer, static_cast(*this)); } }; @@ -75,7 +73,7 @@ struct lsResponseError { // Short description. std::string message; - void Write(Writer& visitor); + void Write(Writer &visitor); }; ///////////////////////////////////////////////////////////////////////////// @@ -87,28 +85,28 @@ struct lsResponseError { ///////////////////////////////////////////////////////////////////////////// struct lsDocumentUri { - static lsDocumentUri FromPath(const std::string& path); + static lsDocumentUri FromPath(const std::string &path); - bool operator==(const lsDocumentUri& other) const; + bool operator==(const lsDocumentUri &other) const; - void SetPath(const std::string& path); + void SetPath(const std::string &path); std::string GetPath() const; std::string raw_uri; }; template -void Reflect(TVisitor& visitor, lsDocumentUri& value) { +void Reflect(TVisitor &visitor, lsDocumentUri &value) { Reflect(visitor, value.raw_uri); } struct lsPosition { int line = 0; int character = 0; - bool operator==(const lsPosition& o) const { + bool operator==(const lsPosition &o) const { return line == o.line && character == o.character; } - bool operator<(const lsPosition& o) const { + bool operator<(const lsPosition &o) const { return line != o.line ? line < o.line : character < o.character; } std::string ToString() const; @@ -118,10 +116,10 @@ MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { lsPosition start; lsPosition end; - bool operator==(const lsRange& o) const { + bool operator==(const lsRange &o) const { return start == o.start && end == o.end; } - bool operator<(const lsRange& o) const { + bool operator<(const lsRange &o) const { return !(start == o.start) ? start < o.start : end < o.end; } }; @@ -130,10 +128,10 @@ MAKE_REFLECT_STRUCT(lsRange, start, end); struct lsLocation { lsDocumentUri uri; lsRange range; - bool operator==(const lsLocation& o) const { + bool operator==(const lsLocation &o) const { return uri == o.uri && range == o.range; } - bool operator<(const lsLocation& o) const { + bool operator<(const lsLocation &o) const { return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri : range < o.range; } @@ -192,8 +190,7 @@ struct lsLocationEx : lsLocation { }; MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role); -template -struct lsCommand { +template struct lsCommand { // Title of the command (ie, 'save') std::string title; // Actual command identifier. @@ -204,7 +201,7 @@ struct lsCommand { T arguments; }; template -void Reflect(TVisitor& visitor, lsCommand& value) { +void Reflect(TVisitor &visitor, lsCommand &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(title); REFLECT_MEMBER(command); @@ -212,8 +209,7 @@ void Reflect(TVisitor& visitor, lsCommand& value) { REFLECT_MEMBER_END(); } -template -struct lsCodeLens { +template struct lsCodeLens { // The range in which this code lens is valid. Should only span a single line. lsRange range; // The command this code lens represents. @@ -223,7 +219,7 @@ struct lsCodeLens { TData data; }; template -void Reflect(TVisitor& visitor, lsCodeLens& value) { +void Reflect(TVisitor &visitor, lsCodeLens &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(range); REFLECT_MEMBER(command); @@ -263,7 +259,7 @@ struct lsTextEdit { // empty string. std::string newText; - bool operator==(const lsTextEdit& that); + bool operator==(const lsTextEdit &that); }; MAKE_REFLECT_STRUCT(lsTextEdit, range, newText); @@ -321,7 +317,7 @@ struct lsMarkedString { std::optional language; std::string value; }; -void Reflect(Writer& visitor, lsMarkedString& value); +void Reflect(Writer &visitor, lsMarkedString &value); struct lsTextDocumentContentChangeEvent { // The range of the document that changed. @@ -337,8 +333,7 @@ struct lsTextDocumentDidChangeParams { lsVersionedTextDocumentIdentifier textDocument; std::vector contentChanges; }; -MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, - textDocument, +MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, textDocument, contentChanges); // Show a message to the user. @@ -360,7 +355,7 @@ struct Out_ShowLogMessage : public lsOutMessage { }; template -void Reflect(TVisitor& visitor, Out_ShowLogMessage& value) { +void Reflect(TVisitor &visitor, Out_ShowLogMessage &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(jsonrpc); std::string method = value.method(); diff --git a/src/lsp_completion.h b/src/lsp_completion.h index 1e49b39db..26e3ff4b2 100644 --- a/src/lsp_completion.h +++ b/src/lsp_completion.h @@ -106,9 +106,9 @@ struct lsCompletionItem { // nor with themselves. // std::vector additionalTextEdits; - // An std::optional command that is executed *after* inserting this completion. - // *Note* that additional modifications to the current document should be - // described with the additionalTextEdits-property. Command command; + // An std::optional command that is executed *after* inserting this + // completion. *Note* that additional modifications to the current document + // should be described with the additionalTextEdits-property. Command command; // An data entry field that is preserved on a completion item between // a completion and a completion resolve request. @@ -117,7 +117,7 @@ struct lsCompletionItem { // Use this helper to figure out what content the completion item will insert // into the document, as it could live in either |textEdit|, |insertText|, or // |label|. - const std::string& InsertedContent() const { + const std::string &InsertedContent() const { if (textEdit) return textEdit->newText; if (!insertText.empty()) @@ -125,13 +125,6 @@ struct lsCompletionItem { return label; } }; -MAKE_REFLECT_STRUCT(lsCompletionItem, - label, - kind, - detail, - documentation, - sortText, - insertText, - filterText, - insertTextFormat, +MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation, + sortText, insertText, filterText, insertTextFormat, textEdit); diff --git a/src/lsp_diagnostic.h b/src/lsp_diagnostic.h index 535047d58..f8dc5355c 100644 --- a/src/lsp_diagnostic.h +++ b/src/lsp_diagnostic.h @@ -88,7 +88,7 @@ struct Out_TextDocumentPublishDiagnostics Params params; }; template -void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) { +void Reflect(TVisitor &visitor, Out_TextDocumentPublishDiagnostics &value) { std::string method = "textDocument/publishDiagnostics"; REFLECT_MEMBER_START(); REFLECT_MEMBER(jsonrpc); @@ -96,6 +96,5 @@ void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) { REFLECT_MEMBER(params); REFLECT_MEMBER_END(); } -MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, - uri, +MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, uri, diagnostics); diff --git a/src/main.cc b/src/main.cc index 63c5148b8..c68a16f8d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -28,21 +28,21 @@ std::string g_init_options; namespace { opt opt_help("h", desc("Alias for -help")); opt opt_verbose("v", desc("verbosity"), init(0)); -opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests")); +opt opt_test_index("test-index", ValueOptional, init("!"), + desc("run index tests")); opt opt_init("init", desc("extra initialization options")); opt opt_log_file("log-file", desc("log"), value_desc("filename")); -opt opt_log_file_append("log-file-append", desc("log"), value_desc("filename")); +opt opt_log_file_append("log-file-append", desc("log"), + value_desc("filename")); list opt_extra(Positional, ZeroOrMore, desc("extra")); -void CloseLog() { - fclose(ccls::log::file); -} +void CloseLog() { fclose(ccls::log::file); } -} // namespace +} // namespace -int main(int argc, char** argv) { +int main(int argc, char **argv) { TraceMe(); sys::PrintStackTraceOnErrorSignal(argv[0]); @@ -98,9 +98,9 @@ int main(int argc, char** argv) { try { Config config; Reflect(json_reader, config); - } catch (std::invalid_argument& e) { + } catch (std::invalid_argument &e) { fprintf(stderr, "Failed to parse --init %s, expected %s\n", - static_cast(json_reader).GetPath().c_str(), + static_cast(json_reader).GetPath().c_str(), e.what()); return 1; } @@ -108,11 +108,13 @@ int main(int argc, char** argv) { sys::ChangeStdinToBinary(); sys::ChangeStdoutToBinary(); - // The thread that reads from stdin and dispatchs commands to the main thread. + // The thread that reads from stdin and dispatchs commands to the main + // thread. pipeline::LaunchStdin(); // The thread that writes responses from the main thread to stdout. pipeline::LaunchStdout(); - // Main thread which also spawns indexer threads upon the "initialize" request. + // Main thread which also spawns indexer threads upon the "initialize" + // request. pipeline::MainLoop(); } diff --git a/src/match.cc b/src/match.cc index 5dd467272..bec43beab 100644 --- a/src/match.cc +++ b/src/match.cc @@ -5,7 +5,7 @@ using namespace ccls; // static -std::optional Matcher::Create(const std::string& search) { +std::optional Matcher::Create(const std::string &search) { /* std::string real_search; real_search.reserve(search.size() * 3 + 2); @@ -19,51 +19,51 @@ std::optional Matcher::Create(const std::string& search) { try { Matcher m; m.regex_string = search; - m.regex = std::regex( - search, std::regex_constants::ECMAScript | std::regex_constants::icase | - std::regex_constants::optimize - // std::regex_constants::nosubs + m.regex = std::regex(search, std::regex_constants::ECMAScript | + std::regex_constants::icase | + std::regex_constants::optimize + // std::regex_constants::nosubs ); return m; - } catch (const std::exception& e) { + } catch (const std::exception &e) { Out_ShowLogMessage out; out.display_type = Out_ShowLogMessage::DisplayType::Show; out.params.type = lsMessageType::Error; - out.params.message = "ccls: Parsing EMCAScript regex \"" + search + - "\" failed; " + e.what(); + out.params.message = + "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); pipeline::WriteStdout(kMethodType_Unknown, out); return std::nullopt; } } -bool Matcher::IsMatch(const std::string& value) const { +bool Matcher::IsMatch(const std::string &value) const { // std::smatch match; // return std::regex_match(value, match, regex); return std::regex_search(value, regex, std::regex_constants::match_any); } -GroupMatch::GroupMatch(const std::vector& whitelist, - const std::vector& blacklist) { - for (const std::string& entry : whitelist) { +GroupMatch::GroupMatch(const std::vector &whitelist, + const std::vector &blacklist) { + for (const std::string &entry : whitelist) { std::optional m = Matcher::Create(entry); if (m) this->whitelist.push_back(*m); } - for (const std::string& entry : blacklist) { + for (const std::string &entry : blacklist) { std::optional m = Matcher::Create(entry); if (m) this->blacklist.push_back(*m); } } -bool GroupMatch::IsMatch(const std::string& value, - std::string* match_failure_reason) const { - for (const Matcher& m : whitelist) { +bool GroupMatch::IsMatch(const std::string &value, + std::string *match_failure_reason) const { + for (const Matcher &m : whitelist) { if (m.IsMatch(value)) return true; } - for (const Matcher& m : blacklist) { + for (const Matcher &m : blacklist) { if (m.IsMatch(value)) { if (match_failure_reason) *match_failure_reason = "blacklist \"" + m.regex_string + "\""; diff --git a/src/match.h b/src/match.h index 46b8610c1..134257a39 100644 --- a/src/match.h +++ b/src/match.h @@ -7,9 +7,9 @@ #include struct Matcher { - static std::optional Create(const std::string& search); + static std::optional Create(const std::string &search); - bool IsMatch(const std::string& value) const; + bool IsMatch(const std::string &value) const; std::string regex_string; std::regex regex; @@ -17,11 +17,11 @@ struct Matcher { // Check multiple |Matcher| instances at the same time. struct GroupMatch { - GroupMatch(const std::vector& whitelist, - const std::vector& blacklist); + GroupMatch(const std::vector &whitelist, + const std::vector &blacklist); - bool IsMatch(const std::string& value, - std::string* match_failure_reason = nullptr) const; + bool IsMatch(const std::string &value, + std::string *match_failure_reason = nullptr) const; std::vector whitelist; std::vector blacklist; diff --git a/src/maybe.h b/src/maybe.h index 328fc71ec..a24593765 100644 --- a/src/maybe.h +++ b/src/maybe.h @@ -4,29 +4,28 @@ #include -// Like std::optional, but the stored data is responsible for containing the empty -// state. T should define a function `bool T::Valid()`. -template -class Maybe { +// Like std::optional, but the stored data is responsible for containing the +// empty state. T should define a function `bool T::Valid()`. +template class Maybe { T storage; - public: +public: constexpr Maybe() = default; - Maybe(const Maybe&) = default; + Maybe(const Maybe &) = default; Maybe(std::nullopt_t) {} - Maybe(const T& x) : storage(x) {} - Maybe(T&& x) : storage(std::forward(x)) {} + Maybe(const T &x) : storage(x) {} + Maybe(T &&x) : storage(std::forward(x)) {} - Maybe& operator=(const Maybe&) = default; - Maybe& operator=(const T& x) { + Maybe &operator=(const Maybe &) = default; + Maybe &operator=(const T &x) { storage = x; 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; } + const T &operator*() const { return storage; } + T &operator*() { return storage; } bool Valid() const { return storage.Valid(); } explicit operator bool() const { return Valid(); } @@ -36,9 +35,9 @@ class Maybe { return std::nullopt; } - void operator=(std::optional&& o) { storage = o ? *o : T(); } + void operator=(std::optional &&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); } }; diff --git a/src/message_handler.cc b/src/message_handler.cc index a4be9c95b..2197ea075 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -337,15 +337,16 @@ void EmitSemanticHighlighting(DB *db, out.params.uri = lsDocumentUri::FromPath(wfile->filename); // Transform lsRange into pair (offset pairs) if (!g_config->highlight.lsRanges) { - std::vector> - scratch; + std::vector< + std::pair> + scratch; for (auto &entry : grouped_symbols) { for (auto &range : entry.second.lsRanges) scratch.emplace_back(range, &entry.second); entry.second.lsRanges.clear(); } std::sort(scratch.begin(), scratch.end(), - [](auto &l, auto &r) { return l.first.start < r.first.start; }); + [](auto &l, auto &r) { return l.first.start < r.first.start; }); const auto &buf = wfile->buffer_content; int l = 0, c = 0, i = 0, p = 0; auto mov = [&](int line, int col) { @@ -357,11 +358,13 @@ void EmitSemanticHighlighting(DB *db, if (uint8_t(buf[i]) < 128 || 192 <= uint8_t(buf[i])) p++; } - if (l < line) return true; + if (l < line) + return true; for (; c < col && i < buf.size() && buf[i] != '\n'; c++) if (p++, uint8_t(buf[i++]) >= 128) // Skip 0b10xxxxxx - while (i < buf.size() && uint8_t(buf[i]) >= 128 && uint8_t(buf[i]) < 192) + while (i < buf.size() && uint8_t(buf[i]) >= 128 && + uint8_t(buf[i]) < 192) i++; return c < col; }; diff --git a/src/message_handler.h b/src/message_handler.h index e4f79e78e..eb0f891dd 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -6,8 +6,8 @@ #include "method.h" #include "query.h" -#include #include +#include #include #include @@ -28,7 +28,7 @@ struct WorkingFiles; // relatively stable ids. Only supports xxx files at a time. struct SemanticHighlightSymbolCache { struct Entry { - SemanticHighlightSymbolCache* all_caches_ = nullptr; + SemanticHighlightSymbolCache *all_caches_ = nullptr; // The path this cache belongs to. std::string path; @@ -38,13 +38,13 @@ struct SemanticHighlightSymbolCache { TNameToId detailed_func_name_to_stable_id; TNameToId detailed_var_name_to_stable_id; - Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path); + Entry(SemanticHighlightSymbolCache *all_caches, const std::string &path); std::optional TryGetStableId(SymbolKind kind, - const std::string& detailed_name); - int GetStableId(SymbolKind kind, const std::string& detailed_name); + const std::string &detailed_name); + int GetStableId(SymbolKind kind, const std::string &detailed_name); - TNameToId* GetMapForSymbol_(SymbolKind kind); + TNameToId *GetMapForSymbol_(SymbolKind kind); }; constexpr static int kCacheSize = 10; @@ -54,7 +54,7 @@ struct SemanticHighlightSymbolCache { SemanticHighlightSymbolCache(); void Init(); - std::shared_ptr GetCacheForFile(const std::string& path); + std::shared_ptr GetCacheForFile(const std::string &path); }; struct Out_CclsPublishSemanticHighlighting @@ -79,9 +79,7 @@ struct Out_CclsPublishSemanticHighlighting MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId, parentKind, kind, storage, ranges, lsRanges); MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols); -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, - jsonrpc, - method, +MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, params); // Usage: @@ -94,54 +92,49 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, // Then there will be a global FooHandler instance in // |MessageHandler::message_handlers|. -#define REGISTER_MESSAGE_HANDLER(type) \ +#define REGISTER_MESSAGE_HANDLER(type) \ static type type##message_handler_instance_; struct MessageHandler { - DB* db = nullptr; - MultiQueueWaiter* waiter = nullptr; - Project* project = nullptr; - DiagnosticsPublisher* diag_pub = nullptr; - VFS* vfs = nullptr; - ImportManager* import_manager = nullptr; - SemanticHighlightSymbolCache* semantic_cache = nullptr; - WorkingFiles* working_files = nullptr; - ClangCompleteManager* clang_complete = nullptr; - IncludeComplete* include_complete = nullptr; - CodeCompleteCache* global_code_complete_cache = nullptr; - CodeCompleteCache* non_global_code_complete_cache = nullptr; - CodeCompleteCache* signature_cache = nullptr; + DB *db = nullptr; + MultiQueueWaiter *waiter = nullptr; + Project *project = nullptr; + DiagnosticsPublisher *diag_pub = nullptr; + VFS *vfs = nullptr; + ImportManager *import_manager = nullptr; + SemanticHighlightSymbolCache *semantic_cache = nullptr; + WorkingFiles *working_files = nullptr; + ClangCompleteManager *clang_complete = nullptr; + IncludeComplete *include_complete = nullptr; + CodeCompleteCache *global_code_complete_cache = nullptr; + CodeCompleteCache *non_global_code_complete_cache = nullptr; + CodeCompleteCache *signature_cache = nullptr; virtual MethodType GetMethodType() const = 0; virtual void Run(std::unique_ptr message) = 0; - static std::vector* message_handlers; + static std::vector *message_handlers; - protected: +protected: MessageHandler(); }; -template -struct BaseMessageHandler : MessageHandler { - virtual void Run(TMessage* message) = 0; +template struct BaseMessageHandler : MessageHandler { + virtual void Run(TMessage *message) = 0; // MessageHandler: void Run(std::unique_ptr message) override { - Run(static_cast(message.get())); + Run(static_cast(message.get())); } }; -bool FindFileOrFail(DB* db, - Project* project, - std::optional id, - const std::string& absolute_path, - QueryFile** out_query_file, - int* out_file_id = nullptr); +bool FindFileOrFail(DB *db, Project *project, std::optional id, + const std::string &absolute_path, + QueryFile **out_query_file, int *out_file_id = nullptr); void EmitSkippedRanges(WorkingFile *working_file, const std::vector &skipped_ranges); -void EmitSemanticHighlighting(DB* db, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFile* working_file, - QueryFile* file); +void EmitSemanticHighlighting(DB *db, + SemanticHighlightSymbolCache *semantic_cache, + WorkingFile *working_file, QueryFile *file); diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index dc29162bc..aa079d3dd 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -18,14 +18,14 @@ REGISTER_IN_MESSAGE(In_CclsBase); struct Handler_CclsBase : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsBase* request) override { - QueryFile* file; + void Run(In_CclsBase *request) override { + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_LocationList out; @@ -33,12 +33,12 @@ struct Handler_CclsBase : BaseMessageHandler { for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { - if (const auto* def = db->GetType(sym).AnyDef()) + if (const auto *def = db->GetType(sym).AnyDef()) out.result = GetLsLocationExs(db, working_files, GetTypeDeclarations(db, def->bases)); break; } else if (sym.kind == SymbolKind::Func) { - if (const auto* def = db->GetFunc(sym).AnyDef()) + if (const auto *def = db->GetFunc(sym).AnyDef()) out.result = GetLsLocationExs(db, working_files, GetFuncDeclarations(db, def->bases)); break; @@ -48,4 +48,4 @@ struct Handler_CclsBase : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_CclsBase); -} // namespace +} // namespace diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_callHierarchy.cc index 97b753dd4..0ec1fbda7 100644 --- a/src/messages/ccls_callHierarchy.cc +++ b/src/messages/ccls_callHierarchy.cc @@ -44,16 +44,9 @@ struct In_CclsCallHierarchy : public RequestInMessage { int levels = 1; }; Params params; - }; -MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, - textDocument, - position, - id, - callee, - callType, - qualified, - levels); +MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id, + callee, callType, qualified, levels); MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsCallHierarchy); @@ -72,26 +65,15 @@ struct Out_CclsCallHierarchy : public lsOutMessage { lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, - id, - name, - location, - callType, - numChildren, - children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, - jsonrpc, - id, +MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType, + numChildren, children); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, jsonrpc, id, result); -bool Expand(MessageHandler* m, - Out_CclsCallHierarchy::Entry* entry, - bool callee, - CallType call_type, - bool qualified, - int levels) { - const QueryFunc& func = m->db->Func(entry->usr); - const QueryFunc::Def* def = func.AnyDef(); +bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee, + CallType call_type, bool qualified, int levels) { + const QueryFunc &func = m->db->Func(entry->usr); + const QueryFunc::Def *def = func.AnyDef(); entry->numChildren = 0; if (!def) return false; @@ -108,13 +90,12 @@ bool Expand(MessageHandler* m, entry->children.push_back(std::move(entry1)); } }; - auto handle_uses = [&](const QueryFunc& func, CallType call_type) { + auto handle_uses = [&](const QueryFunc &func, CallType call_type) { if (callee) { - if (const auto* def = func.AnyDef()) + if (const auto *def = func.AnyDef()) for (SymbolRef ref : def->callees) if (ref.kind == SymbolKind::Func) - handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, - def->file_id}, + handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id}, call_type); } else { for (Use use : func.uses) @@ -125,7 +106,7 @@ bool Expand(MessageHandler* m, std::unordered_set seen; seen.insert(func.usr); - std::vector stack; + std::vector stack; entry->name = def->Name(qualified); handle_uses(func, CallType::Direct); @@ -133,10 +114,10 @@ bool Expand(MessageHandler* m, if (call_type & CallType::Base) { stack.push_back(&func); while (stack.size()) { - const QueryFunc& func1 = *stack.back(); + const QueryFunc &func1 = *stack.back(); stack.pop_back(); - if (auto* def1 = func1.AnyDef()) { - EachDefinedFunc(m->db, def1->bases, [&](QueryFunc& func2) { + if (auto *def1 = func1.AnyDef()) { + EachDefinedFunc(m->db, def1->bases, [&](QueryFunc &func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -151,9 +132,9 @@ bool Expand(MessageHandler* m, if (call_type & CallType::Derived) { stack.push_back(&func); while (stack.size()) { - const QueryFunc& func1 = *stack.back(); + const QueryFunc &func1 = *stack.back(); stack.pop_back(); - EachDefinedFunc(m->db, func1.derived, [&](QueryFunc& func2) { + EachDefinedFunc(m->db, func1.derived, [&](QueryFunc &func2) { if (!seen.count(func2.usr)) { seen.insert(func2.usr); stack.push_back(&func2); @@ -165,16 +146,13 @@ bool Expand(MessageHandler* m, return true; } -struct Handler_CclsCallHierarchy - : BaseMessageHandler { +struct Handler_CclsCallHierarchy : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional BuildInitial(Usr root_usr, - bool callee, - CallType call_type, - bool qualified, - int levels) { - const auto* def = db->Func(root_usr).AnyDef(); + std::optional + BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified, + int levels) { + const auto *def = db->Func(root_usr).AnyDef(); if (!def) return {}; @@ -191,8 +169,8 @@ struct Handler_CclsCallHierarchy return entry; } - void Run(In_CclsCallHierarchy* request) override { - auto& params = request->params; + void Run(In_CclsCallHierarchy *request) override { + auto ¶ms = request->params; Out_CclsCallHierarchy out; out.id = request->id; @@ -211,11 +189,11 @@ struct Handler_CclsCallHierarchy params.levels); out.result = std::move(entry); } else { - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, params.position)) { @@ -232,4 +210,4 @@ struct Handler_CclsCallHierarchy }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); -} // namespace +} // namespace diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc index 4325d3b7c..c5d8d7eeb 100644 --- a/src/messages/ccls_callers.cc +++ b/src/messages/ccls_callers.cc @@ -15,14 +15,14 @@ REGISTER_IN_MESSAGE(In_CclsCallers); struct Handler_CclsCallers : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsCallers* request) override { - QueryFile* file; + void Run(In_CclsCallers *request) override { + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_LocationList out; @@ -30,7 +30,7 @@ struct Handler_CclsCallers : BaseMessageHandler { for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Func) { - QueryFunc& func = db->GetFunc(sym); + QueryFunc &func = db->GetFunc(sym); std::vector uses = func.uses; for (Use func_ref : GetUsesForAllBases(db, func)) uses.push_back(func_ref); @@ -44,4 +44,4 @@ struct Handler_CclsCallers : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallers); -} // namespace +} // namespace diff --git a/src/messages/ccls_fileInfo.cc b/src/messages/ccls_fileInfo.cc index 3c1a0fc59..e5795ff48 100644 --- a/src/messages/ccls_fileInfo.cc +++ b/src/messages/ccls_fileInfo.cc @@ -3,14 +3,8 @@ #include "query_utils.h" using namespace ccls; -MAKE_REFLECT_STRUCT(QueryFile::Def, - path, - args, - language, - outline, - all_symbols, - skipped_ranges, - dependencies); +MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, outline, all_symbols, + skipped_ranges, dependencies); namespace { MethodType kMethodType = "$ccls/fileInfo"; @@ -35,8 +29,8 @@ MAKE_REFLECT_STRUCT(Out_CclsFileInfo, jsonrpc, id, result); struct Handler_CclsFileInfo : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsFileInfo* request) override { - QueryFile* file; + void Run(In_CclsFileInfo *request) override { + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; @@ -54,4 +48,4 @@ struct Handler_CclsFileInfo : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFileInfo); -} // namespace +} // namespace diff --git a/src/messages/ccls_freshenIndex.cc b/src/messages/ccls_freshenIndex.cc index 1773b612b..c538270b7 100644 --- a/src/messages/ccls_freshenIndex.cc +++ b/src/messages/ccls_freshenIndex.cc @@ -1,8 +1,8 @@ #include "match.h" #include "message_handler.h" +#include "pipeline.hh" #include "platform.h" #include "project.h" -#include "pipeline.hh" #include "working_files.h" using namespace ccls; @@ -21,38 +21,36 @@ struct In_CclsFreshenIndex : public NotificationInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, - dependencies, - whitelist, +MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, dependencies, whitelist, blacklist); MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params); REGISTER_IN_MESSAGE(In_CclsFreshenIndex); struct Handler_CclsFreshenIndex : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsFreshenIndex* request) override { + void Run(In_CclsFreshenIndex *request) override { GroupMatch matcher(request->params.whitelist, request->params.blacklist); - std::queue q; + std::queue q; // |need_index| stores every filename ever enqueued. std::unordered_set need_index; // Reverse dependency graph. std::unordered_map> graph; // filename -> QueryFile mapping for files haven't enqueued. - std::unordered_map path_to_file; + std::unordered_map path_to_file; - for (const auto& file : db->files) + for (const auto &file : db->files) if (file.def) { if (matcher.IsMatch(file.def->path)) q.push(&file); else path_to_file[file.def->path] = &file; - for (const std::string& dependency : file.def->dependencies) + for (const std::string &dependency : file.def->dependencies) graph[dependency].push_back(file.def->path); } while (!q.empty()) { - const QueryFile* file = q.front(); + const QueryFile *file = q.front(); q.pop(); need_index.insert(file->def->path); @@ -61,13 +59,13 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { continue; { std::lock_guard lock(vfs->mutex); - VFS::State& st = vfs->state[file->def->path]; + VFS::State &st = vfs->state[file->def->path]; if (st.timestamp < write_time) st.stage = 0; } if (request->params.dependencies) - for (const std::string& path : graph[file->def->path]) { + for (const std::string &path : graph[file->def->path]) { auto it = path_to_file.find(path); if (it != path_to_file.end()) { q.push(it->second); @@ -81,4 +79,4 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); -} // namespace +} // namespace diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index f21d7de7d..0246ee845 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -51,32 +51,18 @@ struct Out_CclsInheritanceHierarchy lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, - id, - kind, - name, - location, - numChildren, - children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, - jsonrpc, - id, - result); - -bool Expand(MessageHandler* m, - Out_CclsInheritanceHierarchy::Entry* entry, - bool derived, - bool qualified, - int levels); +MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name, + location, numChildren, children); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, jsonrpc, + id, result); + +bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, + bool derived, bool qualified, int levels); template -bool ExpandHelper(MessageHandler* m, - Out_CclsInheritanceHierarchy::Entry* entry, - bool derived, - bool qualified, - int levels, - Q& entity) { - const auto* def = entity.AnyDef(); +bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, + bool derived, bool qualified, int levels, Q &entity) { + const auto *def = entity.AnyDef(); if (def) { entry->name = def->Name(qualified); if (def->spell) { @@ -122,11 +108,8 @@ bool ExpandHelper(MessageHandler* m, return true; } -bool Expand(MessageHandler* m, - Out_CclsInheritanceHierarchy::Entry* entry, - bool derived, - bool qualified, - int levels) { +bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, + bool derived, bool qualified, int levels) { if (entry->kind == SymbolKind::Func) return ExpandHelper(m, entry, derived, qualified, levels, m->db->Func(entry->usr)); @@ -149,8 +132,8 @@ struct Handler_CclsInheritanceHierarchy return entry; } - void Run(In_CclsInheritanceHierarchy* request) override { - auto& params = request->params; + void Run(In_CclsInheritanceHierarchy *request) override { + auto ¶ms = request->params; Out_CclsInheritanceHierarchy out; out.id = request->id; @@ -169,12 +152,11 @@ struct Handler_CclsInheritanceHierarchy Expand(this, &entry, params.derived, params.qualified, params.levels)) out.result = std::move(entry); } else { - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* wfile = - working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { @@ -208,4 +190,4 @@ struct Handler_CclsInheritanceHierarchy }; REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); -} // namespace +} // namespace diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index 03cfcca3e..cf2e7455f 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -30,17 +30,12 @@ struct In_CclsMemberHierarchy : public RequestInMessage { Params params; }; -MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, - textDocument, - position, - id, - qualified, - levels); +MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, + qualified, levels); MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); -struct Out_CclsMemberHierarchy - : public lsOutMessage { +struct Out_CclsMemberHierarchy : public lsOutMessage { struct Entry { Usr usr; std::string id; @@ -56,31 +51,18 @@ struct Out_CclsMemberHierarchy lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, - id, - name, - fieldName, - location, - numChildren, - children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, - jsonrpc, - id, +MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName, + location, numChildren, children); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, jsonrpc, id, result); -bool Expand(MessageHandler* m, - Out_CclsMemberHierarchy::Entry* entry, - bool qualified, - int levels); +bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, + bool qualified, int levels); // Add a field to |entry| which is a Func/Type. -void DoField(MessageHandler* m, - Out_CclsMemberHierarchy::Entry* entry, - const QueryVar& var, - int64_t offset, - bool qualified, - int levels) { - const QueryVar::Def* def1 = var.AnyDef(); +void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, + const QueryVar &var, int64_t offset, bool qualified, int levels) { + const QueryVar::Def *def1 = var.AnyDef(); if (!def1) return; Out_CclsMemberHierarchy::Entry entry1; @@ -120,37 +102,35 @@ void DoField(MessageHandler* m, } // Expand a type node by adding members recursively to it. -bool Expand(MessageHandler* m, - Out_CclsMemberHierarchy::Entry* entry, - bool qualified, - int levels) { +bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, + bool qualified, int levels) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(int(entry->usr)); return true; } - const QueryType& type = m->db->Type(entry->usr); - const QueryType::Def* def = type.AnyDef(); + const QueryType &type = m->db->Type(entry->usr); + const QueryType::Def *def = type.AnyDef(); // builtin types have no declaration and empty |qualified|. if (!def) return false; entry->name = def->Name(qualified); std::unordered_set seen; if (levels > 0) { - std::vector stack; + std::vector stack; seen.insert(type.usr); stack.push_back(&type); while (stack.size()) { - const auto* def = stack.back()->AnyDef(); + const auto *def = stack.back()->AnyDef(); stack.pop_back(); if (def) { - EachDefinedType(m->db, def->bases, [&](QueryType& type1) { + EachDefinedType(m->db, def->bases, [&](QueryType &type1) { if (!seen.count(type1.usr)) { seen.insert(type1.usr); stack.push_back(&type1); } }); if (def->alias_of) { - const QueryType::Def* def1 = m->db->Type(def->alias_of).AnyDef(); + const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); Out_CclsMemberHierarchy::Entry entry1; entry1.id = std::to_string(def->alias_of); entry1.usr = def->alias_of; @@ -176,7 +156,7 @@ bool Expand(MessageHandler* m, } } else { for (auto it : def->vars) { - QueryVar& var = m->db->Var(it.first); + QueryVar &var = m->db->Var(it.first); if (!var.def.empty()) DoField(m, entry, var, it.second, qualified, levels - 1); } @@ -193,15 +173,13 @@ struct Handler_CclsMemberHierarchy : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional BuildInitial(SymbolKind kind, - Usr root_usr, - bool qualified, - int levels) { + std::optional + BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) { switch (kind) { default: return {}; case SymbolKind::Func: { - const auto* def = db->Func(root_usr).AnyDef(); + const auto *def = db->Func(root_usr).AnyDef(); if (!def) return {}; @@ -210,16 +188,16 @@ struct Handler_CclsMemberHierarchy entry.name = def->Name(qualified); if (def->spell) { if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) + GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - EachDefinedVar(db, def->vars, [&](QueryVar& var) { - DoField(this, &entry, var, -1, qualified, levels - 1); - }); + EachDefinedVar(db, def->vars, [&](QueryVar &var) { + DoField(this, &entry, var, -1, qualified, levels - 1); + }); return entry; } case SymbolKind::Type: { - const auto* def = db->Type(root_usr).AnyDef(); + const auto *def = db->Type(root_usr).AnyDef(); if (!def) return {}; @@ -228,7 +206,7 @@ struct Handler_CclsMemberHierarchy entry.usr = root_usr; if (def->spell) { if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) + GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } Expand(this, &entry, qualified, levels); @@ -237,8 +215,8 @@ struct Handler_CclsMemberHierarchy } } - void Run(In_CclsMemberHierarchy* request) override { - auto& params = request->params; + void Run(In_CclsMemberHierarchy *request) override { + auto ¶ms = request->params; Out_CclsMemberHierarchy out; out.id = request->id; @@ -256,29 +234,28 @@ struct Handler_CclsMemberHierarchy Expand(this, &entry, params.qualified, params.levels)) out.result = std::move(entry); } else { - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* wfile = - working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { switch (sym.kind) { - case SymbolKind::Func: - case SymbolKind::Type: - out.result = BuildInitial(sym.kind, sym.usr, params.qualified, - params.levels); - break; - case SymbolKind::Var: { - const QueryVar::Def* def = db->GetVar(sym).AnyDef(); - if (def && def->type) - out.result = BuildInitial(SymbolKind::Type, def->type, - params.qualified, params.levels); - break; - } - default: - continue; + case SymbolKind::Func: + case SymbolKind::Type: + out.result = + BuildInitial(sym.kind, sym.usr, params.qualified, params.levels); + break; + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (def && def->type) + out.result = BuildInitial(SymbolKind::Type, def->type, + params.qualified, params.levels); + break; + } + default: + continue; } break; } @@ -289,4 +266,4 @@ struct Handler_CclsMemberHierarchy }; REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); -} // namespace +} // namespace diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 706168453..69cde5c6e 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -1,6 +1,6 @@ #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; namespace { @@ -15,24 +15,21 @@ struct In_CclsVars : public RequestInMessage { unsigned kind = ~0u; } params; }; -MAKE_REFLECT_STRUCT(In_CclsVars::Params, - textDocument, - position, - kind); +MAKE_REFLECT_STRUCT(In_CclsVars::Params, textDocument, position, kind); MAKE_REFLECT_STRUCT(In_CclsVars, id, params); REGISTER_IN_MESSAGE(In_CclsVars); struct Handler_CclsVars : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsVars* request) override { - auto& params = request->params; - QueryFile* file; + void Run(In_CclsVars *request) override { + auto ¶ms = request->params; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_LocationList out; @@ -41,24 +38,24 @@ struct Handler_CclsVars : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, params.position)) { Usr usr = sym.usr; switch (sym.kind) { - default: - break; - case SymbolKind::Var: { - const QueryVar::Def* def = db->GetVar(sym).AnyDef(); - if (!def || !def->type) - continue; - usr = def->type; - [[fallthrough]]; - } - case SymbolKind::Type: - out.result = GetLsLocationExs( - db, working_files, - GetVarDeclarations(db, db->Type(usr).instances, params.kind)); - break; + default: + break; + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (!def || !def->type) + continue; + usr = def->type; + [[fallthrough]]; + } + case SymbolKind::Type: + out.result = GetLsLocationExs( + db, working_files, + GetVarDeclarations(db, db->Type(usr).instances, params.kind)); + break; } } pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsVars); -} // namespace +} // namespace diff --git a/src/messages/exit.cc b/src/messages/exit.cc index edf0c4ffc..2ba8da5df 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -10,9 +10,7 @@ REGISTER_IN_MESSAGE(In_Exit); struct Handler_Exit : MessageHandler { MethodType GetMethodType() const override { return kMethodType_Exit; } - void Run(std::unique_ptr request) override { - exit(0); - } + void Run(std::unique_ptr request) override { exit(0); } }; REGISTER_MESSAGE_HANDLER(Handler_Exit); -} // namespace +} // namespace diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index ac7a03892..01995f0b6 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -55,8 +55,7 @@ struct lsDocumentOnTypeFormattingOptions { // More trigger characters. std::vector moreTriggerCharacter; }; -MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, - firstTriggerCharacter, +MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); // Document link options @@ -119,12 +118,8 @@ struct lsTextDocumentSyncOptions { // Save notifications are sent to the server. std::optional save; }; -MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, - openClose, - change, - willSave, - willSaveWaitUntil, - save); +MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave, + willSaveWaitUntil, save); struct lsServerCapabilities { // Defines how text documents are synced. Is either a detailed structure @@ -161,7 +156,8 @@ struct lsServerCapabilities { // The server provides document range formatting. bool documentRangeFormattingProvider = false; // The server provides document formatting on typing. - std::optional documentOnTypeFormattingProvider; + std::optional + documentOnTypeFormattingProvider; // The server provides rename support. bool renameProvider = true; // The server provides document link support. @@ -169,25 +165,15 @@ struct lsServerCapabilities { // The server provides execute command support. lsExecuteCommandOptions executeCommandProvider; }; -MAKE_REFLECT_STRUCT(lsServerCapabilities, - textDocumentSync, - hoverProvider, - completionProvider, - signatureHelpProvider, - definitionProvider, - typeDefinitionProvider, - referencesProvider, - documentHighlightProvider, - documentSymbolProvider, - workspaceSymbolProvider, - codeActionProvider, - codeLensProvider, - documentFormattingProvider, - documentRangeFormattingProvider, - documentOnTypeFormattingProvider, - renameProvider, - documentLinkProvider, - executeCommandProvider); +MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, + completionProvider, signatureHelpProvider, + definitionProvider, typeDefinitionProvider, + referencesProvider, documentHighlightProvider, + documentSymbolProvider, workspaceSymbolProvider, + codeActionProvider, codeLensProvider, + documentFormattingProvider, documentRangeFormattingProvider, + documentOnTypeFormattingProvider, renameProvider, + documentLinkProvider, executeCommandProvider); // Workspace specific client capabilities. struct lsWorkspaceClientCapabilites { @@ -226,12 +212,8 @@ MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit, documentChanges); MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg, dynamicRegistration); -MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, - applyEdit, - workspaceEdit, - didChangeConfiguration, - didChangeWatchedFiles, - symbol, +MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, applyEdit, workspaceEdit, + didChangeConfiguration, didChangeWatchedFiles, symbol, executeCommand); // Text document specific client capabilities. @@ -287,13 +269,9 @@ struct lsTextDocumentClientCapabilities { }; MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, - dynamicRegistration, - willSave, - willSaveWaitUntil, - didSave); + dynamicRegistration, willSave, willSaveWaitUntil, didSave); MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion, - dynamicRegistration, - completionItem); + dynamicRegistration, completionItem); MAKE_REFLECT_STRUCT( lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem, snippetSupport); @@ -301,12 +279,9 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg, dynamicRegistration); MAKE_REFLECT_STRUCT( lsTextDocumentClientCapabilities::CodeLensRegistrationOptions, - dynamicRegistration, - resolveProvider); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, - synchronization, - completion, - rename); + dynamicRegistration, resolveProvider); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, synchronization, + completion, rename); struct lsClientCapabilities { // Workspace specific client capabilities. @@ -343,16 +318,16 @@ struct lsInitializeParams { enum class lsTrace { // NOTE: serialized as a string, one of 'off' | 'messages' | 'verbose'; - Off, // off - Messages, // messages - Verbose // verbose + Off, // off + Messages, // messages + Verbose // verbose }; // The initial trace setting. If omitted trace is disabled ('off'). lsTrace trace = lsTrace::Off; }; -void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) { +void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { if (!reader.IsString()) { value = lsInitializeParams::lsTrace::Off; return; @@ -366,7 +341,7 @@ void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) { value = lsInitializeParams::lsTrace::Verbose; } -#if 0 // unused +#if 0 // unused void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) { switch (value) { case lsInitializeParams::lsTrace::Off: @@ -382,13 +357,8 @@ void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) { } #endif -MAKE_REFLECT_STRUCT(lsInitializeParams, - processId, - rootPath, - rootUri, - initializationOptions, - capabilities, - trace); +MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, + initializationOptions, capabilities, trace); struct lsInitializeError { // Indicates whether the client should retry to send the @@ -419,8 +389,8 @@ MAKE_REFLECT_STRUCT(Out_InitializeResponse, jsonrpc, id, result); struct Handler_Initialize : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_InitializeRequest* request) override { - auto& params = request->params; + void Run(In_InitializeRequest *request) override { + auto ¶ms = request->params; if (!params.rootUri) return; std::string project_path = NormalizePath(params.rootUri->GetPath()); @@ -438,7 +408,7 @@ struct Handler_Initialize : BaseMessageHandler { JsonReader json_reader{&reader}; try { Reflect(json_reader, *g_config); - } catch (std::invalid_argument&) { + } catch (std::invalid_argument &) { // This will not trigger because parse error is handled in // MessageRegistry::Parse in lsp.cc } @@ -460,7 +430,7 @@ struct Handler_Initialize : BaseMessageHandler { } // Client capabilities - const auto& capabilities = params.capabilities; + const auto &capabilities = params.capabilities; g_config->client.snippetSupport = capabilities.textDocument.completion.completionItem.snippetSupport; @@ -508,7 +478,8 @@ struct Handler_Initialize : BaseMessageHandler { std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); pipeline::Indexer_Main(diag_pub, vfs, project, working_files); - }).detach(); + }) + .detach(); } // Start scanning include directories before dispatching project @@ -520,4 +491,4 @@ struct Handler_Initialize : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_Initialize); -} // namespace +} // namespace diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index e06c72811..07368344b 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -19,11 +19,11 @@ MAKE_REFLECT_STRUCT(Out_Shutdown, jsonrpc, id, result); struct Handler_Shutdown : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_Shutdown* request) override { + void Run(In_Shutdown *request) override { Out_Shutdown out; out.id = request->id; pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_Shutdown); -} // namespace +} // namespace diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc index 2832cfca0..c07336f8d 100644 --- a/src/messages/textDocument_codeAction.cc +++ b/src/messages/textDocument_codeAction.cc @@ -33,10 +33,8 @@ struct In_TextDocumentCodeAction : public RequestInMessage { }; MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, diagnostics); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, - textDocument, - range, - context); +MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument, + range, context); MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); @@ -51,7 +49,7 @@ struct Handler_TextDocumentCodeAction : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentCodeAction* request) override { + void Run(In_TextDocumentCodeAction *request) override { const auto ¶ms = request->params; WorkingFile *wfile = working_files->GetFileByFilename(params.textDocument.uri.GetPath()); @@ -74,4 +72,4 @@ struct Handler_TextDocumentCodeAction } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); -} +} // namespace diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index bd6704fd7..a9bed9c81 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -1,8 +1,8 @@ #include "clang_complete.h" #include "lsp_code_action.h" #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; namespace { @@ -30,10 +30,10 @@ struct Out_TextDocumentCodeLens MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result); struct CommonCodeLensParams { - std::vector* result; - DB* db; - WorkingFiles* working_files; - WorkingFile* working_file; + std::vector *result; + DB *db; + WorkingFiles *working_files; + WorkingFile *working_file; }; Use OffsetStartColumn(Use use, int16_t offset) { @@ -41,12 +41,9 @@ Use OffsetStartColumn(Use use, int16_t offset) { return use; } -void AddCodeLens(const char* singular, - const char* plural, - CommonCodeLensParams* common, - Use use, - const std::vector& uses, - bool force_display) { +void AddCodeLens(const char *singular, const char *plural, + CommonCodeLensParams *common, Use use, + const std::vector &uses, bool force_display) { TCodeLens code_lens; std::optional range = GetLsRange(common->working_file, use.range); if (!range) @@ -83,7 +80,7 @@ void AddCodeLens(const char* singular, struct Handler_TextDocumentCodeLens : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentCodeLens* request) override { + void Run(In_TextDocumentCodeLens *request) override { Out_TextDocumentCodeLens out; out.id = request->id; @@ -92,7 +89,7 @@ struct Handler_TextDocumentCodeLens clang_complete->NotifyView(path); - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; @@ -110,119 +107,118 @@ struct Handler_TextDocumentCodeLens Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id}; switch (sym.kind) { - case SymbolKind::Type: { - QueryType& type = db->GetType(sym); - const QueryType::Def* def = type.AnyDef(); - if (!def || def->kind == lsSymbolKind::Namespace) - continue; - AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), - type.uses, true /*force_display*/); - AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), - GetTypeDeclarations(db, type.derived), - false /*force_display*/); - AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetVarDeclarations(db, type.instances, true), - false /*force_display*/); - break; - } - case SymbolKind::Func: { - QueryFunc& func = db->GetFunc(sym); - const QueryFunc::Def* def = func.AnyDef(); - if (!def) - continue; - - int16_t offset = 0; - - // For functions, the outline will report a location that is using the - // extent since that is better for outline. This tries to convert the - // extent location to the spelling location. - auto try_ensure_spelling = [&](Use use) { - Maybe def = GetDefinitionSpell(db, use); - if (!def || def->range.start.line != use.range.start.line) { - return use; - } - return *def; - }; - - std::vector base_callers = GetUsesForAllBases(db, func); - std::vector derived_callers = GetUsesForAllDerived(db, func); - if (base_callers.empty() && derived_callers.empty()) { - Use loc = try_ensure_spelling(use); - AddCodeLens("call", "calls", &common, - OffsetStartColumn(loc, offset++), func.uses, - true /*force_display*/); - } else { - Use loc = try_ensure_spelling(use); - AddCodeLens("direct call", "direct calls", &common, - OffsetStartColumn(loc, offset++), func.uses, - false /*force_display*/); - if (!base_callers.empty()) - AddCodeLens("base call", "base calls", &common, - OffsetStartColumn(loc, offset++), base_callers, - false /*force_display*/); - if (!derived_callers.empty()) - AddCodeLens("derived call", "derived calls", &common, - OffsetStartColumn(loc, offset++), derived_callers, - false /*force_display*/); + case SymbolKind::Type: { + QueryType &type = db->GetType(sym); + const QueryType::Def *def = type.AnyDef(); + if (!def || def->kind == lsSymbolKind::Namespace) + continue; + AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), + type.uses, true /*force_display*/); + AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), + GetTypeDeclarations(db, type.derived), + false /*force_display*/); + AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), + GetVarDeclarations(db, type.instances, true), + false /*force_display*/); + break; + } + case SymbolKind::Func: { + QueryFunc &func = db->GetFunc(sym); + const QueryFunc::Def *def = func.AnyDef(); + if (!def) + continue; + + int16_t offset = 0; + + // For functions, the outline will report a location that is using the + // extent since that is better for outline. This tries to convert the + // extent location to the spelling location. + auto try_ensure_spelling = [&](Use use) { + Maybe def = GetDefinitionSpell(db, use); + if (!def || def->range.start.line != use.range.start.line) { + return use; } - - AddCodeLens("derived", "derived", &common, - OffsetStartColumn(use, offset++), - GetFuncDeclarations(db, func.derived), + return *def; + }; + + std::vector base_callers = GetUsesForAllBases(db, func); + std::vector derived_callers = GetUsesForAllDerived(db, func); + if (base_callers.empty() && derived_callers.empty()) { + Use loc = try_ensure_spelling(use); + AddCodeLens("call", "calls", &common, + OffsetStartColumn(loc, offset++), func.uses, + true /*force_display*/); + } else { + Use loc = try_ensure_spelling(use); + AddCodeLens("direct call", "direct calls", &common, + OffsetStartColumn(loc, offset++), func.uses, false /*force_display*/); + if (!base_callers.empty()) + AddCodeLens("base call", "base calls", &common, + OffsetStartColumn(loc, offset++), base_callers, + false /*force_display*/); + if (!derived_callers.empty()) + AddCodeLens("derived call", "derived calls", &common, + OffsetStartColumn(loc, offset++), derived_callers, + false /*force_display*/); + } - // "Base" - if (def->bases.size() == 1) { - Maybe base_loc = GetDefinitionSpell( - db, SymbolIdx{def->bases[0], SymbolKind::Func}); - if (base_loc) { - std::optional ls_base = - GetLsLocation(db, working_files, *base_loc); - if (ls_base) { - std::optional range = - GetLsRange(common.working_file, sym.range); - if (range) { - TCodeLens code_lens; - code_lens.range = *range; - code_lens.range.start.character += offset++; - code_lens.command = lsCommand(); - code_lens.command->title = "Base"; - code_lens.command->command = "ccls.goto"; - code_lens.command->arguments.uri = ls_base->uri; - code_lens.command->arguments.position = ls_base->range.start; - out.result.push_back(code_lens); - } + AddCodeLens( + "derived", "derived", &common, OffsetStartColumn(use, offset++), + GetFuncDeclarations(db, func.derived), false /*force_display*/); + + // "Base" + if (def->bases.size() == 1) { + Maybe base_loc = GetDefinitionSpell( + db, SymbolIdx{def->bases[0], SymbolKind::Func}); + if (base_loc) { + std::optional ls_base = + GetLsLocation(db, working_files, *base_loc); + if (ls_base) { + std::optional range = + GetLsRange(common.working_file, sym.range); + if (range) { + TCodeLens code_lens; + code_lens.range = *range; + code_lens.range.start.character += offset++; + code_lens.command = lsCommand(); + code_lens.command->title = "Base"; + code_lens.command->command = "ccls.goto"; + code_lens.command->arguments.uri = ls_base->uri; + code_lens.command->arguments.position = ls_base->range.start; + out.result.push_back(code_lens); } } - } else { - AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), - GetTypeDeclarations(db, def->bases), - false /*force_display*/); } - - break; - } - case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - const QueryVar::Def* def = var.AnyDef(); - if (!def || (def->is_local() && !g_config->codeLens.localVariables)) - continue; - - bool force_display = true; - // Do not show 0 refs on macro with no uses, as it is most likely - // a header guard. - if (def->kind == lsSymbolKind::Macro) - force_display = false; - - AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), - var.uses, force_display); - break; - } - case SymbolKind::File: - case SymbolKind::Invalid: { - assert(false && "unexpected"); - break; + } else { + AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), + GetTypeDeclarations(db, def->bases), + false /*force_display*/); } + + break; + } + case SymbolKind::Var: { + QueryVar &var = db->GetVar(sym); + const QueryVar::Def *def = var.AnyDef(); + if (!def || (def->is_local() && !g_config->codeLens.localVariables)) + continue; + + bool force_display = true; + // Do not show 0 refs on macro with no uses, as it is most likely + // a header guard. + if (def->kind == lsSymbolKind::Macro) + force_display = false; + + AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), var.uses, + force_display); + break; + } + case SymbolKind::File: + case SymbolKind::Invalid: { + assert(false && "unexpected"); + break; + } }; } @@ -230,4 +226,4 @@ struct Handler_TextDocumentCodeLens } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); -} // namespace +} // namespace diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 200935392..a2b1cc9dc 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -70,8 +70,8 @@ struct Out_TextDocumentComplete }; MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result); -void DecorateIncludePaths(const std::smatch& match, - std::vector* items) { +void DecorateIncludePaths(const std::smatch &match, + std::vector *items) { std::string spaces_after_include = " "; if (match[3].compare("include") == 0 && match[5].length()) spaces_after_include = match[4].str(); @@ -80,7 +80,7 @@ void DecorateIncludePaths(const std::smatch& match, match[1].str() + '#' + match[2].str() + "include" + spaces_after_include; std::string suffix = match[7].str(); - for (lsCompletionItem& item : *items) { + for (lsCompletionItem &item : *items) { char quote0, quote1; if (match[5].compare("<") == 0 || (match[5].length() == 0 && item.use_angle_brackets_)) @@ -103,17 +103,16 @@ struct ParseIncludeLineResult { std::smatch match; }; -ParseIncludeLineResult ParseIncludeLine(const std::string& line) { - static const std::regex pattern( - "(\\s*)" // [1]: spaces before '#' - "#" // - "(\\s*)" // [2]: spaces after '#' - "([^\\s\"<]*)" // [3]: "include" - "(\\s*)" // [4]: spaces before quote - "([\"<])?" // [5]: the first quote char - "([^\\s\">]*)" // [6]: path of file - "[\">]?" // - "(.*)"); // [7]: suffix after quote char +ParseIncludeLineResult ParseIncludeLine(const std::string &line) { + static const std::regex pattern("(\\s*)" // [1]: spaces before '#' + "#" // + "(\\s*)" // [2]: spaces after '#' + "([^\\s\"<]*)" // [3]: "include" + "(\\s*)" // [4]: spaces before quote + "([\"<])?" // [5]: the first quote char + "([^\\s\">]*)" // [6]: path of file + "[\">]?" // + "(.*)"); // [7]: suffix after quote char std::smatch match; bool ok = std::regex_match(line, match, pattern); return {ok, match[3], match[5], match[6], match}; @@ -123,10 +122,10 @@ static const std::vector preprocessorKeywords = { "define", "undef", "include", "if", "ifdef", "ifndef", "else", "elif", "endif", "line", "error", "pragma"}; -std::vector PreprocessorKeywordCompletionItems( - const std::smatch& match) { +std::vector +PreprocessorKeywordCompletionItems(const std::smatch &match) { std::vector items; - for (auto& keyword : preprocessorKeywords) { + for (auto &keyword : preprocessorKeywords) { lsCompletionItem item; item.label = keyword; item.priority_ = (keyword == "include" ? 2 : 1); @@ -140,12 +139,10 @@ std::vector PreprocessorKeywordCompletionItems( return items; } -template -char* tofixedbase64(T input, char* out) { - const char* digits = - "./0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; +template char *tofixedbase64(T input, char *out) { + const char *digits = "./0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; int len = (sizeof(T) * 8 - 1) / 6 + 1; for (int i = len - 1; i >= 0; i--) { out[i] = digits[input % 64]; @@ -159,16 +156,15 @@ char* tofixedbase64(T input, char* out) { // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. void FilterAndSortCompletionResponse( - Out_TextDocumentComplete* complete_response, - const std::string& complete_text, - bool has_open_paren) { + Out_TextDocumentComplete *complete_response, + const std::string &complete_text, bool has_open_paren) { if (!g_config->completion.filterAndSort) return; static Timer timer("FilterAndSortCompletionResponse", ""); TimeRegion region(timer); - auto& items = complete_response->result.items; + auto &items = complete_response->result.items; auto finalize = [&]() { const size_t kMaxResultSize = 100u; @@ -178,7 +174,7 @@ void FilterAndSortCompletionResponse( } if (has_open_paren) - for (auto& item: items) + for (auto &item : items) item.insertText = item.label; // Set sortText. Note that this happens after resizing - we could do it @@ -195,7 +191,7 @@ void FilterAndSortCompletionResponse( } // Make sure all items have |filterText| set, code that follow needs it. - for (auto& item : items) { + for (auto &item : items) { if (!item.filterText) item.filterText = item.label; } @@ -203,19 +199,19 @@ void FilterAndSortCompletionResponse( // Fuzzy match and remove awful candidates. bool sensitive = g_config->completion.caseSensitivity; FuzzyMatcher fuzzy(complete_text, sensitive); - for (auto& item : items) { + for (auto &item : items) { item.score_ = ReverseSubseqMatch(complete_text, *item.filterText, sensitive) >= 0 ? fuzzy.Match(*item.filterText) : FuzzyMatcher::kMinScore; } items.erase(std::remove_if(items.begin(), items.end(), - [](const lsCompletionItem& item) { + [](const lsCompletionItem &item) { return item.score_ <= FuzzyMatcher::kMinScore; }), items.end()); std::sort(items.begin(), items.end(), - [](const lsCompletionItem& lhs, const lsCompletionItem& rhs) { + [](const lsCompletionItem &lhs, const lsCompletionItem &rhs) { if (lhs.score_ != rhs.score_) return lhs.score_ > rhs.score_; if (lhs.priority_ != rhs.priority_) @@ -231,16 +227,17 @@ void FilterAndSortCompletionResponse( // Returns true if position is an points to a '(' character in |lines|. Skips // whitespace. -bool IsOpenParenOrAngle(const std::vector& lines, - const lsPosition& position) { +bool IsOpenParenOrAngle(const std::vector &lines, + const lsPosition &position) { auto [c, l] = position; while (l < lines.size()) { - const auto& line = lines[l]; + const auto &line = lines[l]; if (c >= line.size()) return false; if (line[c] == '(' || line[c] == '<') return true; - if (!isspace(line[c])) break; + if (!isspace(line[c])) + break; if (++c >= line.size()) { c = 0; l++; @@ -254,8 +251,8 @@ struct Handler_TextDocumentCompletion : MessageHandler { void Run(std::unique_ptr message) override { auto request = std::shared_ptr( - static_cast(message.release())); - auto& params = request->params; + static_cast(message.release())); + auto ¶ms = request->params; auto write_empty_result = [request]() { Out_TextDocumentComplete out; @@ -264,7 +261,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { }; std::string path = params.textDocument.uri.GetPath(); - WorkingFile* file = working_files->GetFileByFilename(path); + WorkingFile *file = working_files->GetFileByFilename(path); if (!file) { write_empty_result(); return; @@ -350,15 +347,16 @@ struct Handler_TextDocumentCompletion : MessageHandler { if (include_complete->is_scanning) lock.lock(); std::string quote = result.match[5]; - for (auto& item : include_complete->completion_items) - if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) - out.result.items.push_back(item); + for (auto &item : include_complete->completion_items) + if (quote.empty() || + quote == (item.use_angle_brackets_ ? "<" : "\"")) + out.result.items.push_back(item); } FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren); DecorateIncludePaths(result.match, &out.result.items); } - for (lsCompletionItem& item : out.result.items) { + for (lsCompletionItem &item : out.result.items) { item.textEdit->range.start.line = params.position.line; item.textEdit->range.start.character = 0; item.textEdit->range.end.line = params.position.line; @@ -369,14 +367,15 @@ struct Handler_TextDocumentCompletion : MessageHandler { } else { ClangCompleteManager::OnComplete callback = std::bind( [this, request, params, is_global_completion, existing_completion, - has_open_paren](const std::vector& results, + has_open_paren](const std::vector &results, bool is_cached_result) { Out_TextDocumentComplete out; out.id = request->id; out.result.items = results; // Emit completion results. - FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren); + FilterAndSortCompletionResponse(&out, existing_completion, + has_open_paren); pipeline::WriteStdout(kMethodType, out); // Cache completion results. @@ -435,4 +434,4 @@ struct Handler_TextDocumentCompletion : MessageHandler { }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCompletion); -} // namespace +} // namespace diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 93786c3e1..21518b904 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -3,9 +3,9 @@ #include "query_utils.h" using namespace ccls; +#include #include #include -#include namespace { MethodType kMethodType = "textDocument/definition"; @@ -24,35 +24,35 @@ struct Out_TextDocumentDefinition }; MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); -std::vector GetNonDefDeclarationTargets(DB* db, SymbolRef sym) { +std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { - case SymbolKind::Var: { - std::vector ret = GetNonDefDeclarations(db, sym); - // If there is no declaration, jump the its type. - if (ret.empty()) { - for (auto& def : db->GetVar(sym).def) - if (def.type) { - if (Maybe use = GetDefinitionSpell( - db, SymbolIdx{def.type, SymbolKind::Type})) { - ret.push_back(*use); - break; - } + case SymbolKind::Var: { + std::vector ret = GetNonDefDeclarations(db, sym); + // If there is no declaration, jump the its type. + if (ret.empty()) { + for (auto &def : db->GetVar(sym).def) + if (def.type) { + if (Maybe use = GetDefinitionSpell( + db, SymbolIdx{def.type, SymbolKind::Type})) { + ret.push_back(*use); + break; } - } - return ret; + } } - default: - return GetNonDefDeclarations(db, sym); + return ret; + } + default: + return GetNonDefDeclarations(db, sym); } } struct Handler_TextDocumentDefinition : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDefinition* request) override { - auto& params = request->params; + void Run(In_TextDocumentDefinition *request) override { + auto ¶ms = request->params; int file_id; - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file, &file_id)) return; @@ -62,9 +62,8 @@ struct Handler_TextDocumentDefinition Maybe on_def; bool has_symbol = false; - WorkingFile* wfile = - working_files->GetFileByFilename(file->def->path); - lsPosition& ls_pos = params.position; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsPosition &ls_pos = params.position; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { // Found symbol. Return definition. @@ -75,7 +74,7 @@ struct Handler_TextDocumentDefinition // - start at spelling but end at extent for better mouse tooltip // - goto declaration while in definition of recursive type std::vector uses; - EachEntityDef(db, sym, [&](const auto& def) { + EachEntityDef(db, sym, [&](const auto &def) { if (def.spell && def.extent) { Use spell = *def.spell; // If on a definition, clear |uses| to find declarations below. @@ -109,7 +108,7 @@ struct Handler_TextDocumentDefinition // No symbols - check for includes. if (out.result.empty()) { - for (const IndexInclude& include : file->def->includes) { + for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { lsLocationEx result; result.uri = lsDocumentUri::FromPath(include.resolved_path); @@ -121,7 +120,7 @@ struct Handler_TextDocumentDefinition // Find the best match of the identifier at point. if (!has_symbol) { lsPosition position = request->params.position; - const std::string& buffer = wfile->buffer_content; + const std::string &buffer = wfile->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); std::string_view short_query = query; { @@ -161,11 +160,11 @@ struct Handler_TextDocumentDefinition } } }; - for (auto& func : db->funcs) + for (auto &func : db->funcs) fn({func.usr, SymbolKind::Func}); - for (auto& type : db->types) + for (auto &type : db->types) fn({type.usr, SymbolKind::Type}); - for (auto& var : db->vars) + for (auto &var : db->vars) if (var.def.size() && !var.def[0].is_local()) fn({var.usr, SymbolKind::Var}); @@ -183,4 +182,4 @@ struct Handler_TextDocumentDefinition } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); -} // namespace +} // namespace diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index 54ce8b702..abb63553f 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -1,8 +1,8 @@ #include "clang_complete.h" #include "message_handler.h" +#include "pipeline.hh" #include "project.h" #include "working_files.h" -#include "pipeline.hh" using namespace ccls; namespace { @@ -20,7 +20,7 @@ struct Handler_TextDocumentDidChange : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDidChange* request) override { + void Run(In_TextDocumentDidChange *request) override { std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); if (g_config->index.onDidChange) { @@ -33,4 +33,4 @@ struct Handler_TextDocumentDidChange } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); -} // namespace +} // namespace diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index e13382d74..6e28b898f 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -22,7 +22,7 @@ struct Handler_TextDocumentDidClose : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDidClose* request) override { + void Run(In_TextDocumentDidClose *request) override { std::string path = request->params.textDocument.uri.GetPath(); // Clear any diagnostics for the file. @@ -36,4 +36,4 @@ struct Handler_TextDocumentDidClose } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); -} // namespace +} // namespace diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 9f6eea539..3071beb14 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -1,8 +1,8 @@ #include "clang_complete.h" #include "include_complete.h" #include "message_handler.h" -#include "project.h" #include "pipeline.hh" +#include "project.h" #include "working_files.h" using namespace ccls; @@ -12,7 +12,7 @@ MethodType kMethodType = "textDocument/didOpen"; // Open, view, change, close file struct In_TextDocumentDidOpen : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } - + struct Params { lsTextDocumentItem textDocument; @@ -31,18 +31,18 @@ struct Handler_TextDocumentDidOpen : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDidOpen* request) override { + void Run(In_TextDocumentDidOpen *request) override { // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. - const auto& params = request->params; + const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); - WorkingFile* working_file = working_files->OnOpen(params.textDocument); + WorkingFile *working_file = working_files->OnOpen(params.textDocument); if (std::optional cached_file_contents = pipeline::LoadCachedFileContents(path)) working_file->SetIndexContent(*cached_file_contents); - QueryFile* file = nullptr; + QueryFile *file = nullptr; FindFileOrFail(db, project, std::nullopt, path, &file); if (file && file->def) { EmitSkippedRanges(working_file, file->def->skipped_ranges); @@ -68,4 +68,4 @@ struct Handler_TextDocumentDidOpen } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); -} // namespace +} // namespace diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index d3c77f065..7e4ebdf86 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -1,7 +1,7 @@ #include "clang_complete.h" #include "message_handler.h" -#include "project.h" #include "pipeline.hh" +#include "project.h" using namespace ccls; namespace { @@ -28,8 +28,8 @@ struct Handler_TextDocumentDidSave : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDidSave* request) override { - const auto& params = request->params; + void Run(In_TextDocumentDidSave *request) override { + const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); // Send out an index request, and copy the current buffer state so we @@ -55,4 +55,4 @@ struct Handler_TextDocumentDidSave } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); -} // namespace +} // namespace diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index f7cfc0f15..8ee24cc6a 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -24,16 +24,16 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result); struct Handler_TextDocumentDocumentHighlight : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDocumentHighlight* request) override { + void Run(In_TextDocumentDocumentHighlight *request) override { int file_id; - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, &file_id)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentDocumentHighlight out; @@ -66,4 +66,4 @@ struct Handler_TextDocumentDocumentHighlight } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); -} // namespace +} // namespace diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 288c14ad8..8172e3ba3 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -38,10 +38,10 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result); struct Handler_TextDocumentDocumentSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDocumentSymbol* request) override { - auto& params = request->params; + void Run(In_TextDocumentDocumentSymbol *request) override { + auto ¶ms = request->params; - QueryFile* file; + QueryFile *file; int file_id; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file, &file_id)) @@ -67,8 +67,8 @@ struct Handler_TextDocumentDocumentSymbol if (std::optional info = GetSymbolInfo(db, working_files, sym, false)) { if (sym.kind == SymbolKind::Var) { - QueryVar& var = db->GetVar(sym); - auto* def = var.AnyDef(); + QueryVar &var = db->GetVar(sym); + auto *def = var.AnyDef(); if (!def || !def->spell || def->is_local()) continue; } @@ -84,4 +84,4 @@ struct Handler_TextDocumentDocumentSymbol } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); -} // namespace +} // namespace diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 36f5c710f..e6f4a436f 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -7,10 +7,10 @@ namespace { MethodType kMethodType = "textDocument/hover"; // Find the comments for |sym|, if any. -std::optional GetComments(DB* db, SymbolRef sym) { +std::optional GetComments(DB *db, SymbolRef sym) { std::optional ret; - WithEntity(db, sym, [&](const auto& entity) { - if (const auto* def = entity.AnyDef()) + WithEntity(db, sym, [&](const auto &entity) { + if (const auto *def = entity.AnyDef()) if (def->comments[0]) { lsMarkedString m; m.value = def->comments; @@ -21,12 +21,11 @@ std::optional GetComments(DB* db, SymbolRef sym) { } // Returns the hover or detailed name for `sym`, if any. -std::optional GetHoverOrName(DB* db, - LanguageId lang, +std::optional GetHoverOrName(DB *db, LanguageId lang, SymbolRef sym) { std::optional ret; - WithEntity(db, sym, [&](const auto& entity) { - if (const auto* def = entity.AnyDef()) { + WithEntity(db, sym, [&](const auto &entity) { + if (const auto *def = entity.AnyDef()) { lsMarkedString m; m.language = LanguageIdentifier(lang); if (def->hover[0]) { @@ -58,21 +57,19 @@ struct Out_TextDocumentHover : public lsOutMessage { std::optional result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, - jsonrpc, - id, +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, jsonrpc, id, result); struct Handler_TextDocumentHover : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentHover* request) override { - auto& params = request->params; - QueryFile* file; + void Run(In_TextDocumentHover *request) override { + auto ¶ms = request->params; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentHover out; @@ -104,4 +101,4 @@ struct Handler_TextDocumentHover : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); -} // namespace +} // namespace diff --git a/src/messages/textDocument_implementation.cc b/src/messages/textDocument_implementation.cc index 56bf2f233..32617c1df 100644 --- a/src/messages/textDocument_implementation.cc +++ b/src/messages/textDocument_implementation.cc @@ -1,6 +1,6 @@ #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; namespace { @@ -16,14 +16,14 @@ REGISTER_IN_MESSAGE(In_TextDocumentImplementation); struct Handler_TextDocumentImplementation : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentImplementation* request) override { - QueryFile* file; + void Run(In_TextDocumentImplementation *request) override { + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_LocationList out; @@ -31,12 +31,12 @@ struct Handler_TextDocumentImplementation for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { - QueryType& type = db->GetType(sym); + QueryType &type = db->GetType(sym); out.result = GetLsLocationExs(db, working_files, GetTypeDeclarations(db, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { - QueryFunc& func = db->GetFunc(sym); + QueryFunc &func = db->GetFunc(sym); out.result = GetLsLocationExs(db, working_files, GetFuncDeclarations(db, func.derived)); break; @@ -46,4 +46,4 @@ struct Handler_TextDocumentImplementation } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); -} // namespace +} // namespace diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index b11c50738..61802ffe7 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -27,14 +27,9 @@ struct In_TextDocumentReferences : public RequestInMessage { Params params; }; -MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, - base, - excludeRole, - includeDeclaration, - role); -MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, - textDocument, - position, +MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, base, + excludeRole, includeDeclaration, role); +MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position, context); MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params); REGISTER_IN_MESSAGE(In_TextDocumentReferences); @@ -50,15 +45,14 @@ struct Handler_TextDocumentReferences : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentReferences* request) override { - auto& params = request->params; - QueryFile* file; + void Run(In_TextDocumentReferences *request) override { + auto ¶ms = request->params; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - WorkingFile* wfile = - working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); Out_TextDocumentReferences out; out.id = request->id; @@ -86,9 +80,9 @@ struct Handler_TextDocumentReferences out.result.push_back(*ls_loc); } }; - WithEntity(db, sym, [&](const auto& entity) { + WithEntity(db, sym, [&](const auto &entity) { lsSymbolKind parent_kind = lsSymbolKind::Unknown; - for (auto& def : entity.def) + for (auto &def : entity.def) if (def.spell) { parent_kind = GetSymbolKind(db, sym); if (params.context.base) @@ -102,7 +96,7 @@ struct Handler_TextDocumentReferences for (Use use : entity.uses) fn(use, parent_kind); if (params.context.includeDeclaration) { - for (auto& def : entity.def) + for (auto &def : entity.def) if (def.spell) fn(*def.spell, parent_kind); for (Use use : entity.declarations) @@ -120,21 +114,20 @@ struct Handler_TextDocumentReferences std::string path; if (params.position.line == 0) path = file->def->path; - for (const IndexInclude& include : file->def->includes) + for (const IndexInclude &include : file->def->includes) if (include.line == params.position.line) { path = include.resolved_path; break; } if (path.size()) - for (QueryFile& file1 : db->files) + for (QueryFile &file1 : db->files) if (file1.def) - for (const IndexInclude& include : file1.def->includes) + for (const IndexInclude &include : file1.def->includes) if (include.resolved_path == path) { // Another file |file1| has the same include line. lsLocationEx result; result.uri = lsDocumentUri::FromPath(file1.def->path); - result.range.start.line = result.range.end.line = - include.line; + result.range.start.line = result.range.end.line = include.line; out.result.push_back(std::move(result)); break; } @@ -146,4 +139,4 @@ struct Handler_TextDocumentReferences } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); -} // namespace +} // namespace diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 096b79b91..a9665f3da 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -1,19 +1,18 @@ #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; namespace { MethodType kMethodType = "textDocument/rename"; -lsWorkspaceEdit BuildWorkspaceEdit(DB* db, - WorkingFiles* working_files, - SymbolRef sym, - const std::string& new_text) { +lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, + SymbolRef sym, const std::string &new_text) { std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { - std::optional ls_location = GetLsLocation(db, working_files, use); + std::optional ls_location = + GetLsLocation(db, working_files, use); if (!ls_location) return; @@ -21,14 +20,14 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB* db, if (path_to_edit.find(file_id) == path_to_edit.end()) { path_to_edit[file_id] = lsTextDocumentEdit(); - QueryFile& file = db->files[file_id]; + QueryFile &file = db->files[file_id]; if (!file.def) return; - const std::string& path = file.def->path; + const std::string &path = file.def->path; path_to_edit[file_id].textDocument.uri = lsDocumentUri::FromPath(path); - WorkingFile* working_file = working_files->GetFileByFilename(path); + WorkingFile *working_file = working_files->GetFileByFilename(path); if (working_file) path_to_edit[file_id].textDocument.version = working_file->version; } @@ -38,13 +37,13 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB* db, edit.newText = new_text; // vscode complains if we submit overlapping text edits. - auto& edits = path_to_edit[file_id].edits; + auto &edits = path_to_edit[file_id].edits; if (std::find(edits.begin(), edits.end(), edit) == edits.end()) edits.push_back(edit); }); lsWorkspaceEdit edit; - for (const auto& changes : path_to_edit) + for (const auto &changes : path_to_edit) edit.documentChanges.push_back(changes.second); return edit; } @@ -65,9 +64,7 @@ struct In_TextDocumentRename : public RequestInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, - textDocument, - position, +MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position, newName); MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params); REGISTER_IN_MESSAGE(In_TextDocumentRename); @@ -80,16 +77,16 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result); struct Handler_TextDocumentRename : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentRename* request) override { + void Run(In_TextDocumentRename *request) override { int file_id; - QueryFile* file; + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, &file_id)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentRename out; @@ -107,4 +104,4 @@ struct Handler_TextDocumentRename : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); -} // namespace +} // namespace diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 0d7f056e1..aedb0851c 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -70,9 +70,7 @@ struct lsSignatureHelp { // active signature does have any. std::optional activeParameter; }; -MAKE_REFLECT_STRUCT(lsSignatureHelp, - signatures, - activeSignature, +MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, activeParameter); struct Out_TextDocumentSignatureHelp @@ -86,9 +84,9 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(std::unique_ptr message) override { - auto request = static_cast(message.get()); - lsTextDocumentPositionParams& params = request->params; - WorkingFile* file = + auto request = static_cast(message.get()); + lsTextDocumentPositionParams ¶ms = request->params; + WorkingFile *file = working_files->GetFileByFilename(params.textDocument.uri.GetPath()); std::string search; int active_param = 0; @@ -102,21 +100,21 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { return; ClangCompleteManager::OnComplete callback = std::bind( - [this](InMessage* message, std::string search, int active_param, - const std::vector& results, + [this](InMessage *message, std::string search, int active_param, + const std::vector &results, bool is_cached_result) { - auto msg = static_cast(message); + auto msg = static_cast(message); Out_TextDocumentSignatureHelp out; out.id = msg->id; - for (auto& result : results) { + for (auto &result : results) { if (result.label != search) continue; lsSignatureInformation signature; signature.label = result.detail; - for (auto& parameter : result.parameters_) { + for (auto ¶meter : result.parameters_) { lsParameterInformation ls_param; ls_param.label = parameter; signature.parameters.push_back(ls_param); @@ -168,4 +166,4 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentSignatureHelp); -} // namespace +} // namespace diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index 98a54312f..ada23b4e7 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -23,14 +23,14 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentTypeDefinition, jsonrpc, id, result); struct Handler_TextDocumentTypeDefinition : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentTypeDefinition* request) override { - QueryFile* file; + void Run(In_TextDocumentTypeDefinition *request) override { + QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, nullptr)) { return; } - WorkingFile* working_file = + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentTypeDefinition out; @@ -39,25 +39,25 @@ struct Handler_TextDocumentTypeDefinition FindSymbolsAtLocation(working_file, file, request->params.position)) { Usr usr = sym.usr; switch (sym.kind) { - case SymbolKind::Var: { - const QueryVar::Def* def = db->GetVar(sym).AnyDef(); - if (!def || !def->type) - continue; - usr = def->type; - [[fallthrough]]; - } - case SymbolKind::Type: { - QueryType& type = db->Type(usr); - for (const auto& def : type.def) - if (def.spell) { - if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, - g_config->xref.container)) - out.result.push_back(*ls_loc); - } - break; - } - default: - break; + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (!def || !def->type) + continue; + usr = def->type; + [[fallthrough]]; + } + case SymbolKind::Type: { + QueryType &type = db->Type(usr); + for (const auto &def : type.def) + if (def.spell) { + if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, + g_config->xref.container)) + out.result.push_back(*ls_loc); + } + break; + } + default: + break; } } @@ -66,4 +66,4 @@ struct Handler_TextDocumentTypeDefinition }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); -} // namespace +} // namespace diff --git a/src/messages/workspace_didChangeConfiguration.cc b/src/messages/workspace_didChangeConfiguration.cc index 3845b6adb..81f3210b6 100644 --- a/src/messages/workspace_didChangeConfiguration.cc +++ b/src/messages/workspace_didChangeConfiguration.cc @@ -1,7 +1,7 @@ #include "clang_complete.h" #include "message_handler.h" -#include "project.h" #include "pipeline.hh" +#include "project.h" #include "working_files.h" using namespace ccls; @@ -23,7 +23,7 @@ REGISTER_IN_MESSAGE(In_WorkspaceDidChangeConfiguration); struct Handler_WorkspaceDidChangeConfiguration : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceDidChangeConfiguration* request) override { + void Run(In_WorkspaceDidChangeConfiguration *request) override { project->Load(g_config->projectRoot); project->Index(working_files, lsRequestId()); @@ -31,4 +31,4 @@ struct Handler_WorkspaceDidChangeConfiguration } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeConfiguration); -} // namespace +} // namespace diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index f5e813633..26762a1d7 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -1,7 +1,7 @@ #include "clang_complete.h" #include "message_handler.h" -#include "project.h" #include "pipeline.hh" +#include "project.h" #include "working_files.h" using namespace ccls; @@ -36,8 +36,8 @@ REGISTER_IN_MESSAGE(In_WorkspaceDidChangeWatchedFiles); struct Handler_WorkspaceDidChangeWatchedFiles : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceDidChangeWatchedFiles* request) override { - for (lsFileEvent& event : request->params.changes) { + void Run(In_WorkspaceDidChangeWatchedFiles *request) override { + for (lsFileEvent &event : request->params.changes) { std::string path = event.uri.GetPath(); Project::Entry entry; { @@ -50,19 +50,19 @@ struct Handler_WorkspaceDidChangeWatchedFiles bool is_interactive = working_files->GetFileByFilename(entry.filename) != nullptr; switch (event.type) { - case lsFileChangeType::Created: - case lsFileChangeType::Changed: { - pipeline::Index(path, entry.args, is_interactive); - if (is_interactive) - clang_complete->NotifySave(path); - break; - } - case lsFileChangeType::Deleted: - pipeline::Index(path, entry.args, is_interactive); - break; + case lsFileChangeType::Created: + case lsFileChangeType::Changed: { + pipeline::Index(path, entry.args, is_interactive); + if (is_interactive) + clang_complete->NotifySave(path); + break; + } + case lsFileChangeType::Deleted: + pipeline::Index(path, entry.args, is_interactive); + break; } } } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeWatchedFiles); -} // namespace +} // namespace diff --git a/src/messages/workspace_executeCommand.cc b/src/messages/workspace_executeCommand.cc index c2d71c751..959484bdd 100644 --- a/src/messages/workspace_executeCommand.cc +++ b/src/messages/workspace_executeCommand.cc @@ -1,7 +1,7 @@ #include "lsp_code_action.h" #include "message_handler.h" -#include "query_utils.h" #include "pipeline.hh" +#include "query_utils.h" using namespace ccls; namespace { @@ -24,8 +24,8 @@ MAKE_REFLECT_STRUCT(Out_WorkspaceExecuteCommand, jsonrpc, id, result); struct Handler_WorkspaceExecuteCommand : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceExecuteCommand* request) override { - const auto& params = request->params; + void Run(In_WorkspaceExecuteCommand *request) override { + const auto ¶ms = request->params; Out_WorkspaceExecuteCommand out; out.id = request->id; if (params.command == "ccls._applyFixIt") { @@ -40,4 +40,4 @@ struct Handler_WorkspaceExecuteCommand }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); -} // namespace +} // namespace diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 3b6086354..33d80de96 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -4,21 +4,18 @@ #include "query_utils.h" using namespace ccls; -#include -#include #include +#include #include +#include namespace { MethodType kMethodType = "workspace/symbol"; // Lookup |symbol| in |db| and insert the value into |result|. bool AddSymbol( - DB* db, - WorkingFiles* working_files, - SymbolIdx sym, - bool use_detailed, - std::vector>* result) { + DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed, + std::vector> *result) { std::optional info = GetSymbolInfo(db, working_files, sym, true); if (!info) @@ -63,7 +60,7 @@ MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result); struct Handler_WorkspaceSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceSymbol* request) override { + void Run(In_WorkspaceSymbol *request) override { Out_WorkspaceSymbol out; out.id = request->id; @@ -83,40 +80,41 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { auto Add = [&](SymbolIdx sym) { std::string_view detailed_name = db->GetSymbolName(sym, true); int pos = - ReverseSubseqMatch(query_without_space, detailed_name, sensitive); + ReverseSubseqMatch(query_without_space, detailed_name, sensitive); return pos >= 0 && AddSymbol(db, working_files, sym, detailed_name.find(':', pos) != std::string::npos, &cands) && cands.size() >= g_config->workspaceSymbol.maxNum; }; - for (auto& func : db->funcs) + for (auto &func : db->funcs) if (Add({func.usr, SymbolKind::Func})) goto done_add; - for (auto& type : db->types) + for (auto &type : db->types) if (Add({type.usr, SymbolKind::Type})) goto done_add; - for (auto& var : db->vars) + for (auto &var : db->vars) if (var.def.size() && !var.def[0].is_local() && Add({var.usr, SymbolKind::Var})) goto done_add; - done_add: + done_add: - if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { + if (g_config->workspaceSymbol.sort && + query.size() <= FuzzyMatcher::kMaxPat) { // Sort results with a fuzzy matching algorithm. int longest = 0; - for (auto& cand : cands) + for (auto &cand : cands) longest = std::max( longest, int(db->GetSymbolName(std::get<2>(cand), true).size())); FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); - for (auto& cand : cands) + for (auto &cand : cands) std::get<1>(cand) = fuzzy.Match( db->GetSymbolName(std::get<2>(cand), std::get<1>(cand))); - std::sort(cands.begin(), cands.end(), [](const auto& l, const auto& r) { + std::sort(cands.begin(), cands.end(), [](const auto &l, const auto &r) { return std::get<1>(l) > std::get<1>(r); }); out.result.reserve(cands.size()); - for (auto& cand: cands) { + for (auto &cand : cands) { // Discard awful candidates. if (std::get<1>(cand) <= FuzzyMatcher::kMinScore) break; @@ -124,7 +122,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { } } else { out.result.reserve(cands.size()); - for (auto& cand : cands) + for (auto &cand : cands) out.result.push_back(std::get<0>(cand)); } @@ -132,4 +130,4 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); -} // namespace +} // namespace diff --git a/src/method.cc b/src/method.cc index 914e2d4f7..c3a48a6df 100644 --- a/src/method.cc +++ b/src/method.cc @@ -4,12 +4,11 @@ MethodType kMethodType_Unknown = "$unknown"; MethodType kMethodType_Exit = "exit"; MethodType kMethodType_TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"; -MethodType kMethodType_CclsPublishSkippedRanges = - "$ccls/publishSkippedRanges"; +MethodType kMethodType_CclsPublishSkippedRanges = "$ccls/publishSkippedRanges"; MethodType kMethodType_CclsPublishSemanticHighlighting = "$ccls/publishSemanticHighlighting"; -void Reflect(Reader& visitor, lsRequestId& value) { +void Reflect(Reader &visitor, lsRequestId &value) { if (visitor.IsInt64()) { value.type = lsRequestId::kInt; value.value = int(visitor.GetInt64()); @@ -25,7 +24,7 @@ void Reflect(Reader& visitor, lsRequestId& value) { } } -void Reflect(Writer& visitor, lsRequestId& value) { +void Reflect(Writer &visitor, lsRequestId &value) { switch (value.type) { case lsRequestId::kNone: visitor.Null(); diff --git a/src/method.h b/src/method.h index a7317b1e7..b308002e9 100644 --- a/src/method.h +++ b/src/method.h @@ -5,7 +5,7 @@ #include -using MethodType = const char*; +using MethodType = const char *; extern MethodType kMethodType_Unknown; extern MethodType kMethodType_Exit; extern MethodType kMethodType_TextDocumentPublishDiagnostics; @@ -22,8 +22,8 @@ struct lsRequestId { bool Valid() const { return type != kNone; } }; -void Reflect(Reader& visitor, lsRequestId& value); -void Reflect(Writer& visitor, lsRequestId& value); +void Reflect(Reader &visitor, lsRequestId &value); +void Reflect(Writer &visitor, lsRequestId &value); struct InMessage { virtual ~InMessage() = default; @@ -35,14 +35,10 @@ struct InMessage { struct RequestInMessage : public InMessage { // number or string, actually no null lsRequestId id; - lsRequestId GetRequestId() const override { - return id; - } + lsRequestId GetRequestId() const override { return id; } }; // NotificationInMessage does not have |id|. struct NotificationInMessage : public InMessage { - lsRequestId GetRequestId() const override { - return lsRequestId(); - } + lsRequestId GetRequestId() const override { return lsRequestId(); } }; diff --git a/src/pipeline.cc b/src/pipeline.cc index bbced1d94..053d4f4f0 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -6,10 +6,10 @@ #include "log.hh" #include "lsp.h" #include "message_handler.h" +#include "pipeline.hh" #include "platform.h" #include "project.h" #include "query_utils.h" -#include "pipeline.hh" #include #include @@ -28,12 +28,12 @@ void DiagnosticsPublisher::Init() { g_config->diagnostics.blacklist); } -void DiagnosticsPublisher::Publish(WorkingFiles* working_files, +void DiagnosticsPublisher::Publish(WorkingFiles *working_files, std::string path, std::vector diagnostics) { bool good = true; // Cache diagnostics so we can show fixits. - working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { + working_files->DoActionOnFile(path, [&](WorkingFile *working_file) { if (working_file) { good = working_file->diagnostics_.empty(); working_file->diagnostics_ = diagnostics; @@ -52,7 +52,8 @@ void DiagnosticsPublisher::Publish(WorkingFiles* working_files, Out_TextDocumentPublishDiagnostics out; out.params.uri = lsDocumentUri::FromPath(path); out.params.diagnostics = diagnostics; - ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); + ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, + out); } } @@ -71,13 +72,13 @@ struct Stdout_Request { std::string content; }; -MultiQueueWaiter* main_waiter; -MultiQueueWaiter* indexer_waiter; -MultiQueueWaiter* stdout_waiter; -ThreadedQueue>* on_request; -ThreadedQueue* index_request; -ThreadedQueue* on_indexed; -ThreadedQueue* for_stdout; +MultiQueueWaiter *main_waiter; +MultiQueueWaiter *indexer_waiter; +MultiQueueWaiter *stdout_waiter; +ThreadedQueue> *on_request; +ThreadedQueue *index_request; +ThreadedQueue *on_indexed; +ThreadedQueue *for_stdout; bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, const std::vector &args, @@ -92,23 +93,24 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, } if (prev->args != args) { - LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); + LOG_S(INFO) << "args changed for " << path + << (from ? " (via " + *from + ")" : std::string()); return true; } return false; }; -std::string AppendSerializationFormat(const std::string& base) { +std::string AppendSerializationFormat(const std::string &base) { switch (g_config->cacheFormat) { - case SerializeFormat::Binary: - return base + ".blob"; - case SerializeFormat::Json: - return base + ".json"; + case SerializeFormat::Binary: + return base + ".blob"; + case SerializeFormat::Json: + return base + ".json"; } } -std::string GetCachePath(const std::string& source_file) { +std::string GetCachePath(const std::string &source_file) { std::string cache_file; size_t len = g_config->projectRoot.size(); if (StartsWith(source_file, g_config->projectRoot)) { @@ -122,8 +124,7 @@ std::string GetCachePath(const std::string& source_file) { return g_config->cacheDirectory + cache_file; } -std::unique_ptr RawCacheLoad( - const std::string& path) { +std::unique_ptr RawCacheLoad(const std::string &path) { std::string cache_path = GetCachePath(path); std::optional file_content = ReadContent(cache_path); std::optional serialized_indexed_content = @@ -136,14 +137,12 @@ std::unique_ptr RawCacheLoad( IndexFile::kMajorVersion); } -bool Indexer_Parse(DiagnosticsPublisher* diag_pub, - WorkingFiles* working_files, - Project* project, - VFS* vfs) { +bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, + Project *project, VFS *vfs) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; - auto& request = *opt_request; + auto &request = *opt_request; // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { @@ -183,7 +182,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, reparse = 2; int reparseForDep = g_config->index.reparseForDependency; if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded)) - for (const auto& dep : prev->dependencies) { + for (const auto &dep : prev->dependencies) { if (auto write_time1 = LastWriteTime(dep.first().str())) { if (dep.second < *write_time1) { reparse = 2; @@ -210,7 +209,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, } std::lock_guard lock(vfs->mutex); - VFS::State& state = vfs->state[path_to_index]; + VFS::State &state = vfs->state[path_to_index]; if (state.owner == g_thread_id) state.stage = 0; return true; @@ -218,7 +217,8 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, LOG_S(INFO) << "parse " << path_to_index; - auto indexes = idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); + auto indexes = + idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -232,7 +232,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, return true; } - for (std::unique_ptr& curr : indexes) { + for (std::unique_ptr &curr : indexes) { // Only emit diagnostics for non-interactive sessions, which makes it easier // to identify indexing problems. For interactive sessions, diagnostics are // handled by code completion. @@ -260,7 +260,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, vfs->Reset(path); if (entry.id >= 0) { std::lock_guard lock(project->mutex_); - for (auto& dep : curr->dependencies) + for (auto &dep : curr->dependencies) project->absolute_path_to_entry_index_[dep.first()] = entry.id; } @@ -274,7 +274,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, return true; } -} // namespace +} // namespace void Init() { main_waiter = new MultiQueueWaiter; @@ -288,28 +288,25 @@ void Init() { for_stdout = new ThreadedQueue(stdout_waiter); } -void Indexer_Main(DiagnosticsPublisher* diag_pub, - VFS* vfs, - Project* project, - WorkingFiles* working_files) { +void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, + WorkingFiles *working_files) { while (true) if (!Indexer_Parse(diag_pub, working_files, project, vfs)) indexer_waiter->Wait(index_request); } -void Main_OnIndexed(DB* db, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files, - IndexUpdate* update) { +void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, + WorkingFiles *working_files, IndexUpdate *update) { if (update->refresh) { Project::loaded = true; - LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; + LOG_S(INFO) + << "loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); - for (auto& f : working_files->files) { + for (auto &f : working_files->files) { std::string filename = LowerPathIfInsensitive(f->filename); if (db->name2file_id.find(filename) == db->name2file_id.end()) continue; - QueryFile* file = &db->files[db->name2file_id[filename]]; + QueryFile *file = &db->files[db->name2file_id[filename]]; EmitSemanticHighlighting(db, semantic_cache, f.get(), file); } return; @@ -322,9 +319,9 @@ void Main_OnIndexed(DB* db, // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { - auto& def_u = *update->files_def_update; + auto &def_u = *update->files_def_update; LOG_S(INFO) << "apply index for " << def_u.first.path; - if (WorkingFile* working_file = + if (WorkingFile *working_file = working_files->GetFileByFilename(def_u.first.path)) { working_file->SetIndexContent(def_u.second); EmitSkippedRanges(working_file, def_u.first.skipped_ranges); @@ -369,7 +366,8 @@ void LaunchStdin() { if (method_type == kMethodType_Exit) break; } - }).detach(); + }) + .detach(); } void LaunchStdout() { @@ -383,7 +381,7 @@ void LaunchStdout() { continue; } - for (auto& message : messages) { + for (auto &message : messages) { #ifdef _WIN32 fwrite(message.content.c_str(), message.content.size(), 1, stdout); fflush(stdout); @@ -392,7 +390,8 @@ void LaunchStdout() { #endif } } - }).detach(); + }) + .detach(); } void MainLoop() { @@ -412,9 +411,8 @@ void MainLoop() { Out_Error out; out.id = id; out.error.code = lsErrorCodes::InternalError; - out.error.message = - "Dropping completion request; a newer request " - "has come in that will be serviced instead."; + out.error.message = "Dropping completion request; a newer request " + "has come in that will be serviced instead."; pipeline::WriteStdout(kMethodType_Unknown, out); } }); @@ -426,7 +424,7 @@ void MainLoop() { DB db; // Setup shared references. - for (MessageHandler* handler : *MessageHandler::message_handlers) { + for (MessageHandler *handler : *MessageHandler::message_handlers) { handler->db = &db; handler->waiter = indexer_waiter; handler->project = &project; @@ -445,9 +443,9 @@ void MainLoop() { while (true) { std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); - for (auto& message : messages) { + for (auto &message : messages) { // TODO: Consider using std::unordered_map to lookup the handler - for (MessageHandler* handler : *MessageHandler::message_handlers) { + for (MessageHandler *handler : *MessageHandler::message_handlers) { if (handler->GetMethodType() == message->GetMethodType()) { handler->Run(std::move(message)); break; @@ -473,18 +471,16 @@ void MainLoop() { } } -void Index(const std::string& path, - const std::vector& args, - bool interactive, - lsRequestId id) { +void Index(const std::string &path, const std::vector &args, + bool interactive, lsRequestId id) { index_request->PushBack({path, args, interactive, id}, interactive); } -std::optional LoadCachedFileContents(const std::string& path) { +std::optional LoadCachedFileContents(const std::string &path) { return ReadContent(GetCachePath(path)); } -void WriteStdout(MethodType method, lsBaseOutMessage& response) { +void WriteStdout(MethodType method, lsBaseOutMessage &response) { std::ostringstream sstream; response.Write(sstream); @@ -494,4 +490,4 @@ void WriteStdout(MethodType method, lsBaseOutMessage& response) { for_stdout->PushBack(std::move(out)); } -} +} // namespace ccls::pipeline diff --git a/src/platform.h b/src/platform.h index 561647b3f..d130e788a 100644 --- a/src/platform.h +++ b/src/platform.h @@ -4,7 +4,7 @@ #include #include -std::string NormalizePath(const std::string& path); +std::string NormalizePath(const std::string &path); // Free any unused memory and return it to the system. void FreeUnusedMemory(); @@ -12,5 +12,5 @@ void FreeUnusedMemory(); // Stop self and wait for SIGCONT. void TraceMe(); -std::string GetExternalCommandOutput(const std::vector& command, +std::string GetExternalCommandOutput(const std::vector &command, std::string_view input); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 10bad8d4e..ac7409fff 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -14,10 +14,10 @@ #include #include #include -#include #include -#include // required for stat.h +#include // required for stat.h #include +#include #ifdef __GLIBC__ #include #endif @@ -89,9 +89,9 @@ std::optional RealPathNotExpandSymlink(std::string path) { return resolved; } -} // namespace +} // namespace -std::string NormalizePath(const std::string& path) { +std::string NormalizePath(const std::string &path) { std::optional resolved = RealPathNotExpandSymlink(path); return resolved ? *resolved : path; } @@ -106,12 +106,12 @@ void TraceMe() { // If the environment variable is defined, wait for a debugger. // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. - const char* traceme = getenv("CCLS_TRACEME"); + const char *traceme = getenv("CCLS_TRACEME"); if (traceme) raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } -std::string GetExternalCommandOutput(const std::vector& command, +std::string GetExternalCommandOutput(const std::vector &command, std::string_view input) { int pin[2], pout[2]; if (pipe(pin) < 0) { @@ -132,9 +132,9 @@ std::string GetExternalCommandOutput(const std::vector& command, close(pin[1]); close(pout[0]); close(pout[1]); - auto argv = new char*[command.size() + 1]; + auto argv = new char *[command.size() + 1]; for (size_t i = 0; i < command.size(); i++) - argv[i] = const_cast(command[i].c_str()); + argv[i] = const_cast(command[i].c_str()); argv[command.size()] = nullptr; execvp(argv[0], argv); _Exit(127); diff --git a/src/platform_win.cc b/src/platform_win.cc index 6c02c0ee2..0ba14c3a4 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -15,10 +15,10 @@ #include #include -std::string NormalizePath(const std::string& path) { +std::string NormalizePath(const std::string &path) { DWORD retval = 0; TCHAR buffer[MAX_PATH] = TEXT(""); - TCHAR** lpp_part = {NULL}; + TCHAR **lpp_part = {NULL}; retval = GetFullPathName(path.c_str(), MAX_PATH, buffer, lpp_part); // fail, return original @@ -36,7 +36,7 @@ void FreeUnusedMemory() {} // TODO Wait for debugger to attach void TraceMe() {} -std::string GetExternalCommandOutput(const std::vector& command, +std::string GetExternalCommandOutput(const std::vector &command, std::string_view input) { return ""; } diff --git a/src/position.cc b/src/position.cc index abcab3120..6759e44fd 100644 --- a/src/position.cc +++ b/src/position.cc @@ -6,8 +6,8 @@ #include #include -Position Position::FromString(const std::string& encoded) { - char* p = const_cast(encoded.c_str()); +Position Position::FromString(const std::string &encoded) { + char *p = const_cast(encoded.c_str()); int16_t line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); p++; @@ -21,9 +21,9 @@ std::string Position::ToString() { return buf; } -Range Range::FromString(const std::string& encoded) { +Range Range::FromString(const std::string &encoded) { Position start, end; - char* p = const_cast(encoded.c_str()); + char *p = const_cast(encoded.c_str()); start.line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); p++; @@ -57,7 +57,7 @@ std::string Range::ToString() { } // Position -void Reflect(Reader& visitor, Position& value) { +void Reflect(Reader &visitor, Position &value) { if (visitor.Format() == SerializeFormat::Json) { value = Position::FromString(visitor.GetString()); } else { @@ -65,7 +65,7 @@ void Reflect(Reader& visitor, Position& value) { Reflect(visitor, value.column); } } -void Reflect(Writer& visitor, Position& value) { +void Reflect(Writer &visitor, Position &value) { if (visitor.Format() == SerializeFormat::Json) { std::string output = value.ToString(); visitor.String(output.c_str(), output.size()); @@ -76,7 +76,7 @@ void Reflect(Writer& visitor, Position& value) { } // Range -void Reflect(Reader& visitor, Range& value) { +void Reflect(Reader &visitor, Range &value) { if (visitor.Format() == SerializeFormat::Json) { value = Range::FromString(visitor.GetString()); } else { @@ -86,7 +86,7 @@ void Reflect(Reader& visitor, Range& value) { Reflect(visitor, value.end.column); } } -void Reflect(Writer& visitor, Range& value) { +void Reflect(Writer &visitor, Range &value) { if (visitor.Format() == SerializeFormat::Json) { std::string output = value.ToString(); visitor.String(output.c_str(), output.size()); diff --git a/src/position.h b/src/position.h index 99ec77620..a83f54d69 100644 --- a/src/position.h +++ b/src/position.h @@ -10,17 +10,17 @@ struct Position { int16_t line = -1; int16_t column = -1; - static Position FromString(const std::string& encoded); + static Position FromString(const std::string &encoded); bool Valid() const { return line >= 0; } std::string ToString(); // Compare two Positions and check if they are equal. Ignores the value of // |interesting|. - bool operator==(const Position& o) const { + bool operator==(const Position &o) const { return line == o.line && column == o.column; } - bool operator<(const Position& o) const { + bool operator<(const Position &o) const { if (line != o.line) return line < o.line; return column < o.column; @@ -32,7 +32,7 @@ struct Range { Position start; Position end; - static Range FromString(const std::string& encoded); + static Range FromString(const std::string &encoded); bool Valid() const { return start.Valid(); } bool Contains(int line, int column) const; @@ -40,17 +40,16 @@ struct Range { std::string ToString(); - bool operator==(const Range& o) const { + bool operator==(const Range &o) const { return start == o.start && end == o.end; } - bool operator<(const Range& o) const { + bool operator<(const Range &o) const { return !(start == o.start) ? start < o.start : end < o.end; } }; namespace std { -template <> -struct hash { +template <> struct hash { std::size_t operator()(Range x) const { union U { Range range = {}; @@ -61,12 +60,12 @@ struct hash { return hash()(u.u64); } }; -} +} // namespace std // Reflection class Reader; class Writer; -void Reflect(Reader& visitor, Position& value); -void Reflect(Writer& visitor, Position& value); -void Reflect(Reader& visitor, Range& value); -void Reflect(Writer& visitor, Range& value); +void Reflect(Reader &visitor, Position &value); +void Reflect(Writer &visitor, Position &value); +void Reflect(Reader &visitor, Range &value); +void Reflect(Writer &visitor, Range &value); diff --git a/src/project.cc b/src/project.cc index 3b1b0b1dc..ee5971a11 100644 --- a/src/project.cc +++ b/src/project.cc @@ -5,8 +5,8 @@ #include "language.h" #include "log.hh" #include "match.h" -#include "platform.h" #include "pipeline.hh" +#include "platform.h" #include "serializers/json.h" #include "utils.h" #include "working_files.h" @@ -67,9 +67,9 @@ enum OptionClass { Separate, }; -Project::Entry GetCompilationEntryFromCompileCommandEntry( - ProjectConfig* config, - const CompileCommandsEntry& entry) { +Project::Entry +GetCompilationEntryFromCompileCommandEntry(ProjectConfig *config, + const CompileCommandsEntry &entry) { Project::Entry result; result.filename = entry.file; const std::string base_name = sys::path::filename(entry.file); @@ -77,7 +77,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // Expand %c %cpp %clang std::vector args; const LanguageId lang = SourceFileLanguage(entry.file); - for (const std::string& arg : entry.args) { + for (const std::string &arg : entry.args) { if (arg.compare(0, 3, "%c ") == 0) { if (lang == LanguageId::C) args.push_back(arg.substr(3)); @@ -106,21 +106,21 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( auto TargetAndMode = driver::ToolChain::getTargetAndModeFromProgramName(args[0]); if (!TargetAndMode.TargetPrefix.empty()) { - const char* arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()}; + const char *arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()}; args.insert(args.begin() + 1, std::begin(arr), std::end(arr)); Driver.setTargetAndMode(TargetAndMode); } Driver.setCheckInputsExist(false); - std::vector cargs; - for (auto& arg : args) + std::vector cargs; + for (auto &arg : args) cargs.push_back(arg.c_str()); cargs.push_back("-fsyntax-only"); std::unique_ptr C(Driver.BuildCompilation(cargs)); - const driver::JobList& Jobs = C->getJobs(); + const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1) return result; - const driver::ArgStringList& CCArgs = Jobs.begin()->getArguments(); + const driver::ArgStringList &CCArgs = Jobs.begin()->getArguments(); auto CI = std::make_unique(); CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(), @@ -132,16 +132,16 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( for (auto &E : HeaderOpts.UserEntries) { std::string path = entry.ResolveIfRelative(E.Path); switch (E.Group) { - default: - config->angle_dirs.insert(path); - break; - case frontend::Quoted: - config->quote_dirs.insert(path); - break; - case frontend::Angled: - config->angle_dirs.insert(path); - config->quote_dirs.insert(path); - break; + default: + config->angle_dirs.insert(path); + break; + case frontend::Quoted: + config->quote_dirs.insert(path); + break; + case frontend::Angled: + config->angle_dirs.insert(path); + config->quote_dirs.insert(path); + break; } } @@ -155,7 +155,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - // if (!sys::fs::exists(HeaderOpts.ResourceDir) && HeaderOpts.UseBuiltinIncludes) + // if (!sys::fs::exists(HeaderOpts.ResourceDir) && + // HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory); @@ -169,17 +170,18 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( return result; } -std::vector ReadCompilerArgumentsFromFile( - const std::string& path) { +std::vector +ReadCompilerArgumentsFromFile(const std::string &path) { auto MBOrErr = MemoryBuffer::getFile(path); - if (!MBOrErr) return {}; + if (!MBOrErr) + return {}; std::vector args; for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) args.push_back(*I); return args; } -std::vector LoadFromDirectoryListing(ProjectConfig* config) { +std::vector LoadFromDirectoryListing(ProjectConfig *config) { std::vector result; config->mode = ProjectMode::DotCcls; SmallString<256> Path; @@ -194,7 +196,7 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { GetFilesInFolder(config->project_dir, true /*recursive*/, true /*add_folder_to_path*/, - [&folder_args, &files](const std::string& path) { + [&folder_args, &files](const std::string &path) { if (SourceFileLanguage(path) != LanguageId::Unknown) { files.push_back(path); } else if (sys::path::filename(path) == ".ccls") { @@ -204,12 +206,13 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { } }); - const std::string& project_dir = config->project_dir; - const auto& project_dir_args = folder_args[project_dir]; + const std::string &project_dir = config->project_dir; + const auto &project_dir_args = folder_args[project_dir]; LOG_IF_S(INFO, !project_dir_args.empty()) << "Using .ccls arguments " << StringJoin(project_dir_args); - auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) { + auto GetCompilerArgumentForFile = [&project_dir, + &folder_args](std::string cur) { while (!(cur = sys::path::parent_path(cur)).empty()) { auto it = folder_args.find(cur); if (it != folder_args.end()) @@ -223,13 +226,13 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { return folder_args[project_dir]; }; - for (const std::string& file : files) { + for (const std::string &file : files) { CompileCommandsEntry e; e.directory = config->project_dir; e.file = file; e.args = GetCompilerArgumentForFile(file); if (e.args.empty()) - e.args.push_back("%clang"); // Add a Dummy. + e.args.push_back("%clang"); // Add a Dummy. e.args.push_back(e.file); result.push_back(GetCompilationEntryFromCompileCommandEntry(config, e)); } @@ -237,9 +240,9 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { return result; } -std::vector LoadCompilationEntriesFromDirectory( - ProjectConfig* project, - const std::string& opt_compilation_db_dir) { +std::vector +LoadCompilationEntriesFromDirectory(ProjectConfig *project, + const std::string &opt_compilation_db_dir) { // If there is a .ccls file always load using directory listing. SmallString<256> Path; sys::path::append(Path, project->project_dir, ".ccls"); @@ -273,7 +276,7 @@ std::vector LoadCompilationEntriesFromDirectory( std::vector{g_config->compilationDatabaseCommand, project->project_dir}, input.GetString()); - FILE* fout = fopen(Path.c_str(), "wb"); + FILE *fout = fopen(Path.c_str(), "wb"); fwrite(contents.c_str(), contents.size(), 1, fout); fclose(fout); #endif @@ -284,7 +287,7 @@ std::vector LoadCompilationEntriesFromDirectory( tooling::CompilationDatabase::loadFromDirectory(comp_db_dir, err_msg); if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 - // TODO + // TODO #else unlink(Path.c_str()); rmdir(comp_db_dir.c_str()); @@ -326,11 +329,11 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { return score; } -} // namespace +} // namespace bool Project::loaded = false; -void Project::Load(const std::string& root_directory) { +void Project::Load(const std::string &root_directory) { Project::loaded = false; // Load data. ProjectConfig project; @@ -344,11 +347,11 @@ void Project::Load(const std::string& root_directory) { project.quote_dirs.end()); angle_include_directories.assign(project.angle_dirs.begin(), project.angle_dirs.end()); - for (std::string& path : quote_include_directories) { + for (std::string &path : quote_include_directories) { EnsureEndsInSlash(path); LOG_S(INFO) << "quote_include_dir: " << path; } - for (std::string& path : angle_include_directories) { + for (std::string &path : angle_include_directories) { EnsureEndsInSlash(path); LOG_S(INFO) << "angle_include_dir: " << path; } @@ -362,9 +365,8 @@ void Project::Load(const std::string& root_directory) { } } -void Project::SetFlagsForFile( - const std::vector& flags, - const std::string& path) { +void Project::SetFlagsForFile(const std::vector &flags, + const std::string &path) { std::lock_guard lock(mutex_); auto it = absolute_path_to_entry_index_.find(path); if (it != absolute_path_to_entry_index_.end()) { @@ -380,8 +382,8 @@ void Project::SetFlagsForFile( } } -Project::Entry Project::FindCompilationEntryForFile( - const std::string& filename) { +Project::Entry +Project::FindCompilationEntryForFile(const std::string &filename) { { std::lock_guard lock(mutex_); auto it = absolute_path_to_entry_index_.find(filename); @@ -391,9 +393,9 @@ Project::Entry Project::FindCompilationEntryForFile( // We couldn't find the file. Try to infer it. // TODO: Cache inferred file in a separate array (using a lock or similar) - Entry* best_entry = nullptr; + Entry *best_entry = nullptr; int best_score = std::numeric_limits::min(); - for (Entry& entry : entries) { + for (Entry &entry : entries) { int score = ComputeGuessScore(filename, entry.filename); if (score > best_score) { best_score = score; @@ -412,8 +414,9 @@ Project::Entry Project::FindCompilationEntryForFile( // |best_entry| probably has its own path in the arguments. We need to remap // that path to the new filename. - std::string best_entry_base_name = sys::path::filename(best_entry->filename); - for (std::string& arg : result.args) { + std::string best_entry_base_name = + sys::path::filename(best_entry->filename); + for (std::string &arg : result.args) { try { if (arg == best_entry->filename || sys::path::filename(arg) == best_entry_base_name) @@ -427,10 +430,10 @@ Project::Entry Project::FindCompilationEntryForFile( } void Project::ForAllFilteredFiles( - std::function action) { + std::function action) { GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); for (int i = 0; i < entries.size(); ++i) { - const Project::Entry& entry = entries[i]; + const Project::Entry &entry = entries[i]; std::string failure_reason; if (matcher.IsMatch(entry.filename, &failure_reason)) action(i, entries[i]); @@ -441,9 +444,8 @@ void Project::ForAllFilteredFiles( } } -void Project::Index(WorkingFiles* wfiles, - lsRequestId id) { - ForAllFilteredFiles([&](int i, const Project::Entry& entry) { +void Project::Index(WorkingFiles *wfiles, lsRequestId id) { + ForAllFilteredFiles([&](int i, const Project::Entry &entry) { bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; pipeline::Index(entry.filename, entry.args, is_interactive, id); }); diff --git a/src/project.h b/src/project.h index acb55495f..d91f830c3 100644 --- a/src/project.h +++ b/src/project.h @@ -40,24 +40,23 @@ struct Project { // will affect flags in their subtrees (relative paths are relative to the // project root, not subdirectories). For compile_commands.json, its entries // are indexed. - void Load(const std::string& root_directory); + void Load(const std::string &root_directory); // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure. - Entry FindCompilationEntryForFile(const std::string& filename); + Entry FindCompilationEntryForFile(const std::string &filename); // If the client has overridden the flags, or specified them for a file // that is not in the compilation_database.json make sure those changes // are permanent. - void SetFlagsForFile( - const std::vector& flags, - const std::string& path); + void SetFlagsForFile(const std::vector &flags, + const std::string &path); // Run |action| on every file in the project. - void ForAllFilteredFiles( - std::function action); + void + ForAllFilteredFiles(std::function action); - void Index(WorkingFiles* wfiles, lsRequestId id); + void Index(WorkingFiles *wfiles, lsRequestId id); static bool loaded; }; diff --git a/src/query.cc b/src/query.cc index a5757e2f9..56e637ea7 100644 --- a/src/query.cc +++ b/src/query.cc @@ -19,7 +19,7 @@ void AssignFileId(const Lid2file_id &, int file_id, SymbolRef &ref) { ref.usr = file_id; } -void AssignFileId(const Lid2file_id& lid2file_id, int file_id, Use& use) { +void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) { if (use.kind == SymbolKind::File) use.usr = file_id; if (use.file_id == -1) @@ -44,35 +44,35 @@ void AssignFileId(const Lid2file_id &lid2file_id, int file_id, AssignFileId(lid2file_id, file_id, x); } -void AddRange(std::vector& into, const std::vector& from) { +void AddRange(std::vector &into, const std::vector &from) { into.reserve(into.size() + from.size()); for (Use use : from) into.push_back(use); } -void AddRange(std::vector& into, const std::vector& from) { +void AddRange(std::vector &into, const std::vector &from) { into.insert(into.end(), from.begin(), from.end()); } template -void RemoveRange(std::vector& from, const std::vector& to_remove) { +void RemoveRange(std::vector &from, const std::vector &to_remove) { if (to_remove.size()) { std::unordered_set to_remove_set(to_remove.begin(), to_remove.end()); from.erase( - std::remove_if(from.begin(), from.end(), - [&](const T& t) { return to_remove_set.count(t) > 0; }), - from.end()); + std::remove_if(from.begin(), from.end(), + [&](const T &t) { return to_remove_set.count(t) > 0; }), + from.end()); } } -QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { +QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile &indexed) { QueryFile::Def def; def.path = std::move(indexed.path); def.args = std::move(indexed.args); def.includes = std::move(indexed.includes); def.skipped_ranges = std::move(indexed.skipped_ranges); def.dependencies.reserve(indexed.dependencies.size()); - for (auto& dep : indexed.dependencies) + for (auto &dep : indexed.dependencies) def.dependencies.push_back(dep.first()); def.language = indexed.language; @@ -83,8 +83,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { def.outline.push_back(SymbolRef{{use.range, usr, kind, use.role}}); }; - for (auto& it : indexed.usr2type) { - const IndexType& type = it.second; + for (auto &it : indexed.usr2type) { + const IndexType &type = it.second; if (type.def.spell) add_all_symbols(*type.def.spell, type.usr, SymbolKind::Type); if (type.def.extent) @@ -100,8 +100,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { if (use.file_id == -1) add_all_symbols(use, type.usr, SymbolKind::Type); } - for (auto& it: indexed.usr2func) { - const IndexFunc& func = it.second; + for (auto &it : indexed.usr2func) { + const IndexFunc &func = it.second; if (func.def.spell) add_all_symbols(*func.def.spell, func.usr, SymbolKind::Func); if (func.def.extent) @@ -124,8 +124,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { add_all_symbols(use, func.usr, SymbolKind::Func); } } - for (auto& it : indexed.usr2var) { - const IndexVar& var = it.second; + for (auto &it : indexed.usr2var) { + const IndexVar &var = it.second; if (var.def.spell) add_all_symbols(*var.def.spell, var.usr, SymbolKind::Var); if (var.def.extent) @@ -140,11 +140,11 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { } std::sort(def.outline.begin(), def.outline.end(), - [](const SymbolRef& a, const SymbolRef& b) { + [](const SymbolRef &a, const SymbolRef &b) { return a.range.start < b.range.start; }); std::sort(def.all_symbols.begin(), def.all_symbols.end(), - [](const SymbolRef& a, const SymbolRef& b) { + [](const SymbolRef &a, const SymbolRef &b) { return a.range.start < b.range.start; }); @@ -153,8 +153,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) { // Returns true if an element with the same file is found. template -bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { - for (auto& def1 : def_list) +bool TryReplaceDef(llvm::SmallVectorImpl &def_list, Q &&def) { + for (auto &def1 : def_list) if (def1.file_id == def.file_id) { def1 = std::move(def); return true; @@ -162,10 +162,9 @@ bool TryReplaceDef(llvm::SmallVectorImpl& def_list, Q&& def) { return false; } -} // namespace +} // namespace -IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, - IndexFile* current) { +IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { IndexUpdate r; static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path, ""); @@ -177,16 +176,16 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.files_def_update = BuildFileDefUpdate(std::move(*current)); r.funcs_hint = current->usr2func.size() - previous->usr2func.size(); - for (auto& it : previous->usr2func) { - auto& func = it.second; + for (auto &it : previous->usr2func) { + auto &func = it.second; if (func.def.detailed_name[0]) r.funcs_removed.push_back(func.usr); r.funcs_declarations[func.usr].first = std::move(func.declarations); r.funcs_uses[func.usr].first = std::move(func.uses); r.funcs_derived[func.usr].first = std::move(func.derived); } - for (auto& it : current->usr2func) { - auto& func = it.second; + for (auto &it : current->usr2func) { + auto &func = it.second; if (func.def.detailed_name[0]) r.funcs_def_update.emplace_back(it.first, func.def); r.funcs_declarations[func.usr].second = std::move(func.declarations); @@ -195,8 +194,8 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, } r.types_hint = current->usr2type.size() - previous->usr2type.size(); - for (auto& it : previous->usr2type) { - auto& type = it.second; + for (auto &it : previous->usr2type) { + auto &type = it.second; if (type.def.detailed_name[0]) r.types_removed.push_back(type.usr); r.types_declarations[type.usr].first = std::move(type.declarations); @@ -204,8 +203,8 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, r.types_derived[type.usr].first = std::move(type.derived); r.types_instances[type.usr].first = std::move(type.instances); }; - for (auto& it : current->usr2type) { - auto& type = it.second; + for (auto &it : current->usr2type) { + auto &type = it.second; if (type.def.detailed_name[0]) r.types_def_update.emplace_back(it.first, type.def); r.types_declarations[type.usr].second = std::move(type.declarations); @@ -215,15 +214,15 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, }; r.vars_hint = current->usr2var.size() - previous->usr2var.size(); - for (auto& it : previous->usr2var) { - auto& var = it.second; + for (auto &it : previous->usr2var) { + auto &var = it.second; if (var.def.detailed_name[0]) r.vars_removed.push_back(var.usr); r.vars_declarations[var.usr].first = std::move(var.declarations); r.vars_uses[var.usr].first = std::move(var.uses); } - for (auto& it : current->usr2var) { - auto& var = it.second; + for (auto &it : current->usr2var) { + auto &var = it.second; if (var.def.detailed_name[0]) r.vars_def_update.emplace_back(it.first, var.def); r.vars_declarations[var.usr].second = std::move(var.declarations); @@ -233,51 +232,53 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, return r; } -void DB::RemoveUsrs(SymbolKind kind, - int file_id, - const std::vector& to_remove) { +void DB::RemoveUsrs(SymbolKind kind, int file_id, + const std::vector &to_remove) { switch (kind) { - case SymbolKind::Func: { - for (Usr usr : to_remove) { - // FIXME - if (!HasFunc(usr)) continue; - QueryFunc& func = Func(usr); - auto it = llvm::find_if(func.def, [=](const QueryFunc::Def& def) { - return def.file_id == file_id; - }); - if (it != func.def.end()) - func.def.erase(it); - } - break; + case SymbolKind::Func: { + for (Usr usr : to_remove) { + // FIXME + if (!HasFunc(usr)) + continue; + QueryFunc &func = Func(usr); + auto it = llvm::find_if(func.def, [=](const QueryFunc::Def &def) { + return def.file_id == file_id; + }); + if (it != func.def.end()) + func.def.erase(it); } - case SymbolKind::Type: { - for (Usr usr : to_remove) { - // FIXME - if (!HasType(usr)) continue; - QueryType& type = Type(usr); - auto it = llvm::find_if(type.def, [=](const QueryType::Def& def) { - return def.file_id == file_id; - }); - if (it != type.def.end()) - type.def.erase(it); - } - break; + break; + } + case SymbolKind::Type: { + for (Usr usr : to_remove) { + // FIXME + if (!HasType(usr)) + continue; + QueryType &type = Type(usr); + auto it = llvm::find_if(type.def, [=](const QueryType::Def &def) { + return def.file_id == file_id; + }); + if (it != type.def.end()) + type.def.erase(it); } - case SymbolKind::Var: { - for (Usr usr : to_remove) { - // FIXME - if (!HasVar(usr)) continue; - QueryVar& var = Var(usr); - auto it = llvm::find_if(var.def, [=](const QueryVar::Def& def) { - return def.file_id == file_id; - }); - if (it != var.def.end()) - var.def.erase(it); - } - break; + break; + } + case SymbolKind::Var: { + for (Usr usr : to_remove) { + // FIXME + if (!HasVar(usr)) + continue; + QueryVar &var = Var(usr); + auto it = llvm::find_if(var.def, [=](const QueryVar::Def &def) { + return def.file_id == file_id; + }); + if (it != var.def.end()) + var.def.erase(it); } - default: - break; + break; + } + default: + break; } } @@ -295,9 +296,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { } std::unordered_map prev_lid2file_id, lid2file_id; - for (auto & [ lid, path ] : u->prev_lid2path) + for (auto &[lid, path] : u->prev_lid2path) prev_lid2file_id[lid] = GetFileId(path); - for (auto & [ lid, path ] : u->lid2path) + for (auto &[lid, path] : u->lid2path) lid2file_id[lid] = GetFileId(path); auto UpdateUses = [&](Usr usr, SymbolKind kind, @@ -347,7 +348,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); - for (auto & [ usr, p ] : u->funcs_uses) + for (auto &[usr, p] : u->funcs_uses) UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p); if ((t = types.size() + u->types_hint) > types.capacity()) { @@ -360,7 +361,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); REMOVE_ADD(type, instances); - for (auto & [ usr, p ] : u->types_uses) + for (auto &[usr, p] : u->types_uses) UpdateUses(usr, SymbolKind::Type, type_usr, types, p); if ((t = vars.size() + u->vars_hint) > vars.capacity()) { @@ -371,13 +372,13 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); REMOVE_ADD(var, declarations); - for (auto & [ usr, p ] : u->vars_uses) + for (auto &[usr, p] : u->vars_uses) UpdateUses(usr, SymbolKind::Var, var_usr, vars, p); #undef REMOVE_ADD } -int DB::GetFileId(const std::string& path) { +int DB::GetFileId(const std::string &path) { auto it = name2file_id.try_emplace(LowerPathIfInsensitive(path)); if (it.second) { int id = files.size(); @@ -386,7 +387,7 @@ int DB::GetFileId(const std::string& path) { return it.first->second; } -int DB::Update(QueryFile::DefUpdate&& u) { +int DB::Update(QueryFile::DefUpdate &&u) { int file_id = GetFileId(u.first.path); files[file_id].def = u.first; return file_id; @@ -395,7 +396,7 @@ int DB::Update(QueryFile::DefUpdate&& u) { void DB::Update(const Lid2file_id &lid2file_id, int file_id, std::vector> &&us) { for (auto &u : us) { - auto& def = u.second; + auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); @@ -404,7 +405,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto R = func_usr.try_emplace({u.first}, func_usr.size()); if (R.second) funcs.emplace_back(); - QueryFunc& existing = funcs[R.first->second]; + QueryFunc &existing = funcs[R.first->second]; existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); @@ -414,7 +415,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, void DB::Update(const Lid2file_id &lid2file_id, int file_id, std::vector> &&us) { for (auto &u : us) { - auto& def = u.second; + auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); @@ -422,7 +423,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) types.emplace_back(); - QueryType& existing = types[R.first->second]; + QueryType &existing = types[R.first->second]; existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); @@ -432,7 +433,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, void DB::Update(const Lid2file_id &lid2file_id, int file_id, std::vector> &&us) { for (auto &u : us) { - auto& def = u.second; + auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; AssignFileId(lid2file_id, file_id, def.spell); @@ -440,7 +441,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) vars.emplace_back(); - QueryVar& existing = vars[R.first->second]; + QueryVar &existing = vars[R.first->second]; existing.usr = u.first; if (!TryReplaceDef(existing.def, std::move(def))) existing.def.push_back(std::move(def)); @@ -450,24 +451,24 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) { Usr usr = sym.usr; switch (sym.kind) { - default: - break; - case SymbolKind::File: - if (files[usr].def) - return files[usr].def->path; - break; - case SymbolKind::Func: - if (const auto* def = Func(usr).AnyDef()) - return def->Name(qualified); - break; - case SymbolKind::Type: - if (const auto* def = Type(usr).AnyDef()) - return def->Name(qualified); - break; - case SymbolKind::Var: - if (const auto* def = Var(usr).AnyDef()) - return def->Name(qualified); - break; + default: + break; + case SymbolKind::File: + if (files[usr].def) + return files[usr].def->path; + break; + case SymbolKind::Func: + if (const auto *def = Func(usr).AnyDef()) + return def->Name(qualified); + break; + case SymbolKind::Type: + if (const auto *def = Type(usr).AnyDef()) + return def->Name(qualified); + break; + case SymbolKind::Var: + if (const auto *def = Var(usr).AnyDef()) + return def->Name(qualified); + break; } return ""; } diff --git a/src/query.h b/src/query.h index 795ca13af..c7b694e7c 100644 --- a/src/query.h +++ b/src/query.h @@ -30,19 +30,20 @@ struct QueryFile { std::unordered_map symbol2refcnt; }; -template -struct QueryEntity { +template struct QueryEntity { using Def = QDef; - Def* AnyDef() { - Def* ret = nullptr; - for (auto& i : static_cast(this)->def) { + Def *AnyDef() { + Def *ret = nullptr; + for (auto &i : static_cast(this)->def) { ret = &i; if (i.spell) break; } return ret; } - const Def* AnyDef() const { return const_cast(this)->AnyDef(); } + const Def *AnyDef() const { + return const_cast(this)->AnyDef(); + } }; using UseUpdate = @@ -77,8 +78,7 @@ struct QueryVar : QueryEntity { struct IndexUpdate { // Creates a new IndexUpdate based on the delta from previous to current. If // no delta computation should be done just pass null for previous. - static IndexUpdate CreateDelta(IndexFile* previous, - IndexFile* current); + static IndexUpdate CreateDelta(IndexFile *previous, IndexFile *current); int file_id; @@ -120,8 +120,7 @@ struct IndexUpdate { struct WrappedUsr { Usr usr; }; -template <> -struct llvm::DenseMapInfo { +template <> struct llvm::DenseMapInfo { static inline WrappedUsr getEmptyKey() { return {0}; } static inline WrappedUsr getTombstoneKey() { return {~0ULL}; } static unsigned getHashValue(WrappedUsr w) { return w.usr; } @@ -140,11 +139,12 @@ struct DB { std::vector types; std::vector vars; - void RemoveUsrs(SymbolKind kind, int file_id, const std::vector& to_remove); + void RemoveUsrs(SymbolKind kind, int file_id, + const std::vector &to_remove); // Insert the contents of |update| into |db|. - void ApplyIndexUpdate(IndexUpdate* update); - int GetFileId(const std::string& path); - int Update(QueryFile::DefUpdate&& u); + void ApplyIndexUpdate(IndexUpdate *update); + int GetFileId(const std::string &path); + int Update(QueryFile::DefUpdate &&u); void Update(const Lid2file_id &, int file_id, std::vector> &&us); void Update(const Lid2file_id &, int file_id, @@ -157,12 +157,12 @@ struct DB { bool HasType(Usr usr) const { return type_usr.count({usr}); } bool HasVar(Usr usr) const { return var_usr.count({usr}); } - QueryFunc& Func(Usr usr) { return funcs[func_usr[{usr}]]; } - QueryType& Type(Usr usr) { return types[type_usr[{usr}]]; } - QueryVar& Var(Usr usr) { return vars[var_usr[{usr}]]; } + QueryFunc &Func(Usr usr) { return funcs[func_usr[{usr}]]; } + QueryType &Type(Usr usr) { return types[type_usr[{usr}]]; } + QueryVar &Var(Usr usr) { return vars[var_usr[{usr}]]; } - QueryFile& GetFile(SymbolIdx ref) { return files[ref.usr]; } - QueryFunc& GetFunc(SymbolIdx ref) { return Func(ref.usr); } - QueryType& GetType(SymbolIdx ref) { return Type(ref.usr); } - QueryVar& GetVar(SymbolIdx ref) { return Var(ref.usr); } + QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; } + QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); } + QueryType &GetType(SymbolIdx ref) { return Type(ref.usr); } + QueryVar &GetVar(SymbolIdx ref) { return Var(ref.usr); } }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 0a61ffd2a..e5a4887af 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -8,22 +8,22 @@ namespace { // Computes roughly how long |range| is. -int ComputeRangeSize(const Range& range) { +int ComputeRangeSize(const Range &range) { if (range.start.line != range.end.line) return INT_MAX; return range.end.column - range.start.column; } template -std::vector GetDeclarations(llvm::DenseMap& entity_usr, - std::vector& entities, - const std::vector& usrs) { +std::vector GetDeclarations(llvm::DenseMap &entity_usr, + std::vector &entities, + const std::vector &usrs) { std::vector ret; ret.reserve(usrs.size()); for (Usr usr : usrs) { - Q& entity = entities[entity_usr[{usr}]]; + Q &entity = entities[entity_usr[{usr}]]; bool has_def = false; - for (auto& def : entity.def) + for (auto &def : entity.def) if (def.spell) { ret.push_back(*def.spell); has_def = true; @@ -35,39 +35,38 @@ std::vector GetDeclarations(llvm::DenseMap& entity_usr, return ret; } -} // namespace +} // namespace -Maybe GetDefinitionSpell(DB* db, SymbolIdx sym) { +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { Maybe ret; - EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.spell); }); + EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); return ret; } -Maybe GetDefinitionExtent(DB* db, SymbolIdx sym) { +Maybe GetDefinitionExtent(DB *db, SymbolIdx sym) { // Used to jump to file. if (sym.kind == SymbolKind::File) return Use{{Range{{0, 0}, {0, 0}}, sym.usr, sym.kind, Role::None}, int(sym.usr)}; Maybe ret; - EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.extent); }); + EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); }); return ret; } -std::vector GetFuncDeclarations(DB* db, const std::vector& usrs) { +std::vector GetFuncDeclarations(DB *db, const std::vector &usrs) { return GetDeclarations(db->func_usr, db->funcs, usrs); } -std::vector GetTypeDeclarations(DB* db, const std::vector& usrs) { +std::vector GetTypeDeclarations(DB *db, const std::vector &usrs) { return GetDeclarations(db->type_usr, db->types, usrs); } -std::vector GetVarDeclarations(DB* db, - const std::vector& usrs, +std::vector GetVarDeclarations(DB *db, const std::vector &usrs, unsigned kind) { std::vector ret; ret.reserve(usrs.size()); for (Usr usr : usrs) { - QueryVar& var = db->Var(usr); + QueryVar &var = db->Var(usr); bool has_def = false; - for (auto& def : var.def) + for (auto &def : var.def) if (def.spell) { has_def = true; // See messages/ccls_vars.cc @@ -90,29 +89,29 @@ std::vector GetVarDeclarations(DB* db, return ret; } -std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym) { +std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym) { switch (sym.kind) { - case SymbolKind::Func: - return db->GetFunc(sym).declarations; - case SymbolKind::Type: - return db->GetType(sym).declarations; - case SymbolKind::Var: - return db->GetVar(sym).declarations; - default: - return {}; + case SymbolKind::Func: + return db->GetFunc(sym).declarations; + case SymbolKind::Type: + return db->GetType(sym).declarations; + case SymbolKind::Var: + return db->GetVar(sym).declarations; + default: + return {}; } } -std::vector GetUsesForAllBases(DB* db, QueryFunc& root) { +std::vector GetUsesForAllBases(DB *db, QueryFunc &root) { std::vector ret; - std::vector stack{&root}; + std::vector stack{&root}; std::unordered_set seen; seen.insert(root.usr); while (!stack.empty()) { - QueryFunc& func = *stack.back(); + QueryFunc &func = *stack.back(); stack.pop_back(); - if (auto* def = func.AnyDef()) { - EachDefinedFunc(db, def->bases, [&](QueryFunc& func1) { + if (auto *def = func.AnyDef()) { + EachDefinedFunc(db, def->bases, [&](QueryFunc &func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -125,15 +124,15 @@ std::vector GetUsesForAllBases(DB* db, QueryFunc& root) { return ret; } -std::vector GetUsesForAllDerived(DB* db, QueryFunc& root) { +std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { std::vector ret; - std::vector stack{&root}; + std::vector stack{&root}; std::unordered_set seen; seen.insert(root.usr); while (!stack.empty()) { - QueryFunc& func = *stack.back(); + QueryFunc &func = *stack.back(); stack.pop_back(); - EachDefinedFunc(db, func.derived, [&](QueryFunc& func1) { + EachDefinedFunc(db, func.derived, [&](QueryFunc &func1) { if (!seen.count(func1.usr)) { seen.insert(func1.usr); stack.push_back(&func1); @@ -145,8 +144,8 @@ std::vector GetUsesForAllDerived(DB* db, QueryFunc& root) { return ret; } -std::optional GetLsPosition(WorkingFile* working_file, - const Position& position) { +std::optional GetLsPosition(WorkingFile *working_file, + const Position &position) { if (!working_file) return lsPosition{position.line, position.column}; @@ -157,8 +156,8 @@ std::optional GetLsPosition(WorkingFile* working_file, return std::nullopt; } -std::optional GetLsRange(WorkingFile* working_file, - const Range& location) { +std::optional GetLsRange(WorkingFile *working_file, + const Range &location) { if (!working_file) { return lsRange{lsPosition{location.start.line, location.start.column}, lsPosition{location.end.line, location.end.column}}; @@ -187,8 +186,8 @@ std::optional GetLsRange(WorkingFile* working_file, lsPosition{*end, end_column}}; } -lsDocumentUri GetLsDocumentUri(DB* db, int file_id, std::string* path) { - QueryFile& file = db->files[file_id]; +lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { + QueryFile &file = db->files[file_id]; if (file.def) { *path = file.def->path; return lsDocumentUri::FromPath(*path); @@ -198,8 +197,8 @@ lsDocumentUri GetLsDocumentUri(DB* db, int file_id, std::string* path) { } } -lsDocumentUri GetLsDocumentUri(DB* db, int file_id) { - QueryFile& file = db->files[file_id]; +lsDocumentUri GetLsDocumentUri(DB *db, int file_id) { + QueryFile &file = db->files[file_id]; if (file.def) { return lsDocumentUri::FromPath(file.def->path); } else { @@ -207,8 +206,7 @@ lsDocumentUri GetLsDocumentUri(DB* db, int file_id) { } } -std::optional GetLsLocation(DB* db, - WorkingFiles* working_files, +std::optional GetLsLocation(DB *db, WorkingFiles *working_files, Use use) { std::string path; lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); @@ -219,10 +217,8 @@ std::optional GetLsLocation(DB* db, return lsLocation{uri, *range}; } -std::optional GetLsLocationEx(DB* db, - WorkingFiles* working_files, - Use use, - bool container) { +std::optional GetLsLocationEx(DB *db, WorkingFiles *working_files, + Use use, bool container) { std::optional ls_loc = GetLsLocation(db, working_files, use); if (!ls_loc) return std::nullopt; @@ -230,7 +226,7 @@ std::optional GetLsLocationEx(DB* db, ret.lsLocation::operator=(*ls_loc); if (container) { ret.role = uint16_t(use.role); - EachEntityDef(db, use, [&](const auto& def) { + EachEntityDef(db, use, [&](const auto &def) { ret.containerName = std::string_view(def.detailed_name); return false; }); @@ -238,9 +234,8 @@ std::optional GetLsLocationEx(DB* db, return ret; } -std::vector GetLsLocationExs(DB* db, - WorkingFiles* working_files, - const std::vector& uses) { +std::vector GetLsLocationExs(DB *db, WorkingFiles *working_files, + const std::vector &uses) { std::vector ret; for (Use use : uses) if (auto loc = @@ -253,14 +248,14 @@ std::vector GetLsLocationExs(DB* db, return ret; } -lsSymbolKind GetSymbolKind(DB* db, SymbolIdx sym) { +lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { lsSymbolKind ret; if (sym.kind == SymbolKind::File) ret = lsSymbolKind::File; else { ret = lsSymbolKind::Unknown; - WithEntity(db, sym, [&](const auto& entity) { - for (auto& def : entity.def) { + WithEntity(db, sym, [&](const auto &entity) { + for (auto &def : entity.def) { ret = def.kind; break; } @@ -270,44 +265,44 @@ lsSymbolKind GetSymbolKind(DB* db, SymbolIdx sym) { } // Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(DB* db, - WorkingFiles* working_files, +std::optional GetSymbolInfo(DB *db, + WorkingFiles *working_files, SymbolIdx sym, bool detailed_name) { switch (sym.kind) { - case SymbolKind::Invalid: + case SymbolKind::Invalid: + break; + case SymbolKind::File: { + QueryFile &file = db->GetFile(sym); + if (!file.def) break; - case SymbolKind::File: { - QueryFile& file = db->GetFile(sym); - if (!file.def) - break; - lsSymbolInformation info; - info.name = file.def->path; - info.kind = lsSymbolKind::File; - return info; - } - default: { - lsSymbolInformation info; - EachEntityDef(db, sym, [&](const auto& def) { - if (detailed_name) - info.name = def.detailed_name; - else - info.name = def.Name(true); - info.kind = def.kind; - info.containerName = def.detailed_name; - return false; - }); - return info; - } + lsSymbolInformation info; + info.name = file.def->path; + info.kind = lsSymbolKind::File; + return info; + } + default: { + lsSymbolInformation info; + EachEntityDef(db, sym, [&](const auto &def) { + if (detailed_name) + info.name = def.detailed_name; + else + info.name = def.Name(true); + info.kind = def.kind; + info.containerName = def.detailed_name; + return false; + }); + return info; + } } return std::nullopt; } -std::vector FindSymbolsAtLocation(WorkingFile* working_file, - QueryFile* file, - lsPosition& ls_pos) { +std::vector FindSymbolsAtLocation(WorkingFile *working_file, + QueryFile *file, + lsPosition &ls_pos) { std::vector symbols; if (working_file) { if (auto line = working_file->GetIndexPosFromBufferPos( @@ -322,7 +317,7 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, for (SymbolRef sym : file->def->all_symbols) if (sym.range.Contains(ls_pos.line, ls_pos.character)) symbols.push_back(sym); - for (auto[sym, refcnt] : file->symbol2refcnt) + for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && sym.range.Contains(ls_pos.line, ls_pos.character)) symbols.push_back(sym); @@ -337,22 +332,23 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, // // Then order functions before other types, which makes goto definition work // better on constructors. - std::sort(symbols.begin(), symbols.end(), - [](const SymbolRef& a, const SymbolRef& b) { - int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); - if (t) - return t < 0; - // MacroExpansion - if ((t = (a.role & Role::Dynamic) - (b.role & Role::Dynamic))) - return t > 0; - if ((t = (a.role & Role::Definition) - (b.role & Role::Definition))) - return t > 0; - // operator> orders Var/Func before Type. - t = static_cast(a.kind) - static_cast(b.kind); - if (t) - return t > 0; - return a.usr < b.usr; - }); + std::sort( + symbols.begin(), symbols.end(), + [](const SymbolRef &a, const SymbolRef &b) { + int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); + if (t) + return t < 0; + // MacroExpansion + if ((t = (a.role & Role::Dynamic) - (b.role & Role::Dynamic))) + return t > 0; + if ((t = (a.role & Role::Definition) - (b.role & Role::Definition))) + return t > 0; + // operator> orders Var/Func before Type. + t = static_cast(a.kind) - static_cast(b.kind); + if (t) + return t > 0; + return a.usr < b.usr; + }); return symbols; } diff --git a/src/query_utils.h b/src/query_utils.h index 523970000..884085ae6 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -5,81 +5,75 @@ #include -Maybe GetDefinitionSpell(DB* db, SymbolIdx sym); -Maybe GetDefinitionExtent(DB* db, SymbolIdx sym); +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); +Maybe GetDefinitionExtent(DB *db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. -std::vector GetFuncDeclarations(DB*, const std::vector&); -std::vector GetTypeDeclarations(DB*, const std::vector&); -std::vector GetVarDeclarations(DB*, const std::vector&, unsigned); +std::vector GetFuncDeclarations(DB *, const std::vector &); +std::vector GetTypeDeclarations(DB *, const std::vector &); +std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); // Get non-defining declarations. -std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym); - -std::vector GetUsesForAllBases(DB* db, QueryFunc& root); -std::vector GetUsesForAllDerived(DB* db, QueryFunc& root); -std::optional GetLsPosition(WorkingFile* working_file, - const Position& position); -std::optional GetLsRange(WorkingFile* working_file, - const Range& location); -lsDocumentUri GetLsDocumentUri(DB* db, int file_id, std::string* path); -lsDocumentUri GetLsDocumentUri(DB* db, int file_id); - -std::optional GetLsLocation(DB* db, - WorkingFiles* working_files, +std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym); + +std::vector GetUsesForAllBases(DB *db, QueryFunc &root); +std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); +std::optional GetLsPosition(WorkingFile *working_file, + const Position &position); +std::optional GetLsRange(WorkingFile *working_file, + const Range &location); +lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); +lsDocumentUri GetLsDocumentUri(DB *db, int file_id); + +std::optional GetLsLocation(DB *db, WorkingFiles *working_files, Use use); -std::optional GetLsLocationEx(DB* db, - WorkingFiles* working_files, - Use use, - bool container); -std::vector GetLsLocationExs(DB* db, - WorkingFiles* working_files, - const std::vector& refs); +std::optional GetLsLocationEx(DB *db, WorkingFiles *working_files, + Use use, bool container); +std::vector GetLsLocationExs(DB *db, WorkingFiles *working_files, + const std::vector &refs); // Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(DB* db, - WorkingFiles* working_files, +std::optional GetSymbolInfo(DB *db, + WorkingFiles *working_files, SymbolIdx sym, bool detailed_name); -std::vector FindSymbolsAtLocation(WorkingFile* working_file, - QueryFile* file, - lsPosition& ls_pos); +std::vector FindSymbolsAtLocation(WorkingFile *working_file, + QueryFile *file, + lsPosition &ls_pos); -template -void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) { +template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { switch (sym.kind) { - case SymbolKind::Invalid: - case SymbolKind::File: - break; - case SymbolKind::Func: - fn(db->GetFunc(sym)); - break; - case SymbolKind::Type: - fn(db->GetType(sym)); - break; - case SymbolKind::Var: - fn(db->GetVar(sym)); - break; + case SymbolKind::Invalid: + case SymbolKind::File: + break; + case SymbolKind::Func: + fn(db->GetFunc(sym)); + break; + case SymbolKind::Type: + fn(db->GetType(sym)); + break; + case SymbolKind::Var: + fn(db->GetVar(sym)); + break; } } -template -void EachEntityDef(DB* db, SymbolIdx sym, Fn&& fn) { - WithEntity(db, sym, [&](const auto& entity) { - for (auto& def : entity.def) +template void EachEntityDef(DB *db, SymbolIdx sym, Fn &&fn) { + WithEntity(db, sym, [&](const auto &entity) { + for (auto &def : entity.def) if (!fn(def)) break; }); } template -void EachOccurrence(DB* db, SymbolIdx sym, bool include_decl, Fn&& fn) { - WithEntity(db, sym, [&](const auto& entity) { +void EachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) { + WithEntity(db, sym, [&](const auto &entity) { for (Use use : entity.uses) fn(use); if (include_decl) { - for (auto& def : entity.def) + for (auto &def : entity.def) if (def.spell) fn(*def.spell); for (Use use : entity.declarations) @@ -88,31 +82,30 @@ void EachOccurrence(DB* db, SymbolIdx sym, bool include_decl, Fn&& fn) { }); } -lsSymbolKind GetSymbolKind(DB* db, SymbolIdx sym); +lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym); template -void EachDefinedFunc(DB* db, const std::vector& usrs, Fn&& fn) { +void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { for (Usr usr : usrs) { - auto& obj = db->Func(usr); + auto &obj = db->Func(usr); if (!obj.def.empty()) fn(obj); } } - template -void EachDefinedType(DB* db, const std::vector& usrs, Fn&& fn) { +void EachDefinedType(DB *db, const std::vector &usrs, Fn &&fn) { for (Usr usr : usrs) { - auto& obj = db->Type(usr); + auto &obj = db->Type(usr); if (!obj.def.empty()) fn(obj); } } template -void EachDefinedVar(DB* db, const std::vector& usrs, Fn&& fn) { +void EachDefinedVar(DB *db, const std::vector &usrs, Fn &&fn) { for (Usr usr : usrs) { - auto& obj = db->Var(usr); + auto &obj = db->Var(usr); if (!obj.def.empty()) fn(obj); } diff --git a/src/serializer.cc b/src/serializer.cc index ba6086f48..9ab01f06f 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -18,143 +18,115 @@ bool gTestOutputMode = false; //// Elementary types -void Reflect(Reader& visitor, uint8_t& value) { - value = visitor.GetUInt8(); -} -void Reflect(Writer& visitor, uint8_t& value) { - visitor.UInt8(value); -} +void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); } +void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); } -void Reflect(Reader& visitor, short& value) { +void Reflect(Reader &visitor, short &value) { if (!visitor.IsInt()) throw std::invalid_argument("short"); value = (short)visitor.GetInt(); } -void Reflect(Writer& visitor, short& value) { - visitor.Int(value); -} +void Reflect(Writer &visitor, short &value) { visitor.Int(value); } -void Reflect(Reader& visitor, unsigned short& value) { +void Reflect(Reader &visitor, unsigned short &value) { if (!visitor.IsInt()) throw std::invalid_argument("unsigned short"); value = (unsigned short)visitor.GetInt(); } -void Reflect(Writer& visitor, unsigned short& value) { - visitor.Int(value); -} +void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); } -void Reflect(Reader& visitor, int& value) { +void Reflect(Reader &visitor, int &value) { if (!visitor.IsInt()) throw std::invalid_argument("int"); value = visitor.GetInt(); } -void Reflect(Writer& visitor, int& value) { - visitor.Int(value); -} +void Reflect(Writer &visitor, int &value) { visitor.Int(value); } -void Reflect(Reader& visitor, unsigned& value) { +void Reflect(Reader &visitor, unsigned &value) { if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned"); value = visitor.GetUInt32(); } -void Reflect(Writer& visitor, unsigned& value) { - visitor.UInt32(value); -} +void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); } -void Reflect(Reader& visitor, long& value) { +void Reflect(Reader &visitor, long &value) { if (!visitor.IsInt64()) throw std::invalid_argument("long"); value = long(visitor.GetInt64()); } -void Reflect(Writer& visitor, long& value) { - visitor.Int64(value); -} +void Reflect(Writer &visitor, long &value) { visitor.Int64(value); } -void Reflect(Reader& visitor, unsigned long& value) { +void Reflect(Reader &visitor, unsigned long &value) { if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned long"); value = (unsigned long)visitor.GetUInt64(); } -void Reflect(Writer& visitor, unsigned long& value) { - visitor.UInt64(value); -} +void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); } -void Reflect(Reader& visitor, long long& value) { +void Reflect(Reader &visitor, long long &value) { if (!visitor.IsInt64()) throw std::invalid_argument("long long"); value = visitor.GetInt64(); } -void Reflect(Writer& visitor, long long& value) { - visitor.Int64(value); -} +void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); } -void Reflect(Reader& visitor, unsigned long long& value) { +void Reflect(Reader &visitor, unsigned long long &value) { if (!visitor.IsUInt64()) throw std::invalid_argument("unsigned long long"); value = visitor.GetUInt64(); } -void Reflect(Writer& visitor, unsigned long long& value) { +void Reflect(Writer &visitor, unsigned long long &value) { visitor.UInt64(value); } -void Reflect(Reader& visitor, double& value) { +void Reflect(Reader &visitor, double &value) { if (!visitor.IsDouble()) throw std::invalid_argument("double"); value = visitor.GetDouble(); } -void Reflect(Writer& visitor, double& value) { - visitor.Double(value); -} +void Reflect(Writer &visitor, double &value) { visitor.Double(value); } -void Reflect(Reader& visitor, bool& value) { +void Reflect(Reader &visitor, bool &value) { if (!visitor.IsBool()) throw std::invalid_argument("bool"); value = visitor.GetBool(); } -void Reflect(Writer& visitor, bool& value) { - visitor.Bool(value); -} +void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); } -void Reflect(Reader& visitor, std::string& value) { +void Reflect(Reader &visitor, std::string &value) { if (!visitor.IsString()) throw std::invalid_argument("std::string"); value = visitor.GetString(); } -void Reflect(Writer& visitor, std::string& value) { +void Reflect(Writer &visitor, std::string &value) { visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); } -void Reflect(Reader&, std::string_view&) { - assert(0); -} -void Reflect(Writer& visitor, std::string_view& data) { +void Reflect(Reader &, std::string_view &) { assert(0); } +void Reflect(Writer &visitor, std::string_view &data) { if (data.empty()) visitor.String(""); else visitor.String(&data[0], (rapidjson::SizeType)data.size()); } -void Reflect(Reader& vis, const char*& v) { - const char* str = vis.GetString(); +void Reflect(Reader &vis, const char *&v) { + const char *str = vis.GetString(); v = ccls::Intern(str); } -void Reflect(Writer& vis, const char*& v) { - vis.String(v); -} +void Reflect(Writer &vis, const char *&v) { vis.String(v); } -void Reflect(Reader& visitor, JsonNull& value) { +void Reflect(Reader &visitor, JsonNull &value) { assert(visitor.Format() == SerializeFormat::Json); visitor.GetNull(); } -void Reflect(Writer& visitor, JsonNull& value) { - visitor.Null(); -} +void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); } // std::unordered_map template -void Reflect(Reader& visitor, std::unordered_map& map) { - visitor.IterArray([&](Reader& entry) { +void Reflect(Reader &visitor, std::unordered_map &map) { + visitor.IterArray([&](Reader &entry) { V val; Reflect(entry, val); auto usr = val.usr; @@ -162,20 +134,20 @@ void Reflect(Reader& visitor, std::unordered_map& map) { }); } template -void Reflect(Writer& visitor, std::unordered_map& map) { +void Reflect(Writer &visitor, std::unordered_map &map) { std::vector> xs(map.begin(), map.end()); std::sort(xs.begin(), xs.end(), - [](const auto& a, const auto& b) { return a.first < b.first; }); + [](const auto &a, const auto &b) { return a.first < b.first; }); visitor.StartArray(xs.size()); - for (auto& it : xs) + for (auto &it : xs) Reflect(visitor, it.second); visitor.EndArray(); } // Used by IndexFile::dependencies. Timestamps are emitted for Binary. -void Reflect(Reader& visitor, StringMap& map) { - visitor.IterArray([&](Reader& entry) { - std::string name; +void Reflect(Reader &visitor, StringMap &map) { + visitor.IterArray([&](Reader &entry) { + std::string name; Reflect(entry, name); if (visitor.Format() == SerializeFormat::Binary) Reflect(entry, map[name]); @@ -183,9 +155,9 @@ void Reflect(Reader& visitor, StringMap& map) { map[name] = 0; }); } -void Reflect(Writer& visitor, StringMap& map) { +void Reflect(Writer &visitor, StringMap &map) { visitor.StartArray(map.size()); - for (auto& it : map) { + for (auto &it : map) { std::string key = it.first(); Reflect(visitor, key); if (visitor.Format() == SerializeFormat::Binary) @@ -195,13 +167,13 @@ void Reflect(Writer& visitor, StringMap& map) { } // TODO: Move this to indexer.cc -void Reflect(Reader& visitor, IndexInclude& value) { +void Reflect(Reader &visitor, IndexInclude &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); REFLECT_MEMBER(resolved_path); REFLECT_MEMBER_END(); } -void Reflect(Writer& visitor, IndexInclude& value) { +void Reflect(Writer &visitor, IndexInclude &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); if (gTestOutputMode) { @@ -216,13 +188,13 @@ void Reflect(Writer& visitor, IndexInclude& value) { } template -void ReflectHoverAndComments(Reader& visitor, Def& def) { +void ReflectHoverAndComments(Reader &visitor, Def &def) { ReflectMember(visitor, "hover", def.hover); ReflectMember(visitor, "comments", def.comments); } template -void ReflectHoverAndComments(Writer& visitor, Def& def) { +void ReflectHoverAndComments(Writer &visitor, Def &def) { // Don't emit empty hover and comments in JSON test mode. if (!gTestOutputMode || def.hover[0]) ReflectMember(visitor, "hover", def.hover); @@ -230,12 +202,12 @@ void ReflectHoverAndComments(Writer& visitor, Def& def) { ReflectMember(visitor, "comments", def.comments); } -template -void ReflectShortName(Reader& visitor, Def& def) { +template void ReflectShortName(Reader &visitor, Def &def) { if (gTestOutputMode) { std::string short_name; ReflectMember(visitor, "short_name", short_name); - def.short_name_offset = std::string_view(def.detailed_name).find(short_name); + def.short_name_offset = + std::string_view(def.detailed_name).find(short_name); assert(def.short_name_offset != std::string::npos); def.short_name_size = short_name.size(); } else { @@ -244,8 +216,7 @@ void ReflectShortName(Reader& visitor, Def& def) { } } -template -void ReflectShortName(Writer& visitor, Def& def) { +template void ReflectShortName(Writer &visitor, Def &def) { if (gTestOutputMode) { std::string_view short_name(def.detailed_name + def.short_name_offset, def.short_name_size); @@ -256,8 +227,7 @@ void ReflectShortName(Writer& visitor, Def& def) { } } -template -void Reflect(TVisitor& visitor, IndexType& value) { +template void Reflect(TVisitor &visitor, IndexType &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); @@ -279,8 +249,7 @@ void Reflect(TVisitor& visitor, IndexType& value) { REFLECT_MEMBER_END(); } -template -void Reflect(TVisitor& visitor, IndexFunc& value) { +template void Reflect(TVisitor &visitor, IndexFunc &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); @@ -300,8 +269,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER_END(); } -template -void Reflect(TVisitor& visitor, IndexVar& value) { +template void Reflect(TVisitor &visitor, IndexVar &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); @@ -319,12 +287,11 @@ void Reflect(TVisitor& visitor, IndexVar& value) { } // IndexFile -bool ReflectMemberStart(Writer& visitor, IndexFile& value) { +bool ReflectMemberStart(Writer &visitor, IndexFile &value) { visitor.StartObject(); return true; } -template -void Reflect(TVisitor& visitor, IndexFile& value) { +template void Reflect(TVisitor &visitor, IndexFile &value) { REFLECT_MEMBER_START(); if (!gTestOutputMode) { REFLECT_MEMBER(last_write_time); @@ -342,19 +309,19 @@ void Reflect(TVisitor& visitor, IndexFile& value) { REFLECT_MEMBER_END(); } -void Reflect(Reader& visitor, SerializeFormat& value) { +void Reflect(Reader &visitor, SerializeFormat &value) { std::string fmt = visitor.GetString(); value = fmt[0] == 'b' ? SerializeFormat::Binary : SerializeFormat::Json; } -void Reflect(Writer& visitor, SerializeFormat& value) { +void Reflect(Writer &visitor, SerializeFormat &value) { switch (value) { - case SerializeFormat::Binary: - visitor.String("binary"); - break; - case SerializeFormat::Json: - visitor.String("json"); - break; + case SerializeFormat::Binary: + visitor.String("binary"); + break; + case SerializeFormat::Json: + visitor.String("json"); + break; } } @@ -363,8 +330,9 @@ static BumpPtrAllocator Alloc; static DenseSet Strings; static std::mutex AllocMutex; -const char* Intern(const std::string& str) { - if (str.empty()) return ""; +const char *Intern(const std::string &str) { + if (str.empty()) + return ""; StringRef Str(str.data(), str.size() + 1); std::lock_guard lock(AllocMutex); auto R = Strings.insert(Str); @@ -373,100 +341,98 @@ const char* Intern(const std::string& str) { return R.first->data(); } -std::string Serialize(SerializeFormat format, IndexFile& file) { +std::string Serialize(SerializeFormat format, IndexFile &file) { switch (format) { - case SerializeFormat::Binary: { - BinaryWriter writer; - int major = IndexFile::kMajorVersion; - int minor = IndexFile::kMinorVersion; - Reflect(writer, major); - Reflect(writer, minor); - Reflect(writer, file); - return writer.Take(); - } - case SerializeFormat::Json: { - rapidjson::StringBuffer output; - rapidjson::PrettyWriter writer(output); - writer.SetFormatOptions( - rapidjson::PrettyFormatOptions::kFormatSingleLineArray); - writer.SetIndent(' ', 2); - JsonWriter json_writer(&writer); - if (!gTestOutputMode) { - std::string version = std::to_string(IndexFile::kMajorVersion); - for (char c : version) - output.Put(c); - output.Put('\n'); - } - Reflect(json_writer, file); - return output.GetString(); + case SerializeFormat::Binary: { + BinaryWriter writer; + int major = IndexFile::kMajorVersion; + int minor = IndexFile::kMinorVersion; + Reflect(writer, major); + Reflect(writer, minor); + Reflect(writer, file); + return writer.Take(); + } + case SerializeFormat::Json: { + rapidjson::StringBuffer output; + rapidjson::PrettyWriter writer(output); + writer.SetFormatOptions( + rapidjson::PrettyFormatOptions::kFormatSingleLineArray); + writer.SetIndent(' ', 2); + JsonWriter json_writer(&writer); + if (!gTestOutputMode) { + std::string version = std::to_string(IndexFile::kMajorVersion); + for (char c : version) + output.Put(c); + output.Put('\n'); } + Reflect(json_writer, file); + return output.GetString(); + } } return ""; } -std::unique_ptr Deserialize( - SerializeFormat format, - const std::string& path, - const std::string& serialized_index_content, - const std::string& file_content, - std::optional expected_version) { +std::unique_ptr +Deserialize(SerializeFormat format, const std::string &path, + const std::string &serialized_index_content, + const std::string &file_content, + std::optional expected_version) { if (serialized_index_content.empty()) return nullptr; std::unique_ptr file; switch (format) { - case SerializeFormat::Binary: { - try { - int major, minor; - if (serialized_index_content.size() < 8) - throw std::invalid_argument("Invalid"); - BinaryReader reader(serialized_index_content); - Reflect(reader, major); - Reflect(reader, minor); - if (major != IndexFile::kMajorVersion || - minor != IndexFile::kMinorVersion) - throw std::invalid_argument("Invalid version"); - file = std::make_unique(sys::fs::UniqueID(0, 0), path, - file_content); - Reflect(reader, *file); - } catch (std::invalid_argument& e) { - LOG_S(INFO) << "failed to deserialize '" << path - << "': " << e.what(); - return nullptr; - } - break; - } - case SerializeFormat::Json: { - rapidjson::Document reader; - if (gTestOutputMode || !expected_version) { - reader.Parse(serialized_index_content.c_str()); - } else { - const char* p = strchr(serialized_index_content.c_str(), '\n'); - if (!p) - return nullptr; - if (atoi(serialized_index_content.c_str()) != *expected_version) - return nullptr; - reader.Parse(p + 1); - } - if (reader.HasParseError()) - return nullptr; - + case SerializeFormat::Binary: { + try { + int major, minor; + if (serialized_index_content.size() < 8) + throw std::invalid_argument("Invalid"); + BinaryReader reader(serialized_index_content); + Reflect(reader, major); + Reflect(reader, minor); + if (major != IndexFile::kMajorVersion || + minor != IndexFile::kMinorVersion) + throw std::invalid_argument("Invalid version"); file = std::make_unique(sys::fs::UniqueID(0, 0), path, file_content); - JsonReader json_reader{&reader}; - try { - Reflect(json_reader, *file); - } catch (std::invalid_argument& e) { - LOG_S(INFO) << "'" << path << "': failed to deserialize " - << json_reader.GetPath() << "." << e.what(); + Reflect(reader, *file); + } catch (std::invalid_argument &e) { + LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what(); + return nullptr; + } + break; + } + case SerializeFormat::Json: { + rapidjson::Document reader; + if (gTestOutputMode || !expected_version) { + reader.Parse(serialized_index_content.c_str()); + } else { + const char *p = strchr(serialized_index_content.c_str(), '\n'); + if (!p) + return nullptr; + if (atoi(serialized_index_content.c_str()) != *expected_version) return nullptr; - } - break; + reader.Parse(p + 1); } + if (reader.HasParseError()) + return nullptr; + + file = std::make_unique(sys::fs::UniqueID(0, 0), path, + file_content); + JsonReader json_reader{&reader}; + try { + Reflect(json_reader, *file); + } catch (std::invalid_argument &e) { + LOG_S(INFO) << "'" << path << "': failed to deserialize " + << json_reader.GetPath() << "." << e.what(); + return nullptr; + } + break; + } } // Restore non-serialized state. file->path = path; return file; } -} +} // namespace ccls diff --git a/src/serializer.h b/src/serializer.h index 1bbbc3579..78eebd407 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -21,7 +21,7 @@ struct JsonNull {}; struct mandatory_optional_tag {}; class Reader { - public: +public: virtual ~Reader() {} virtual SerializeFormat Format() const = 0; @@ -41,17 +41,17 @@ class Reader { virtual int64_t GetInt64() = 0; virtual uint64_t GetUInt64() = 0; virtual double GetDouble() = 0; - virtual const char* GetString() = 0; + virtual const char *GetString() = 0; - virtual bool HasMember(const char* x) = 0; - virtual std::unique_ptr operator[](const char* x) = 0; + virtual bool HasMember(const char *x) = 0; + virtual std::unique_ptr operator[](const char *x) = 0; - virtual void IterArray(std::function fn) = 0; - virtual void Member(const char* name, std::function fn) = 0; + virtual void IterArray(std::function fn) = 0; + virtual void Member(const char *name, std::function fn) = 0; }; class Writer { - public: +public: virtual ~Writer() {} virtual SerializeFormat Format() const = 0; @@ -63,13 +63,13 @@ class Writer { virtual void UInt32(uint32_t x) = 0; virtual void UInt64(uint64_t x) = 0; virtual void Double(double x) = 0; - virtual void String(const char* x) = 0; - virtual void String(const char* x, size_t len) = 0; + virtual void String(const char *x) = 0; + virtual void String(const char *x, size_t len) = 0; virtual void StartArray(size_t) = 0; virtual void EndArray() = 0; virtual void StartObject() = 0; virtual void EndObject() = 0; - virtual void Key(const char* name) = 0; + virtual void Key(const char *name) = 0; }; struct IndexFile; @@ -77,48 +77,45 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) -#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ +#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) -#define MAKE_REFLECT_TYPE_PROXY(type_name) \ +#define MAKE_REFLECT_TYPE_PROXY(type_name) \ MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) -#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ - as_type value0; \ - ::Reflect(visitor, value0); \ - value = static_cast(value0); \ - } \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer& visitor, type& value) { \ - auto value0 = static_cast(value); \ - ::Reflect(visitor, value0); \ +#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &visitor, type &value) { \ + as_type value0; \ + ::Reflect(visitor, value0); \ + value = static_cast(value0); \ + } \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &visitor, type &value) { \ + auto value0 = static_cast(value); \ + ::Reflect(visitor, value0); \ } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); -#define _MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ +#define _MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ REFLECT_MEMBER_MANDATORY_OPTIONAL(name); -#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ - template \ - void Reflect(TVisitor& visitor, type& value) { \ - REFLECT_MEMBER_START(); \ - REFLECT_MEMBER_END(); \ +#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ + template void Reflect(TVisitor &visitor, type &value) { \ + REFLECT_MEMBER_START(); \ + REFLECT_MEMBER_END(); \ } -#define MAKE_REFLECT_STRUCT(type, ...) \ - template \ - void Reflect(TVisitor& visitor, type& value) { \ - REFLECT_MEMBER_START(); \ - MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ - REFLECT_MEMBER_END(); \ +#define MAKE_REFLECT_STRUCT(type, ...) \ + template void Reflect(TVisitor &visitor, type &value) { \ + REFLECT_MEMBER_START(); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ + REFLECT_MEMBER_END(); \ } -#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ - template \ - void Reflect(TVisitor& visitor, type& value) { \ - REFLECT_MEMBER_START(); \ - MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ - REFLECT_MEMBER_END(); \ +#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ + template void Reflect(TVisitor &visitor, type &value) { \ + REFLECT_MEMBER_START(); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ + REFLECT_MEMBER_END(); \ } // clang-format off @@ -131,71 +128,70 @@ struct IndexFile; // Reflects the struct so it is serialized as an array instead of an object. // This currently only supports writers. -#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \ - inline void Reflect(Writer& visitor, type& value) { \ - visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ - MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \ - visitor.EndArray(); \ +#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \ + inline void Reflect(Writer &visitor, type &value) { \ + visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ + MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \ + visitor.EndArray(); \ } //// Elementary types -void Reflect(Reader& visitor, uint8_t& value); -void Reflect(Writer& visitor, uint8_t& value); +void Reflect(Reader &visitor, uint8_t &value); +void Reflect(Writer &visitor, uint8_t &value); -void Reflect(Reader& visitor, short& value); -void Reflect(Writer& visitor, short& value); +void Reflect(Reader &visitor, short &value); +void Reflect(Writer &visitor, short &value); -void Reflect(Reader& visitor, unsigned short& value); -void Reflect(Writer& visitor, unsigned short& value); +void Reflect(Reader &visitor, unsigned short &value); +void Reflect(Writer &visitor, unsigned short &value); -void Reflect(Reader& visitor, int& value); -void Reflect(Writer& visitor, int& value); +void Reflect(Reader &visitor, int &value); +void Reflect(Writer &visitor, int &value); -void Reflect(Reader& visitor, unsigned& value); -void Reflect(Writer& visitor, unsigned& value); +void Reflect(Reader &visitor, unsigned &value); +void Reflect(Writer &visitor, unsigned &value); -void Reflect(Reader& visitor, long& value); -void Reflect(Writer& visitor, long& value); +void Reflect(Reader &visitor, long &value); +void Reflect(Writer &visitor, long &value); -void Reflect(Reader& visitor, unsigned long& value); -void Reflect(Writer& visitor, unsigned long& value); +void Reflect(Reader &visitor, unsigned long &value); +void Reflect(Writer &visitor, unsigned long &value); -void Reflect(Reader& visitor, long long& value); -void Reflect(Writer& visitor, long long& value); +void Reflect(Reader &visitor, long long &value); +void Reflect(Writer &visitor, long long &value); -void Reflect(Reader& visitor, unsigned long long& value); -void Reflect(Writer& visitor, unsigned long long& value); +void Reflect(Reader &visitor, unsigned long long &value); +void Reflect(Writer &visitor, unsigned long long &value); -void Reflect(Reader& visitor, double& value); -void Reflect(Writer& visitor, double& value); +void Reflect(Reader &visitor, double &value); +void Reflect(Writer &visitor, double &value); -void Reflect(Reader& visitor, bool& value); -void Reflect(Writer& visitor, bool& value); +void Reflect(Reader &visitor, bool &value); +void Reflect(Writer &visitor, bool &value); -void Reflect(Reader& visitor, std::string& value); -void Reflect(Writer& visitor, std::string& value); +void Reflect(Reader &visitor, std::string &value); +void Reflect(Writer &visitor, std::string &value); -void Reflect(Reader& visitor, std::string_view& view); -void Reflect(Writer& visitor, std::string_view& view); +void Reflect(Reader &visitor, std::string_view &view); +void Reflect(Writer &visitor, std::string_view &view); -void Reflect(Reader& vis, const char*& v); -void Reflect(Writer& vis, const char*& v); +void Reflect(Reader &vis, const char *&v); +void Reflect(Writer &vis, const char *&v); -void Reflect(Reader& visitor, JsonNull& value); -void Reflect(Writer& visitor, JsonNull& value); +void Reflect(Reader &visitor, JsonNull &value); +void Reflect(Writer &visitor, JsonNull &value); -void Reflect(Reader& visitor, SerializeFormat& value); -void Reflect(Writer& visitor, SerializeFormat& value); +void Reflect(Reader &visitor, SerializeFormat &value); +void Reflect(Writer &visitor, SerializeFormat &value); //// Type constructors -// ReflectMember std::optional is used to represent TypeScript optional properties -// (in `key: value` context). -// Reflect std::optional is used for a different purpose, whether an object is -// nullable (possibly in `value` context). -template -void Reflect(Reader& visitor, std::optional& value) { +// ReflectMember std::optional is used to represent TypeScript optional +// properties (in `key: value` context). Reflect std::optional is used for a +// different purpose, whether an object is nullable (possibly in `value` +// context). +template void Reflect(Reader &visitor, std::optional &value) { if (visitor.IsNull()) { visitor.GetNull(); return; @@ -204,8 +200,7 @@ void Reflect(Reader& visitor, std::optional& value) { Reflect(visitor, real_value); value = std::move(real_value); } -template -void Reflect(Writer& visitor, std::optional& value) { +template void Reflect(Writer &visitor, std::optional &value) { if (value) { if (visitor.Format() != SerializeFormat::Json) visitor.UInt8(1); @@ -215,8 +210,7 @@ void Reflect(Writer& visitor, std::optional& value) { } // The same as std::optional -template -void Reflect(Reader& visitor, Maybe& value) { +template void Reflect(Reader &visitor, Maybe &value) { if (visitor.IsNull()) { visitor.GetNull(); return; @@ -225,8 +219,7 @@ void Reflect(Reader& visitor, Maybe& value) { Reflect(visitor, real_value); value = std::move(real_value); } -template -void Reflect(Writer& visitor, Maybe& value) { +template void Reflect(Writer &visitor, Maybe &value) { if (value) { if (visitor.Format() != SerializeFormat::Json) visitor.UInt8(1); @@ -236,7 +229,7 @@ void Reflect(Writer& visitor, Maybe& value) { } template -void ReflectMember(Writer& visitor, const char* name, std::optional& value) { +void ReflectMember(Writer &visitor, const char *name, std::optional &value) { // For TypeScript std::optional property key?: value in the spec, // We omit both key and value if value is std::nullopt (null) for JsonWriter // to reduce output. But keep it for other serialization formats. @@ -248,7 +241,7 @@ void ReflectMember(Writer& visitor, const char* name, std::optional& value) { // The same as std::optional template -void ReflectMember(Writer& visitor, const char* name, Maybe& value) { +void ReflectMember(Writer &visitor, const char *name, Maybe &value) { if (value.Valid() || visitor.Format() != SerializeFormat::Json) { visitor.Key(name); Reflect(visitor, value); @@ -256,21 +249,19 @@ void ReflectMember(Writer& visitor, const char* name, Maybe& value) { } template -void ReflectMember(Writer& visitor, - const char* name, - T& value, +void ReflectMember(Writer &visitor, const char *name, T &value, mandatory_optional_tag) { visitor.Key(name); Reflect(visitor, value); } template -void Reflect(Reader& vis, std::pair& v) { +void Reflect(Reader &vis, std::pair &v) { vis.Member("L", [&]() { Reflect(vis, v.first); }); vis.Member("R", [&]() { Reflect(vis, v.second); }); } template -void Reflect(Writer& vis, std::pair& v) { +void Reflect(Writer &vis, std::pair &v) { vis.StartObject(); ReflectMember(vis, "L", v.first); ReflectMember(vis, "R", v.second); @@ -278,43 +269,35 @@ void Reflect(Writer& vis, std::pair& v) { } // std::vector -template -void Reflect(Reader& visitor, std::vector& values) { - visitor.IterArray([&](Reader& entry) { +template void Reflect(Reader &visitor, std::vector &values) { + visitor.IterArray([&](Reader &entry) { T entry_value; Reflect(entry, entry_value); values.push_back(std::move(entry_value)); }); } -template -void Reflect(Writer& visitor, std::vector& values) { +template void Reflect(Writer &visitor, std::vector &values) { visitor.StartArray(values.size()); - for (auto& value : values) + for (auto &value : values) Reflect(visitor, value); visitor.EndArray(); } // ReflectMember -inline bool ReflectMemberStart(Reader& vis) { - return false; -} -inline bool ReflectMemberStart(Writer& vis) { +inline bool ReflectMemberStart(Reader &vis) { return false; } +inline bool ReflectMemberStart(Writer &vis) { vis.StartObject(); return true; } -inline void ReflectMemberEnd(Reader& vis) {} -inline void ReflectMemberEnd(Writer& vis) { - vis.EndObject(); -} +inline void ReflectMemberEnd(Reader &vis) {} +inline void ReflectMemberEnd(Writer &vis) { vis.EndObject(); } -template -void ReflectMember(Reader& vis, const char* name, T& v) { +template void ReflectMember(Reader &vis, const char *name, T &v) { vis.Member(name, [&]() { Reflect(vis, v); }); } -template -void ReflectMember(Writer& vis, const char* name, T& v) { +template void ReflectMember(Writer &vis, const char *name, T &v) { vis.Key(name); Reflect(vis, v); } @@ -322,12 +305,11 @@ void ReflectMember(Writer& vis, const char* name, T& v) { // API namespace ccls { -const char* Intern(const std::string& str); -std::string Serialize(SerializeFormat format, IndexFile& file); -std::unique_ptr Deserialize( - SerializeFormat format, - const std::string& path, - const std::string& serialized_index_content, - const std::string& file_content, - std::optional expected_version); -} +const char *Intern(const std::string &str); +std::string Serialize(SerializeFormat format, IndexFile &file); +std::unique_ptr +Deserialize(SerializeFormat format, const std::string &path, + const std::string &serialized_index_content, + const std::string &file_content, + std::optional expected_version); +} // namespace ccls diff --git a/src/serializers/binary.h b/src/serializers/binary.h index 7327ba158..a8d3a1e4d 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -5,17 +5,16 @@ #include class BinaryReader : public Reader { - const char* p_; + const char *p_; - template - T Get() { - auto ret = *reinterpret_cast(p_); + template T Get() { + auto ret = *reinterpret_cast(p_); p_ += sizeof(T); return ret; } uint64_t VarUInt() { - auto x = *reinterpret_cast(p_++); + auto x = *reinterpret_cast(p_++); if (x < 253) return x; if (x == 253) @@ -29,11 +28,9 @@ class BinaryReader : public Reader { return int64_t(x >> 1 ^ -(x & 1)); } - public: +public: BinaryReader(std::string_view buf) : p_(buf.data()) {} - SerializeFormat Format() const override { - return SerializeFormat::Binary; - } + SerializeFormat Format() const override { return SerializeFormat::Binary; } bool IsBool() override { return true; } // Abuse how the function is called in serializer.h @@ -52,35 +49,32 @@ class BinaryReader : public Reader { uint32_t GetUInt32() override { return VarUInt(); } uint64_t GetUInt64() override { return VarUInt(); } double GetDouble() override { return Get(); } - const char* GetString() override { - const char* ret = p_; + const char *GetString() override { + const char *ret = p_; while (*p_) p_++; p_++; return ret; } - bool HasMember(const char* x) override { return true; } - std::unique_ptr operator[](const char* x) override { return {}; } + bool HasMember(const char *x) override { return true; } + std::unique_ptr operator[](const char *x) override { return {}; } - void IterArray(std::function fn) override { + void IterArray(std::function fn) override { for (auto n = VarUInt(); n; n--) fn(*this); } - void Member(const char*, std::function fn) override { - fn(); - } + void Member(const char *, std::function fn) override { fn(); } }; class BinaryWriter : public Writer { std::string buf_; - template - void Pack(T x) { + template void Pack(T x) { auto i = buf_.size(); buf_.resize(i + sizeof(x)); - *reinterpret_cast(buf_.data() + i) = x; + *reinterpret_cast(buf_.data() + i) = x; } void VarUInt(uint64_t n) { @@ -97,14 +91,10 @@ class BinaryWriter : public Writer { Pack(n); } } - void VarInt(int64_t n) { - VarUInt(uint64_t(n) << 1 ^ n >> 63); - } + void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); } - public: - SerializeFormat Format() const override { - return SerializeFormat::Binary; - } +public: + SerializeFormat Format() const override { return SerializeFormat::Binary; } std::string Take() { return std::move(buf_); } void Null() override { Pack(uint8_t(0)); } @@ -115,8 +105,8 @@ class BinaryWriter : public Writer { void UInt32(uint32_t x) override { VarUInt(x); } void UInt64(uint64_t x) override { VarUInt(x); } void Double(double x) override { Pack(x); } - void String(const char* x) override { String(x, strlen(x)); } - void String(const char* x, size_t len) override { + void String(const char *x) override { String(x, strlen(x)); } + void String(const char *x, size_t len) override { auto i = buf_.size(); buf_.resize(i + len + 1); memcpy(buf_.data() + i, x, len); @@ -125,5 +115,5 @@ class BinaryWriter : public Writer { void EndArray() override {} void StartObject() override {} void EndObject() override {} - void Key(const char* name) override {} + void Key(const char *name) override {} }; diff --git a/src/serializers/json.h b/src/serializers/json.h index b650f83b4..092d9afe9 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -6,11 +6,11 @@ #include class JsonReader : public Reader { - rapidjson::GenericValue>* m_; - std::vector path_; + rapidjson::GenericValue> *m_; + std::vector path_; - public: - JsonReader(rapidjson::GenericValue>* m) : m_(m) {} +public: + JsonReader(rapidjson::GenericValue> *m) : m_(m) {} SerializeFormat Format() const override { return SerializeFormat::Json; } bool IsBool() override { return m_->IsBool(); } @@ -29,20 +29,20 @@ class JsonReader : public Reader { uint32_t GetUInt32() override { return uint32_t(m_->GetUint64()); } uint64_t GetUInt64() override { return m_->GetUint64(); } double GetDouble() override { return m_->GetDouble(); } - const char* GetString() override { return m_->GetString(); } + const char *GetString() override { return m_->GetString(); } - bool HasMember(const char* x) override { return m_->HasMember(x); } - std::unique_ptr operator[](const char* x) override { - auto& sub = (*m_)[x]; + bool HasMember(const char *x) override { return m_->HasMember(x); } + std::unique_ptr operator[](const char *x) override { + auto &sub = (*m_)[x]; return std::unique_ptr(new JsonReader(&sub)); } - void IterArray(std::function fn) override { + void IterArray(std::function fn) override { if (!m_->IsArray()) throw std::invalid_argument("array"); // Use "0" to indicate any element for now. path_.push_back("0"); - for (auto& entry : m_->GetArray()) { + for (auto &entry : m_->GetArray()) { auto saved = m_; m_ = &entry; fn(*this); @@ -51,7 +51,7 @@ class JsonReader : public Reader { path_.pop_back(); } - void Member(const char* name, std::function fn) override { + void Member(const char *name, std::function fn) override { path_.push_back(name); auto it = m_->FindMember(name); if (it != m_->MemberEnd()) { @@ -65,7 +65,7 @@ class JsonReader : public Reader { std::string GetPath() const { std::string ret; - for (auto& t : path_) { + for (auto &t : path_) { ret += '/'; ret += t; } @@ -75,10 +75,10 @@ class JsonReader : public Reader { }; class JsonWriter : public Writer { - rapidjson::Writer* m_; + rapidjson::Writer *m_; - public: - JsonWriter(rapidjson::Writer* m) : m_(m) {} +public: + JsonWriter(rapidjson::Writer *m) : m_(m) {} SerializeFormat Format() const override { return SerializeFormat::Json; } void Null() override { m_->Null(); } @@ -89,11 +89,11 @@ class JsonWriter : public Writer { void UInt32(uint32_t x) override { m_->Uint64(x); } void UInt64(uint64_t x) override { m_->Uint64(x); } void Double(double x) override { m_->Double(x); } - void String(const char* x) override { m_->String(x); } - void String(const char* x, size_t len) override { m_->String(x, len); } + void String(const char *x) override { m_->String(x); } + void String(const char *x, size_t len) override { m_->String(x, len); } void StartArray(size_t) override { m_->StartArray(); } void EndArray() override { m_->EndArray(); } void StartObject() override { m_->StartObject(); } void EndObject() override { m_->EndObject(); } - void Key(const char* name) override { m_->Key(name); } + void Key(const char *name) override { m_->Key(name); } }; diff --git a/src/test.cc b/src/test.cc index 83ba466cb..943c54b6a 100644 --- a/src/test.cc +++ b/src/test.cc @@ -13,9 +13,9 @@ #include #include +#include #include #include -#include // The 'diff' utility is available and we can use dprintf(3). #if _POSIX_C_SOURCE >= 200809L @@ -25,7 +25,7 @@ extern bool gTestOutputMode; -std::string ToString(const rapidjson::Document& document) { +std::string ToString(const rapidjson::Document &document) { rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); writer.SetFormatOptions( @@ -45,18 +45,18 @@ struct TextReplacer { std::vector replacements; - std::string Apply(const std::string& content) { + std::string Apply(const std::string &content) { std::string result = content; - for (const Replacement& replacement : replacements) { + for (const Replacement &replacement : replacements) { while (true) { size_t idx = result.find(replacement.from); if (idx == std::string::npos) break; result.replace(result.begin() + idx, - result.begin() + idx + replacement.from.size(), - replacement.to); + result.begin() + idx + replacement.from.size(), + replacement.to); } } @@ -65,11 +65,10 @@ struct TextReplacer { }; void ParseTestExpectation( - const std::string& filename, - const std::vector& lines_with_endings, - TextReplacer* replacer, - std::vector* flags, - std::unordered_map* output_sections) { + const std::string &filename, + const std::vector &lines_with_endings, TextReplacer *replacer, + std::vector *flags, + std::unordered_map *output_sections) { // Scan for EXTRA_FLAGS: { bool in_output = false; @@ -129,9 +128,9 @@ void ParseTestExpectation( } } -void UpdateTestExpectation(const std::string& filename, - const std::string& expectation, - const std::string& actual) { +void UpdateTestExpectation(const std::string &filename, + const std::string &expectation, + const std::string &actual) { // Read the entire file into a string. std::ifstream in(filename); std::string str; @@ -148,10 +147,8 @@ void UpdateTestExpectation(const std::string& filename, WriteToFile(filename, str); } -void DiffDocuments(std::string path, - std::string path_section, - rapidjson::Document& expected, - rapidjson::Document& actual) { +void DiffDocuments(std::string path, std::string path_section, + rapidjson::Document &expected, rapidjson::Document &actual) { std::string joined_actual_output = ToString(actual); std::string joined_expected_output = ToString(expected); printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str()); @@ -190,7 +187,7 @@ void DiffDocuments(std::string path, path_section.c_str(), joined_actual_output.c_str()); } -void VerifySerializeToFrom(IndexFile* file) { +void VerifySerializeToFrom(IndexFile *file) { std::string expected = file->ToString(); std::string serialized = ccls::Serialize(SerializeFormat::Json, *file); std::unique_ptr result = @@ -199,14 +196,14 @@ void VerifySerializeToFrom(IndexFile* file) { std::string actual = result->ToString(); if (expected != actual) { fprintf(stderr, "Serialization failure\n"); - //assert(false); + // assert(false); } } std::string FindExpectedOutputForFilename( std::string filename, - const std::unordered_map& expected) { - for (const auto& entry : expected) { + const std::unordered_map &expected) { + for (const auto &entry : expected) { if (EndsWith(entry.first, filename)) return entry.second; } @@ -217,17 +214,17 @@ std::string FindExpectedOutputForFilename( return "{}"; } -IndexFile* FindDbForPathEnding( - const std::string& path, - const std::vector>& dbs) { - for (auto& db : dbs) { +IndexFile * +FindDbForPathEnding(const std::string &path, + const std::vector> &dbs) { + for (auto &db : dbs) { if (EndsWith(db->path, path)) return db.get(); } return nullptr; } -bool RunIndexTests(const std::string& filter_path, bool enable_update) { +bool RunIndexTests(const std::string &filter_path, bool enable_update) { gTestOutputMode = true; std::string version = LLVM_VERSION_STRING; @@ -248,7 +245,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // this can be done by constructing ClangIndex index(1, 1); GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, - [&](const std::string& path) { + [&](const std::string &path) { bool is_fail_allowed = false; if (EndsWithAny(path, {".m", ".mm"})) { @@ -291,13 +288,13 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { VFS vfs; auto dbs = ccls::idx::Index(&vfs, "", path, flags, {}); - for (const auto& entry : all_expected_output) { - const std::string& expected_path = entry.first; + for (const auto &entry : all_expected_output) { + const std::string &expected_path = entry.first; std::string expected_output = text_replacer.Apply(entry.second); // FIXME: promote to utils, find and remove duplicates (ie, // ccls_call_tree.cc, maybe something in project.cc). - auto basename = [](const std::string& path) -> std::string { + auto basename = [](const std::string &path) -> std::string { size_t last_index = path.find_last_of('/'); if (last_index == std::string::npos) return path; @@ -305,10 +302,10 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { }; // Get output from index operation. - IndexFile* db = FindDbForPathEnding(expected_path, dbs); + IndexFile *db = FindDbForPathEnding(expected_path, dbs); if (db && !db->diagnostics_.empty()) { printf("For %s\n", path.c_str()); - for (const lsDiagnostic& diagnostic : db->diagnostics_) { + for (const lsDiagnostic &diagnostic : db->diagnostics_) { printf(" "); if (diagnostic.severity) switch (*diagnostic.severity) { @@ -353,9 +350,8 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { DiffDocuments(path, expected_path, expected, actual); puts("\n"); if (enable_update) { - printf( - "[Enter to continue - type u to update test, a to update " - "all]"); + printf("[Enter to continue - type u to update test, a to update " + "all]"); char c = 'u'; if (!update_all) { c = getchar(); diff --git a/src/test.h b/src/test.h index 294d1ff92..2d5bf610e 100644 --- a/src/test.h +++ b/src/test.h @@ -2,4 +2,4 @@ #include -bool RunIndexTests(const std::string& filter_path, bool enable_update); +bool RunIndexTests(const std::string &filter_path, bool enable_update); diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 6e3bc9d70..a149c928e 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -18,27 +18,21 @@ struct BaseThreadQueue { // std::lock accepts two or more arguments. We define an overload for one // argument. namespace std { -template -void lock(Lockable& l) { - l.lock(); -} -} // namespace std - -template -struct MultiQueueLock { +template void lock(Lockable &l) { l.lock(); } +} // namespace std + +template struct MultiQueueLock { MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); } ~MultiQueueLock() { unlock(); } void lock() { lock_impl(typename std::index_sequence_for{}); } void unlock() { unlock_impl(typename std::index_sequence_for{}); } - private: - template - void lock_impl(std::index_sequence) { +private: + template void lock_impl(std::index_sequence) { std::lock(std::get(tuple_)->mutex_...); } - template - void unlock_impl(std::index_sequence) { + template void unlock_impl(std::index_sequence) { (void)std::initializer_list{ (std::get(tuple_)->mutex_.unlock(), 0)...}; } @@ -49,16 +43,15 @@ struct MultiQueueLock { struct MultiQueueWaiter { std::condition_variable_any cv; - static bool HasState(std::initializer_list queues) { - for (BaseThreadQueue* queue : queues) { + static bool HasState(std::initializer_list queues) { + for (BaseThreadQueue *queue : queues) { if (!queue->IsEmpty()) return true; } return false; } - template - void Wait(BaseThreadQueue... queues) { + template void Wait(BaseThreadQueue... queues) { MultiQueueLock l(queues...); while (!HasState({queues...})) cv.wait(l); @@ -66,21 +59,19 @@ struct MultiQueueWaiter { }; // A threadsafe-queue. http://stackoverflow.com/a/16075550 -template -struct ThreadedQueue : public BaseThreadQueue { - public: +template struct ThreadedQueue : public BaseThreadQueue { +public: ThreadedQueue() { owned_waiter_ = std::make_unique(); waiter_ = owned_waiter_.get(); } - explicit ThreadedQueue(MultiQueueWaiter* waiter) : waiter_(waiter) {} + explicit ThreadedQueue(MultiQueueWaiter *waiter) : waiter_(waiter) {} // Returns the number of elements in the queue. This is lock-free. size_t Size() const { return total_count_; } // Add an element to the queue. - template ::*push)(T&&)> - void Push(T&& t, bool priority) { + template ::*push)(T &&)> void Push(T &&t, bool priority) { std::lock_guard lock(mutex_); if (priority) (priority_.*push)(std::move(t)); @@ -90,7 +81,7 @@ struct ThreadedQueue : public BaseThreadQueue { waiter_->cv.notify_one(); } - void PushBack(T&& t, bool priority = false) { + void PushBack(T &&t, bool priority = false) { Push<&std::deque::push_back>(std::move(t), priority); } @@ -123,7 +114,7 @@ struct ThreadedQueue : public BaseThreadQueue { waiter_->cv.wait(lock, [&]() { return !priority_.empty() || !queue_.empty(); }); - auto execute = [&](std::deque* q) { + auto execute = [&](std::deque *q) { auto val = std::move(q->front()); q->pop_front(); --total_count_; @@ -138,7 +129,7 @@ struct ThreadedQueue : public BaseThreadQueue { // value if the queue is empty. std::optional TryPopFront() { std::lock_guard lock(mutex_); - auto execute = [&](std::deque* q) { + auto execute = [&](std::deque *q) { auto val = std::move(q->front()); q->pop_front(); --total_count_; @@ -151,21 +142,20 @@ struct ThreadedQueue : public BaseThreadQueue { return std::nullopt; } - template - void Iterate(Fn fn) { + template void Iterate(Fn fn) { std::lock_guard lock(mutex_); - for (auto& entry : priority_) + for (auto &entry : priority_) fn(entry); - for (auto& entry : queue_) + for (auto &entry : queue_) fn(entry); } mutable std::mutex mutex_; - private: +private: std::atomic total_count_{0}; std::deque priority_; std::deque queue_; - MultiQueueWaiter* waiter_; + MultiQueueWaiter *waiter_; std::unique_ptr owned_waiter_; }; diff --git a/src/utils.cc b/src/utils.cc index 36c277a36..5e92e699f 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -7,16 +7,16 @@ using namespace llvm; #include +#include #include #include #include -#include -#include #include +#include #include using namespace std::placeholders; -void TrimInPlace(std::string& s) { +void TrimInPlace(std::string &s) { auto f = [](char c) { return !isspace(c); }; s.erase(s.begin(), std::find_if(s.begin(), s.end(), f)); s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end()); @@ -34,7 +34,8 @@ uint64_t HashUsr(std::string_view s) { // k is an arbitrary key. Don't change it. const uint8_t k[16] = {0xd0, 0xe5, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x61, 0x79, 0xea, 0x70, 0xca, 0x70, 0xf0, 0x0d}; - (void)siphash(reinterpret_cast(s.data()), s.size(), k, out, 8); + (void)siphash(reinterpret_cast(s.data()), s.size(), k, out, + 8); return ret; } @@ -52,20 +53,20 @@ bool StartsWith(std::string_view s, std::string_view prefix) { std::equal(prefix.begin(), prefix.end(), s.begin()); } -bool EndsWithAny(std::string_view s, const std::vector& ss) { +bool EndsWithAny(std::string_view s, const std::vector &ss) { return std::any_of(ss.begin(), ss.end(), std::bind(EndsWith, s, _1)); } -bool FindAnyPartial(const std::string& value, - const std::vector& values) { +bool FindAnyPartial(const std::string &value, + const std::vector &values) { return std::any_of(std::begin(values), std::end(values), - [&value](const std::string& v) { + [&value](const std::string &v) { return value.find(v) != std::string::npos; }); } -std::vector SplitString(const std::string& str, - const std::string& delimiter) { +std::vector SplitString(const std::string &str, + const std::string &delimiter) { // http://stackoverflow.com/a/13172514 std::vector strings; @@ -82,10 +83,10 @@ std::vector SplitString(const std::string& str, return strings; } -std::string LowerPathIfInsensitive(const std::string& path) { +std::string LowerPathIfInsensitive(const std::string &path) { #if defined(_WIN32) std::string ret = path; - for (char& c : ret) + for (char &c : ret) c = tolower(c); return ret; #else @@ -93,14 +94,14 @@ std::string LowerPathIfInsensitive(const std::string& path) { #endif } -void EnsureEndsInSlash(std::string& path) { +void EnsureEndsInSlash(std::string &path) { if (path.empty() || path[path.size() - 1] != '/') path += '/'; } std::string EscapeFileName(std::string path) { bool slash = path.size() && path.back() == '/'; - for (char& c : path) + for (char &c : path) if (c == '\\' || c == '/' || c == ':') c = '@'; if (slash) @@ -108,11 +109,12 @@ std::string EscapeFileName(std::string path) { return path; } -std::optional ReadContent(const std::string& filename) { +std::optional ReadContent(const std::string &filename) { char buf[4096]; std::string ret; - FILE* f = fopen(filename.c_str(), "rb"); - if (!f) return {}; + FILE *f = fopen(filename.c_str(), "rb"); + if (!f) + return {}; size_t n; while ((n = fread(buf, 1, sizeof buf, f)) > 0) ret.append(buf, n); @@ -120,8 +122,8 @@ std::optional ReadContent(const std::string& filename) { return ret; } -void WriteToFile(const std::string& filename, const std::string& content) { - FILE* f = fopen(filename.c_str(), "wb"); +void WriteToFile(const std::string &filename, const std::string &content) { + FILE *f = fopen(filename.c_str(), "wb"); if (!f || (content.size() && fwrite(content.c_str(), content.size(), 1, f) != 1)) { LOG_S(ERROR) << "failed to write to " << filename << ' ' << strerror(errno); @@ -130,7 +132,7 @@ void WriteToFile(const std::string& filename, const std::string& content) { fclose(f); } -std::optional LastWriteTime(const std::string& filename) { +std::optional LastWriteTime(const std::string &filename) { sys::fs::file_status Status; if (sys::fs::status(filename, Status)) return {}; @@ -139,8 +141,7 @@ std::optional LastWriteTime(const std::string& filename) { // Find discontinous |search| in |content|. // Return |found| and the count of skipped chars before found. -int ReverseSubseqMatch(std::string_view pat, - std::string_view text, +int ReverseSubseqMatch(std::string_view pat, std::string_view text, int case_sensitivity) { if (case_sensitivity == 1) case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0; @@ -155,6 +156,4 @@ int ReverseSubseqMatch(std::string_view pat, return -1; } -std::string GetDefaultResourceDirectory() { - return DEFAULT_RESOURCE_DIRECTORY; -} +std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; } diff --git a/src/utils.h b/src/utils.h index 49af3555c..4317e5eb5 100644 --- a/src/utils.h +++ b/src/utils.h @@ -13,7 +13,7 @@ namespace llvm { class StringRef; } -void TrimInPlace(std::string& s); +void TrimInPlace(std::string &s); std::string Trim(std::string s); uint64_t HashUsr(std::string_view s); @@ -22,22 +22,21 @@ uint64_t HashUsr(llvm::StringRef s); // Returns true if |value| starts/ends with |start| or |ending|. bool StartsWith(std::string_view value, std::string_view start); bool EndsWith(std::string_view value, std::string_view ending); -bool EndsWithAny(std::string_view s, const std::vector& ss); -bool FindAnyPartial(const std::string& value, - const std::vector& values); +bool EndsWithAny(std::string_view s, const std::vector &ss); +bool FindAnyPartial(const std::string &value, + const std::vector &values); -std::vector SplitString(const std::string& str, - const std::string& delimiter); +std::vector SplitString(const std::string &str, + const std::string &delimiter); -std::string LowerPathIfInsensitive(const std::string& path); +std::string LowerPathIfInsensitive(const std::string &path); template -std::string StringJoinMap(const TValues& values, - const TMap& map, - const std::string& sep = ", ") { +std::string StringJoinMap(const TValues &values, const TMap &map, + const std::string &sep = ", ") { std::string result; bool first = true; - for (auto& entry : values) { + for (auto &entry : values) { if (!first) result += sep; first = false; @@ -47,24 +46,23 @@ std::string StringJoinMap(const TValues& values, } template -std::string StringJoin(const TValues& values, const std::string& sep = ", ") { - return StringJoinMap(values, [](const std::string& entry) { return entry; }, +std::string StringJoin(const TValues &values, const std::string &sep = ", ") { + return StringJoinMap(values, [](const std::string &entry) { return entry; }, sep); } // Ensures that |path| ends in a slash. -void EnsureEndsInSlash(std::string& path); +void EnsureEndsInSlash(std::string &path); // Converts a file path to one that can be used as filename. // e.g. foo/bar.c => foo_bar.c std::string EscapeFileName(std::string path); -std::optional ReadContent(const std::string& filename); -void WriteToFile(const std::string& filename, const std::string& content); -std::optional LastWriteTime(const std::string& filename); +std::optional ReadContent(const std::string &filename); +void WriteToFile(const std::string &filename, const std::string &content); +std::optional LastWriteTime(const std::string &filename); -int ReverseSubseqMatch(std::string_view pat, - std::string_view text, +int ReverseSubseqMatch(std::string_view pat, std::string_view text, int case_sensitivity); // http://stackoverflow.com/a/38140932 @@ -76,25 +74,24 @@ int ReverseSubseqMatch(std::string_view pat, // }; // MAKE_HASHABLE(SomeHashKey, t.key1, t.key2, t.key3) -inline void hash_combine(std::size_t& seed) {} +inline void hash_combine(std::size_t &seed) {} template -inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { +inline void hash_combine(std::size_t &seed, const T &v, Rest... rest) { std::hash hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); hash_combine(seed, rest...); } -#define MAKE_HASHABLE(type, ...) \ - namespace std { \ - template <> \ - struct hash { \ - std::size_t operator()(const type& t) const { \ - std::size_t ret = 0; \ - hash_combine(ret, __VA_ARGS__); \ - return ret; \ - } \ - }; \ +#define MAKE_HASHABLE(type, ...) \ + namespace std { \ + template <> struct hash { \ + std::size_t operator()(const type &t) const { \ + std::size_t ret = 0; \ + hash_combine(ret, __VA_ARGS__); \ + return ret; \ + } \ + }; \ } std::string GetDefaultResourceDirectory(); diff --git a/src/working_files.cc b/src/working_files.cc index 6f0ca26b9..643388fb8 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -17,7 +17,7 @@ constexpr int kMaxDiff = 20; // |kMaxColumnAlignSize|. constexpr int kMaxColumnAlignSize = 200; -lsPosition GetPositionForOffset(const std::string& content, int offset) { +lsPosition GetPositionForOffset(const std::string &content, int offset) { if (offset >= content.size()) offset = (int)content.size() - 1; @@ -32,7 +32,7 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) { return {line, col}; } -std::vector ToLines(const std::string& content) { +std::vector ToLines(const std::string &content) { std::vector result; std::istringstream lines(content); std::string line; @@ -45,7 +45,7 @@ std::vector ToLines(const std::string& content) { // Myers' O(ND) diff algorithm. // Costs: insertion=1, deletion=1, no substitution. // If the distance is larger than threshold, returns threshould + 1. -int MyersDiff(const char* a, int la, const char* b, int lb, int threshold) { +int MyersDiff(const char *a, int la, const char *b, int lb, int threshold) { assert(threshold <= kMaxDiff); static int v_static[2 * kMaxColumnAlignSize + 2]; const char *ea = a + la, *eb = b + lb; @@ -61,7 +61,7 @@ int MyersDiff(const char* a, int la, const char* b, int lb, int threshold) { if (la + lb > 2 * kMaxColumnAlignSize) return std::min(abs(la - lb), threshold + 1); - int* v = v_static + lb; + int *v = v_static + lb; v[1] = 0; for (int di = 0; di <= threshold; di++) { int low = -di + 2 * std::max(0, di - lb), @@ -80,7 +80,7 @@ int MyersDiff(const char* a, int la, const char* b, int lb, int threshold) { return threshold + 1; } -int MyersDiff(const std::string& a, const std::string& b, int threshold) { +int MyersDiff(const std::string &a, const std::string &b, int threshold) { return MyersDiff(a.data(), a.size(), b.data(), b.size(), threshold); } @@ -107,7 +107,7 @@ std::vector EditDistanceVector(std::string a, std::string b) { // Find matching position of |a[column]| in |b|. // This is actually a single step of Hirschberg's sequence alignment algorithm. -int AlignColumn(const std::string& a, int column, std::string b, bool is_end) { +int AlignColumn(const std::string &a, int column, std::string b, bool is_end) { int head = 0, tail = 0; while (head < (int)a.size() && head < (int)b.size() && a[head] == b[head]) head++; @@ -149,12 +149,10 @@ int AlignColumn(const std::string& a, int column, std::string b, bool is_end) { // Find matching buffer line of index_lines[line]. // By symmetry, this can also be used to find matching index line of a buffer // line. -std::optional FindMatchingLine(const std::vector& index_lines, - const std::vector& index_to_buffer, - int line, - int* column, - const std::vector& buffer_lines, - bool is_end) { +std::optional +FindMatchingLine(const std::vector &index_lines, + const std::vector &index_to_buffer, int line, int *column, + const std::vector &buffer_lines, bool is_end) { // If this is a confident mapping, returns. if (index_to_buffer[line] >= 0) { int ret = index_to_buffer[line]; @@ -179,7 +177,7 @@ std::optional FindMatchingLine(const std::vector& index_lines, // Search for lines [up,down] and use Myers's diff algorithm to find the best // match (least edit distance). int best = up, best_dist = kMaxDiff + 1; - const std::string& needle = index_lines[line]; + const std::string &needle = index_lines[line]; for (int i = up; i <= down; i++) { int dist = MyersDiff(needle, buffer_lines[i], kMaxDiff); if (dist < best_dist) { @@ -193,17 +191,17 @@ std::optional FindMatchingLine(const std::vector& index_lines, return best; } -} // namespace +} // namespace -WorkingFile::WorkingFile(const std::string& filename, - const std::string& buffer_content) +WorkingFile::WorkingFile(const std::string &filename, + const std::string &buffer_content) : filename(filename), buffer_content(buffer_content) { OnBufferContentUpdated(); // SetIndexContent gets called when the file is opened. } -void WorkingFile::SetIndexContent(const std::string& index_content) { +void WorkingFile::SetIndexContent(const std::string &index_content) { index_lines = ToLines(index_content); index_to_buffer.clear(); @@ -234,7 +232,7 @@ void WorkingFile::ComputeLineMapping() { // For index line i, set index_to_buffer[i] to -1 if line i is duplicated. int i = 0; - for (auto& line : index_lines) { + for (auto &line : index_lines) { uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { @@ -251,7 +249,7 @@ void WorkingFile::ComputeLineMapping() { // For buffer line i, set buffer_to_index[i] to -1 if line i is duplicated. i = 0; hash_to_unique.clear(); - for (auto& line : buffer_lines) { + for (auto &line : buffer_lines) { uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { @@ -300,9 +298,8 @@ void WorkingFile::ComputeLineMapping() { buffer_to_index[index_to_buffer[i]] = i; } -std::optional WorkingFile::GetBufferPosFromIndexPos(int line, - int* column, - bool is_end) { +std::optional WorkingFile::GetBufferPosFromIndexPos(int line, int *column, + bool is_end) { if (line < 0 || line >= (int)index_lines.size()) { LOG_S(WARNING) << "bad index_line (got " << line << ", expected [0, " << index_lines.size() << ")) in " << filename; @@ -315,9 +312,8 @@ std::optional WorkingFile::GetBufferPosFromIndexPos(int line, buffer_lines, is_end); } -std::optional WorkingFile::GetIndexPosFromBufferPos(int line, - int* column, - bool is_end) { +std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int *column, + bool is_end) { // See GetBufferLineFromIndexLine for additional comments. if (line < 0 || line >= (int)buffer_lines.size()) return std::nullopt; @@ -329,9 +325,8 @@ std::optional WorkingFile::GetIndexPosFromBufferPos(int line, } std::string WorkingFile::FindClosestCallNameInBuffer( - lsPosition position, - int* active_parameter, - lsPosition* completion_position) const { + lsPosition position, int *active_parameter, + lsPosition *completion_position) const { *active_parameter = 0; int offset = GetOffsetForPosition(position, buffer_content); @@ -378,10 +373,8 @@ std::string WorkingFile::FindClosestCallNameInBuffer( } lsPosition WorkingFile::FindStableCompletionSource( - lsPosition position, - bool* is_global_completion, - std::string* existing_completion, - lsPosition* replace_end_pos) const { + lsPosition position, bool *is_global_completion, + std::string *existing_completion, lsPosition *replace_end_pos) const { *is_global_completion = true; int start_offset = GetOffsetForPosition(position, buffer_content); @@ -410,7 +403,8 @@ lsPosition WorkingFile::FindStableCompletionSource( *replace_end_pos = position; for (int i = start_offset; i < buffer_content.size(); i++) { char c = buffer_content[i]; - if (!isalnum(c) && c != '_') break; + if (!isalnum(c) && c != '_') + break; // We know that replace_end_pos and position are on the same line. replace_end_pos->character++; } @@ -419,41 +413,41 @@ lsPosition WorkingFile::FindStableCompletionSource( return GetPositionForOffset(buffer_content, offset); } -WorkingFile* WorkingFiles::GetFileByFilename(const std::string& filename) { +WorkingFile *WorkingFiles::GetFileByFilename(const std::string &filename) { std::lock_guard lock(files_mutex); return GetFileByFilenameNoLock(filename); } -WorkingFile* WorkingFiles::GetFileByFilenameNoLock( - const std::string& filename) { - for (auto& file : files) { +WorkingFile * +WorkingFiles::GetFileByFilenameNoLock(const std::string &filename) { + for (auto &file : files) { if (file->filename == filename) return file.get(); } return nullptr; } -void WorkingFiles::DoAction(const std::function& action) { +void WorkingFiles::DoAction(const std::function &action) { std::lock_guard lock(files_mutex); action(); } void WorkingFiles::DoActionOnFile( - const std::string& filename, - const std::function& action) { + const std::string &filename, + const std::function &action) { std::lock_guard lock(files_mutex); - WorkingFile* file = GetFileByFilenameNoLock(filename); + WorkingFile *file = GetFileByFilenameNoLock(filename); action(file); } -WorkingFile* WorkingFiles::OnOpen(const lsTextDocumentItem& open) { +WorkingFile *WorkingFiles::OnOpen(const lsTextDocumentItem &open) { std::lock_guard lock(files_mutex); std::string filename = open.uri.GetPath(); std::string content = open.text; // The file may already be open. - if (WorkingFile* file = GetFileByFilenameNoLock(filename)) { + if (WorkingFile *file = GetFileByFilenameNoLock(filename)) { file->version = open.version; file->buffer_content = content; file->OnBufferContentUpdated(); @@ -464,11 +458,11 @@ WorkingFile* WorkingFiles::OnOpen(const lsTextDocumentItem& open) { return files[files.size() - 1].get(); } -void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { +void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams &change) { std::lock_guard lock(files_mutex); std::string filename = change.textDocument.uri.GetPath(); - WorkingFile* file = GetFileByFilenameNoLock(filename); + WorkingFile *file = GetFileByFilenameNoLock(filename); if (!file) { LOG_S(WARNING) << "Could not change " << filename << " because it was not open"; @@ -479,7 +473,7 @@ void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { if (change.textDocument.version) file->version = *change.textDocument.version; - for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) { + for (const lsTextDocumentContentChangeEvent &diff : change.contentChanges) { // Per the spec replace everything if the rangeLength and range are not set. // See https://github.com/Microsoft/language-server-protocol/issues/9. if (!diff.range) { @@ -500,7 +494,7 @@ void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { } } -void WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) { +void WorkingFiles::OnClose(const lsTextDocumentIdentifier &close) { std::lock_guard lock(files_mutex); std::string filename = close.uri.GetPath(); @@ -516,13 +510,13 @@ void WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) { << " because it was not open"; } -WorkingFiles::Snapshot WorkingFiles::AsSnapshot( - const std::vector& filter_paths) { +WorkingFiles::Snapshot +WorkingFiles::AsSnapshot(const std::vector &filter_paths) { std::lock_guard lock(files_mutex); Snapshot result; result.files.reserve(files.size()); - for (const auto& file : files) { + for (const auto &file : files) { if (filter_paths.empty() || FindAnyPartial(file->filename, filter_paths)) result.files.push_back({file->filename, file->buffer_content}); } diff --git a/src/working_files.h b/src/working_files.h index a1758b744..804301a98 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -29,10 +29,10 @@ struct WorkingFile { // lock! std::vector diagnostics_; - WorkingFile(const std::string& filename, const std::string& buffer_content); + WorkingFile(const std::string &filename, const std::string &buffer_content); // This should be called when the indexed content has changed. - void SetIndexContent(const std::string& index_content); + void SetIndexContent(const std::string &index_content); // This should be called whenever |buffer_content| has changed. void OnBufferContentUpdated(); @@ -40,10 +40,12 @@ struct WorkingFile { // Also resolves |column| if not NULL. // When resolving a range, use is_end = false for begin() and is_end = // true for end() to get a better alignment of |column|. - std::optional GetBufferPosFromIndexPos(int line, int* column, bool is_end); + std::optional GetBufferPosFromIndexPos(int line, int *column, + bool is_end); // Finds the index line number which maps to buffer line number |line|. // Also resolves |column| if not NULL. - std::optional GetIndexPosFromBufferPos(int line, int* column, bool is_end); + std::optional GetIndexPosFromBufferPos(int line, int *column, + bool is_end); // TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into // lex_utils.h/cc @@ -53,10 +55,9 @@ struct WorkingFile { // // |completion_position| will be point to a good code completion location to // for fetching signatures. - std::string FindClosestCallNameInBuffer( - lsPosition position, - int* active_parameter, - lsPosition* completion_position = nullptr) const; + std::string + FindClosestCallNameInBuffer(lsPosition position, int *active_parameter, + lsPosition *completion_position = nullptr) const; // Returns a relatively stable completion position (it jumps back until there // is a non-alphanumeric character). @@ -66,11 +67,11 @@ struct WorkingFile { // The out param |existing_completion| is set to any existing completion // content the user has entered. lsPosition FindStableCompletionSource(lsPosition position, - bool* is_global_completion, - std::string* existing_completion, - lsPosition* replace_end_pos) const; + bool *is_global_completion, + std::string *existing_completion, + lsPosition *replace_end_pos) const; - private: +private: // Compute index_to_buffer and buffer_to_index. void ComputeLineMapping(); }; @@ -90,29 +91,29 @@ struct WorkingFiles { // // Find the file with the given filename. - WorkingFile* GetFileByFilename(const std::string& filename); - WorkingFile* GetFileByFilenameNoLock(const std::string& filename); + WorkingFile *GetFileByFilename(const std::string &filename); + WorkingFile *GetFileByFilenameNoLock(const std::string &filename); // Run |action| under the lock. - void DoAction(const std::function& action); + void DoAction(const std::function &action); // Run |action| on the file identified by |filename|. This executes under the // lock. - void DoActionOnFile(const std::string& filename, - const std::function& action); + void DoActionOnFile(const std::string &filename, + const std::function &action); - WorkingFile* OnOpen(const lsTextDocumentItem& open); - void OnChange(const lsTextDocumentDidChangeParams& change); - void OnClose(const lsTextDocumentIdentifier& close); + WorkingFile *OnOpen(const lsTextDocumentItem &open); + void OnChange(const lsTextDocumentDidChangeParams &change); + void OnClose(const lsTextDocumentIdentifier &close); // If |filter_paths| is non-empty, only files which contain any of the given // strings. For example, {"foo", "bar"} means that every result has either the // string "foo" or "bar" contained within it. - Snapshot AsSnapshot(const std::vector& filter_paths); + Snapshot AsSnapshot(const std::vector &filter_paths); // Use unique_ptrs so we can handout WorkingFile ptrs and not have them // invalidated if we resize files. std::vector> files; - std::mutex files_mutex; // Protects |files|. + std::mutex files_mutex; // Protects |files|. }; int GetOffsetForPosition(lsPosition position, std::string_view content); From 06aa25233567ae16a58a6f5237aacfd9e02aa29d Mon Sep 17 00:00:00 2001 From: inengch Date: Mon, 13 Aug 2018 10:22:30 +0800 Subject: [PATCH 172/378] Fix typo error (#49) - The word strengthened is spelled mistakenly. - Unpaired symbol:')' seems to be missing. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a20910ad..4f041e871 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery), * preprocessor skipped regions * semantic highlighting, including support for [rainbow semantic highlighting](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e) -It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strenghened, (see [wiki/FAQ](../../wiki/FAQ). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. +It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strengthened, (see [wiki/FAQ](../../wiki/FAQ)). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. The comparison with cquery as noted on 2018-07-15: From 2f5fcadc39061f1996228ec350c04ae0bd28b2c3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 17 Aug 2018 22:20:51 -0700 Subject: [PATCH 173/378] Remove CompileCommandsEntry and reduce clangDriver invocations --- src/project.cc | 269 +++++++++++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 134 deletions(-) diff --git a/src/project.cc b/src/project.cc index ee5971a11..3b0bfeecd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -32,22 +32,6 @@ using namespace llvm; #include #include -struct CompileCommandsEntry { - std::string directory; - std::string file; - std::string command; - std::vector args; - - std::string ResolveIfRelative(std::string path) const { - if (sys::path::is_absolute(path)) - return path; - SmallString<256> Ret; - sys::path::append(Ret, directory, path); - return NormalizePath(Ret.str()); - } -}; -MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); - namespace { enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; @@ -67,108 +51,131 @@ enum OptionClass { Separate, }; -Project::Entry -GetCompilationEntryFromCompileCommandEntry(ProjectConfig *config, - const CompileCommandsEntry &entry) { - Project::Entry result; - result.filename = entry.file; - const std::string base_name = sys::path::filename(entry.file); +std::string ResolveIfRelative(const std::string &directory, + const std::string &path) { + if (sys::path::is_absolute(path)) + return path; + SmallString<256> Ret; + sys::path::append(Ret, directory, path); + return NormalizePath(Ret.str()); +} - // Expand %c %cpp %clang - std::vector args; - const LanguageId lang = SourceFileLanguage(entry.file); - for (const std::string &arg : entry.args) { - if (arg.compare(0, 3, "%c ") == 0) { - if (lang == LanguageId::C) - args.push_back(arg.substr(3)); - } else if (arg.compare(0, 5, "%cpp ") == 0) { - if (lang == LanguageId::Cpp) - args.push_back(arg.substr(5)); - } else if (arg == "%clang") { - args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); - } else { - args.push_back(arg); +struct ProjectProcessor { + ProjectConfig *config; + std::unordered_set command_set; + ProjectProcessor(ProjectConfig *config) : config(config) {} + + void Process(Project::Entry &entry) { + const std::string base_name = sys::path::filename(entry.filename); + + // Expand %c %cpp %clang + std::vector args; + args.reserve(entry.args.size() + config->extra_flags.size() + 3); + const LanguageId lang = SourceFileLanguage(entry.filename); + for (const std::string &arg : entry.args) { + if (arg.compare(0, 3, "%c ") == 0) { + if (lang == LanguageId::C) + args.push_back(arg.substr(3)); + } else if (arg.compare(0, 5, "%cpp ") == 0) { + if (lang == LanguageId::Cpp) + args.push_back(arg.substr(5)); + } else if (arg == "%clang") { + args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); + } else { + args.push_back(arg); + } } - } - if (args.empty()) - return result; - args.insert(args.end(), config->extra_flags.begin(), - config->extra_flags.end()); - - // a weird C++ deduction guide heap-use-after-free causes libclang to crash. - IgnoringDiagConsumer DiagC; - IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); - DiagnosticsEngine Diags( + if (args.empty()) + return; + args.insert(args.end(), config->extra_flags.begin(), + config->extra_flags.end()); + + size_t hash = std::hash{}(entry.directory); + for (auto &arg : args) { + if (arg[0] != '-' && EndsWith(arg, base_name)) { + const LanguageId lang = SourceFileLanguage(arg); + if (lang != LanguageId::Unknown) { + hash_combine(hash, size_t(lang)); + continue; + } + } + hash_combine(hash, std::hash{}(arg)); + } + for (size_t i = 1; i < args.size(); i++) + // This is most likely the file path we will be passing to clang. The + // path needs to be absolute, otherwise clang_codeCompleteAt is extremely + // slow. See + // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. + if (args[i][0] != '-' && EndsWith(args[i], base_name)) { + args[i] = ResolveIfRelative(entry.directory, args[i]); + continue; + } + + args.push_back("-resource-dir=" + g_config->clang.resourceDir); + args.push_back("-working-directory=" + entry.directory); + // There could be a clang version mismatch between what the project uses and + // what ccls uses. Make sure we do not emit warnings for mismatched options. + args.push_back("-Wno-unknown-warning-option"); + + if (!command_set.insert(hash).second) { + entry.args = std::move(args); + return; + } + + // a weird C++ deduction guide heap-use-after-free causes libclang to crash. + IgnoringDiagConsumer DiagC; + IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); + DiagnosticsEngine Diags( IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, &DiagC, false); - driver::Driver Driver(args[0], llvm::sys::getDefaultTargetTriple(), Diags); - auto TargetAndMode = + driver::Driver Driver(args[0], llvm::sys::getDefaultTargetTriple(), Diags); + auto TargetAndMode = driver::ToolChain::getTargetAndModeFromProgramName(args[0]); - if (!TargetAndMode.TargetPrefix.empty()) { - const char *arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()}; - args.insert(args.begin() + 1, std::begin(arr), std::end(arr)); - Driver.setTargetAndMode(TargetAndMode); - } - Driver.setCheckInputsExist(false); - - std::vector cargs; - for (auto &arg : args) - cargs.push_back(arg.c_str()); - cargs.push_back("-fsyntax-only"); - std::unique_ptr C(Driver.BuildCompilation(cargs)); - const driver::JobList &Jobs = C->getJobs(); - if (Jobs.size() != 1) - return result; - const driver::ArgStringList &CCArgs = Jobs.begin()->getArguments(); - - auto CI = std::make_unique(); - CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(), - CCArgs.data() + CCArgs.size(), Diags); - CI->getFrontendOpts().DisableFree = false; - CI->getCodeGenOpts().DisableFree = false; - - HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts(); - for (auto &E : HeaderOpts.UserEntries) { - std::string path = entry.ResolveIfRelative(E.Path); - switch (E.Group) { - default: - config->angle_dirs.insert(path); - break; - case frontend::Quoted: - config->quote_dirs.insert(path); - break; - case frontend::Angled: - config->angle_dirs.insert(path); - config->quote_dirs.insert(path); - break; + if (!TargetAndMode.TargetPrefix.empty()) { + const char *arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()}; + args.insert(args.begin() + 1, std::begin(arr), std::end(arr)); + Driver.setTargetAndMode(TargetAndMode); } - } - - for (size_t i = 1; i < args.size(); i++) - // This is most likely the file path we will be passing to clang. The - // path needs to be absolute, otherwise clang_codeCompleteAt is extremely - // slow. See - // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. - if (args[i][0] != '-' && EndsWith(args[i], base_name)) { - args[i] = entry.ResolveIfRelative(args[i]); - continue; + Driver.setCheckInputsExist(false); + + std::vector cargs; + cargs.reserve(args.size() + 1); + for (auto &arg : args) + cargs.push_back(arg.c_str()); + cargs.push_back("-fsyntax-only"); + + std::unique_ptr C(Driver.BuildCompilation(cargs)); + const driver::JobList &Jobs = C->getJobs(); + if (Jobs.size() != 1) + return; + const driver::ArgStringList &CCArgs = Jobs.begin()->getArguments(); + + auto CI = std::make_unique(); + CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(), + CCArgs.data() + CCArgs.size(), Diags); + CI->getFrontendOpts().DisableFree = false; + CI->getCodeGenOpts().DisableFree = false; + + HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts(); + for (auto &E : HeaderOpts.UserEntries) { + std::string path = ResolveIfRelative(entry.directory, E.Path); + switch (E.Group) { + default: + config->angle_dirs.insert(path); + break; + case frontend::Quoted: + config->quote_dirs.insert(path); + break; + case frontend::Angled: + config->angle_dirs.insert(path); + config->quote_dirs.insert(path); + break; + } } - - // if (!sys::fs::exists(HeaderOpts.ResourceDir) && - // HeaderOpts.UseBuiltinIncludes) - args.push_back("-resource-dir=" + g_config->clang.resourceDir); - if (CI->getFileSystemOpts().WorkingDir.empty()) - args.push_back("-working-directory=" + entry.directory); - - // There could be a clang version mismatch between what the project uses and - // what ccls uses. Make sure we do not emit warnings for mismatched options. - args.push_back("-Wno-unknown-warning-option"); - - result.directory = entry.directory; - result.args = std::move(args); - return result; -} + entry.args = std::move(args); + } +}; std::vector ReadCompilerArgumentsFromFile(const std::string &path) { @@ -226,23 +233,25 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { return folder_args[project_dir]; }; + ProjectProcessor proc(config); for (const std::string &file : files) { - CompileCommandsEntry e; + Project::Entry e; e.directory = config->project_dir; - e.file = file; + e.filename = file; e.args = GetCompilerArgumentForFile(file); if (e.args.empty()) e.args.push_back("%clang"); // Add a Dummy. - e.args.push_back(e.file); - result.push_back(GetCompilationEntryFromCompileCommandEntry(config, e)); + e.args.push_back(e.filename); + proc.Process(e); + result.push_back(e); } return result; } std::vector -LoadCompilationEntriesFromDirectory(ProjectConfig *project, - const std::string &opt_compilation_db_dir) { +LoadEntriesFromDirectory(ProjectConfig *project, + const std::string &opt_compdb_dir) { // If there is a .ccls file always load using directory listing. SmallString<256> Path; sys::path::append(Path, project->project_dir, ".ccls"); @@ -255,8 +264,8 @@ LoadCompilationEntriesFromDirectory(ProjectConfig *project, if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir - : opt_compilation_db_dir; + comp_db_dir = + opt_compdb_dir.empty() ? project->project_dir : opt_compdb_dir; sys::path::append(Path, comp_db_dir, "compile_commands.json"); } else { project->mode = ProjectMode::ExternalCommand; @@ -302,14 +311,15 @@ LoadCompilationEntriesFromDirectory(ProjectConfig *project, StringSet<> Seen; std::vector result; + ProjectProcessor proc(project); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { - CompileCommandsEntry entry; + Project::Entry entry; entry.directory = std::move(Cmd.Directory); - entry.file = entry.ResolveIfRelative(Cmd.Filename); + entry.filename = ResolveIfRelative(entry.directory, Cmd.Filename); entry.args = std::move(Cmd.CommandLine); - auto entry1 = GetCompilationEntryFromCompileCommandEntry(project, entry); - if (Seen.insert(entry1.filename).second) - result.push_back(entry1); + proc.Process(entry); + if (Seen.insert(entry.filename).second) + result.push_back(entry); } return result; } @@ -335,12 +345,11 @@ bool Project::loaded = false; void Project::Load(const std::string &root_directory) { Project::loaded = false; - // Load data. ProjectConfig project; project.extra_flags = g_config->clang.extraArgs; project.project_dir = root_directory; - entries = LoadCompilationEntriesFromDirectory( - &project, g_config->compilationDatabaseDirectory); + entries = LoadEntriesFromDirectory(&project, + g_config->compilationDatabaseDirectory); // Cleanup / postprocess include directories. quote_include_directories.assign(project.quote_dirs.begin(), @@ -355,14 +364,6 @@ void Project::Load(const std::string &root_directory) { EnsureEndsInSlash(path); LOG_S(INFO) << "angle_include_dir: " << path; } - - // Setup project entries. - std::lock_guard lock(mutex_); - absolute_path_to_entry_index_.reserve(entries.size()); - for (size_t i = 0; i < entries.size(); ++i) { - entries[i].id = i; - absolute_path_to_entry_index_[entries[i].filename] = i; - } } void Project::SetFlagsForFile(const std::vector &flags, From 431eef216724bbae0fdca2181956d3f5ea2c4fc4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 19 Aug 2018 13:11:47 -0700 Subject: [PATCH 174/378] textDocument/hover: prefer definitions in the same file --- src/messages/textDocument_hover.cc | 44 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index e6f4a436f..13bf156a8 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -6,38 +6,36 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/hover"; -// Find the comments for |sym|, if any. -std::optional GetComments(DB *db, SymbolRef sym) { - std::optional ret; - WithEntity(db, sym, [&](const auto &entity) { - if (const auto *def = entity.AnyDef()) - if (def->comments[0]) { - lsMarkedString m; - m.value = def->comments; - ret = m; - } - }); - return ret; -} - // Returns the hover or detailed name for `sym`, if any. -std::optional GetHoverOrName(DB *db, LanguageId lang, - SymbolRef sym) { - std::optional ret; +std::pair, std::optional> +GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { + const char *comments = nullptr; + std::optional ls_comments, hover; WithEntity(db, sym, [&](const auto &entity) { - if (const auto *def = entity.AnyDef()) { + std::remove_reference_t *def = nullptr; + for (auto &d : entity.def) { + if (d.spell) { + comments = d.comments[0] ? d.comments : nullptr; + def = &d; + if (d.spell->file_id == file_id) + break; + } + } + if (def) { lsMarkedString m; m.language = LanguageIdentifier(lang); if (def->hover[0]) { m.value = def->hover; - ret = m; + hover = m; } else if (def->detailed_name[0]) { m.value = def->detailed_name; - ret = m; + hover = m; } + if (comments) + ls_comments = lsMarkedString{std::nullopt, comments}; } }); - return ret; + return {hover, ls_comments}; } struct In_TextDocumentHover : public RequestInMessage { @@ -83,9 +81,7 @@ struct Handler_TextDocumentHover : BaseMessageHandler { if (!ls_range) continue; - std::optional comments = GetComments(db, sym); - std::optional hover = - GetHoverOrName(db, file->def->language, sym); + auto[hover, comments] = GetHover(db, file->def->language, sym, file->id); if (comments || hover) { out.result = Out_TextDocumentHover::Result(); out.result->range = *ls_range; From 66b027910a1ad319cd3e8c4680f80271dbda1676 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Tue, 21 Aug 2018 00:57:50 +0800 Subject: [PATCH 175/378] correctly grabbing the ownership of index files. (#54) --- src/pipeline.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pipeline.cc b/src/pipeline.cc index 053d4f4f0..5a43a01ff 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -194,6 +194,13 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, } } + // Grab the ownership + if (reparse) { + std::lock_guard lock(vfs->mutex); + vfs->state[path_to_index].owner = g_thread_id; + vfs->state[path_to_index].stage = 0; + } + if (reparse < 2) { LOG_S(INFO) << "load cache for " << path_to_index; auto dependencies = prev->dependencies; @@ -207,11 +214,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.is_interactive); } - - std::lock_guard lock(vfs->mutex); - VFS::State &state = vfs->state[path_to_index]; - if (state.owner == g_thread_id) - state.stage = 0; return true; } From f3490a3e6cee8a7f205d33b355c584eb979ea642 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 20 Aug 2018 22:27:52 -0700 Subject: [PATCH 176/378] Add license notice --- src/clang_complete.cc | 15 +++++++++++++++ src/clang_complete.h | 15 +++++++++++++++ src/clang_tu.cc | 15 +++++++++++++++ src/clang_tu.h | 15 +++++++++++++++ src/clang_utils.cc | 15 +++++++++++++++ src/clang_utils.h | 15 +++++++++++++++ src/config.cc | 15 +++++++++++++++ src/config.h | 15 +++++++++++++++ src/file_consumer.cc | 15 +++++++++++++++ src/file_consumer.h | 15 +++++++++++++++ src/filesystem.cc | 15 +++++++++++++++ src/fuzzy_match.cc | 15 +++++++++++++++ src/fuzzy_match.h | 15 +++++++++++++++ src/include_complete.cc | 15 +++++++++++++++ src/include_complete.h | 15 +++++++++++++++ src/indexer.cc | 15 +++++++++++++++ src/indexer.h | 15 +++++++++++++++ src/language.cc | 15 +++++++++++++++ src/language.h | 15 +++++++++++++++ src/log.cc | 15 +++++++++++++++ src/lru_cache.h | 15 +++++++++++++++ src/lsp.cc | 15 +++++++++++++++ src/lsp.h | 15 +++++++++++++++ src/lsp_code_action.h | 15 +++++++++++++++ src/lsp_completion.h | 15 +++++++++++++++ src/lsp_diagnostic.h | 15 +++++++++++++++ src/main.cc | 15 +++++++++++++++ src/match.cc | 15 +++++++++++++++ src/match.h | 15 +++++++++++++++ src/maybe.h | 15 +++++++++++++++ src/message_handler.cc | 15 +++++++++++++++ src/message_handler.h | 15 +++++++++++++++ src/messages/ccls_base.cc | 15 +++++++++++++++ src/messages/ccls_callHierarchy.cc | 15 +++++++++++++++ src/messages/ccls_callers.cc | 15 +++++++++++++++ src/messages/ccls_fileInfo.cc | 15 +++++++++++++++ src/messages/ccls_freshenIndex.cc | 15 +++++++++++++++ src/messages/ccls_inheritanceHierarchy.cc | 15 +++++++++++++++ src/messages/ccls_memberHierarchy.cc | 15 +++++++++++++++ src/messages/ccls_vars.cc | 15 +++++++++++++++ src/messages/exit.cc | 15 +++++++++++++++ src/messages/initialize.cc | 15 +++++++++++++++ src/messages/shutdown.cc | 15 +++++++++++++++ src/messages/textDocument_codeAction.cc | 15 +++++++++++++++ src/messages/textDocument_codeLens.cc | 15 +++++++++++++++ src/messages/textDocument_completion.cc | 15 +++++++++++++++ src/messages/textDocument_definition.cc | 15 +++++++++++++++ src/messages/textDocument_didChange.cc | 15 +++++++++++++++ src/messages/textDocument_didClose.cc | 15 +++++++++++++++ src/messages/textDocument_didOpen.cc | 15 +++++++++++++++ src/messages/textDocument_didSave.cc | 15 +++++++++++++++ src/messages/textDocument_documentHighlight.cc | 15 +++++++++++++++ src/messages/textDocument_documentSymbol.cc | 15 +++++++++++++++ src/messages/textDocument_hover.cc | 15 +++++++++++++++ src/messages/textDocument_implementation.cc | 15 +++++++++++++++ src/messages/textDocument_references.cc | 15 +++++++++++++++ src/messages/textDocument_rename.cc | 15 +++++++++++++++ src/messages/textDocument_signatureHelp.cc | 15 +++++++++++++++ src/messages/textDocument_typeDefinition.cc | 15 +++++++++++++++ src/messages/workspace_didChangeConfiguration.cc | 15 +++++++++++++++ src/messages/workspace_didChangeWatchedFiles.cc | 15 +++++++++++++++ src/messages/workspace_executeCommand.cc | 15 +++++++++++++++ src/messages/workspace_symbol.cc | 15 +++++++++++++++ src/method.cc | 15 +++++++++++++++ src/method.h | 15 +++++++++++++++ src/pipeline.cc | 15 +++++++++++++++ src/platform.h | 15 +++++++++++++++ src/platform_posix.cc | 15 +++++++++++++++ src/platform_win.cc | 15 +++++++++++++++ src/position.cc | 15 +++++++++++++++ src/position.h | 15 +++++++++++++++ src/project.cc | 15 +++++++++++++++ src/project.h | 15 +++++++++++++++ src/query.cc | 15 +++++++++++++++ src/query.h | 15 +++++++++++++++ src/query_utils.cc | 15 +++++++++++++++ src/query_utils.h | 15 +++++++++++++++ src/serializer.cc | 15 +++++++++++++++ src/serializer.h | 15 +++++++++++++++ src/serializers/binary.h | 15 +++++++++++++++ src/serializers/json.h | 15 +++++++++++++++ src/symbol.h | 15 +++++++++++++++ src/test.cc | 15 +++++++++++++++ src/test.h | 15 +++++++++++++++ src/threaded_queue.h | 15 +++++++++++++++ src/utils.cc | 15 +++++++++++++++ src/utils.h | 15 +++++++++++++++ src/working_files.cc | 15 +++++++++++++++ src/working_files.h | 15 +++++++++++++++ 89 files changed, 1335 insertions(+) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 5425361c7..c24f9c7af 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "clang_utils.h" diff --git a/src/clang_complete.h b/src/clang_complete.h index bfcb9407f..d3f034927 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "clang_tu.h" diff --git a/src/clang_tu.cc b/src/clang_tu.cc index ec767f998..28984f19e 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_tu.h" #include "clang_utils.h" diff --git a/src/clang_tu.h b/src/clang_tu.h index 47fe26aae..fa7f4f7b3 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "position.h" #include "working_files.h" diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 3a062b6c3..6a92b73ba 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_utils.h" #include "config.h" diff --git a/src/clang_utils.h b/src/clang_utils.h index 5fcc182e3..769412a97 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/config.cc b/src/config.cc index 9f0c64cf8..bd0ecc2bd 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "config.h" Config *g_config; diff --git a/src/config.h b/src/config.h index 44450b43a..d88ae7d56 100644 --- a/src/config.h +++ b/src/config.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "serializer.h" diff --git a/src/file_consumer.cc b/src/file_consumer.cc index e26a714a8..3542b2638 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "file_consumer.h" #include "clang_utils.h" diff --git a/src/file_consumer.h b/src/file_consumer.h index 3d4759e4c..b02920845 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "position.h" diff --git a/src/filesystem.cc b/src/filesystem.cc index 55a68db99..74eb836b8 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "filesystem.hh" using namespace llvm; diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 81c281837..3d69d925c 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "fuzzy_match.h" #include diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index c92476d29..1773775da 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/include_complete.cc b/src/include_complete.cc index a24de5f4c..779b04b01 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "include_complete.h" #include "filesystem.hh" diff --git a/src/include_complete.h b/src/include_complete.h index 692658021..c161388d1 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp_completion.h" diff --git a/src/indexer.cc b/src/indexer.cc index d37e56b40..d08936579 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "indexer.h" #include "clang_tu.h" diff --git a/src/indexer.h b/src/indexer.h index ff1e1e7be..8a5c399d0 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "clang_utils.h" diff --git a/src/language.cc b/src/language.cc index de64e69ed..ecb3b489f 100644 --- a/src/language.cc +++ b/src/language.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "language.h" #include "utils.h" diff --git a/src/language.h b/src/language.h index 4a34152fe..846185b57 100644 --- a/src/language.h +++ b/src/language.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "serializer.h" diff --git a/src/log.cc b/src/log.cc index 377dc79ce..a10a4a7df 100644 --- a/src/log.cc +++ b/src/log.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "log.hh" #include diff --git a/src/lru_cache.h b/src/lru_cache.h index b52c3bfb3..5e0253a29 100644 --- a/src/lru_cache.h +++ b/src/lru_cache.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/lsp.cc b/src/lsp.cc index a931e3054..afb0b76c2 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "lsp.h" #include "log.hh" diff --git a/src/lsp.h b/src/lsp.h index 6533d6e01..ef4ada8ca 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "config.h" diff --git a/src/lsp_code_action.h b/src/lsp_code_action.h index 2fbc5f4a6..15ed6be4f 100644 --- a/src/lsp_code_action.h +++ b/src/lsp_code_action.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp.h" diff --git a/src/lsp_completion.h b/src/lsp_completion.h index 26e3ff4b2..ef387380f 100644 --- a/src/lsp_completion.h +++ b/src/lsp_completion.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp.h" diff --git a/src/lsp_diagnostic.h b/src/lsp_diagnostic.h index f8dc5355c..7e9c7a8e5 100644 --- a/src/lsp_diagnostic.h +++ b/src/lsp_diagnostic.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp.h" diff --git a/src/main.cc b/src/main.cc index c68a16f8d..558803437 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "log.hh" #include "pipeline.hh" #include "platform.h" diff --git a/src/match.cc b/src/match.cc index bec43beab..3ddb0c37d 100644 --- a/src/match.cc +++ b/src/match.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "match.h" #include "lsp.h" diff --git a/src/match.h b/src/match.h index 134257a39..b9114768d 100644 --- a/src/match.h +++ b/src/match.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/maybe.h b/src/maybe.h index a24593765..ce20eadd1 100644 --- a/src/maybe.h +++ b/src/maybe.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/message_handler.cc b/src/message_handler.cc index 2197ea075..706bfe91b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "log.hh" diff --git a/src/message_handler.h b/src/message_handler.h index eb0f891dd..99da9d309 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lru_cache.h" diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index aa079d3dd..b5f2b8bb3 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_callHierarchy.cc index 0ec1fbda7..8b139eb4a 100644 --- a/src/messages/ccls_callHierarchy.cc +++ b/src/messages/ccls_callHierarchy.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" using namespace ccls; diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc index c5d8d7eeb..7b6c28f9a 100644 --- a/src/messages/ccls_callers.cc +++ b/src/messages/ccls_callers.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/ccls_fileInfo.cc b/src/messages/ccls_fileInfo.cc index e5795ff48..493d7b27f 100644 --- a/src/messages/ccls_fileInfo.cc +++ b/src/messages/ccls_fileInfo.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/ccls_freshenIndex.cc b/src/messages/ccls_freshenIndex.cc index c538270b7..edf23b4d4 100644 --- a/src/messages/ccls_freshenIndex.cc +++ b/src/messages/ccls_freshenIndex.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "match.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index 0246ee845..c169ab8fa 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index cf2e7455f..863678a6e 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 69cde5c6e..98dc53b89 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/exit.cc b/src/messages/exit.cc index 2ba8da5df..ce016d02a 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" namespace { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 01995f0b6..09f235295 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "filesystem.hh" #include "include_complete.h" #include "log.hh" diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index 07368344b..8f480f08d 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" using namespace ccls; diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc index c07336f8d..9ee4e5e11 100644 --- a/src/messages/textDocument_codeAction.cc +++ b/src/messages/textDocument_codeAction.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "working_files.h" diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index a9bed9c81..e28928e48 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "lsp_code_action.h" #include "message_handler.h" diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a2b1cc9dc..9582b5784 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "fuzzy_match.h" #include "include_complete.h" diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 21518b904..7794bfd14 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index abb63553f..a0690a2c6 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index 6e28b898f..8187ee7dc 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 3071beb14..c9d63e8ea 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "include_complete.h" #include "message_handler.h" diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 7e4ebdf86..17bb53ff2 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index 8ee24cc6a..871f617b3 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 8172e3ba3..2704d9141 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 13bf156a8..71dd0919a 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_implementation.cc b/src/messages/textDocument_implementation.cc index 32617c1df..9059f2877 100644 --- a/src/messages/textDocument_implementation.cc +++ b/src/messages/textDocument_implementation.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 61802ffe7..0c73a405d 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index a9665f3da..e701e7067 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index aedb0851c..8799a5424 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index ada23b4e7..ff1383f7c 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" diff --git a/src/messages/workspace_didChangeConfiguration.cc b/src/messages/workspace_didChangeConfiguration.cc index 81f3210b6..eb5b2d887 100644 --- a/src/messages/workspace_didChangeConfiguration.cc +++ b/src/messages/workspace_didChangeConfiguration.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index 26762a1d7..c25078b90 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "clang_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/workspace_executeCommand.cc b/src/messages/workspace_executeCommand.cc index 959484bdd..a7fc764de 100644 --- a/src/messages/workspace_executeCommand.cc +++ b/src/messages/workspace_executeCommand.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "lsp_code_action.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 33d80de96..2449e0727 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "fuzzy_match.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/method.cc b/src/method.cc index c3a48a6df..ca55f45aa 100644 --- a/src/method.cc +++ b/src/method.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "method.h" MethodType kMethodType_Unknown = "$unknown"; diff --git a/src/method.h b/src/method.h index b308002e9..3bf180f4d 100644 --- a/src/method.h +++ b/src/method.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "serializer.h" diff --git a/src/pipeline.cc b/src/pipeline.cc index 5a43a01ff..30c3e9782 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "pipeline.hh" #include "clang_complete.h" diff --git a/src/platform.h b/src/platform.h index d130e788a..46e88307d 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ac7409fff..4f48896c0 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #if defined(__unix__) || defined(__APPLE__) #include "platform.h" diff --git a/src/platform_win.cc b/src/platform_win.cc index 0ba14c3a4..be03055ce 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #if defined(_WIN32) #include "platform.h" diff --git a/src/position.cc b/src/position.cc index 6759e44fd..96292ef1d 100644 --- a/src/position.cc +++ b/src/position.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "position.h" #include "serializer.h" diff --git a/src/position.h b/src/position.h index a83f54d69..110676ca8 100644 --- a/src/position.h +++ b/src/position.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "maybe.h" diff --git a/src/project.cc b/src/project.cc index 3b0bfeecd..581a8a1b6 100644 --- a/src/project.cc +++ b/src/project.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "project.h" #include "clang_utils.h" diff --git a/src/project.h b/src/project.h index d91f830c3..3baa545ee 100644 --- a/src/project.h +++ b/src/project.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "config.h" diff --git a/src/query.cc b/src/query.cc index 56e637ea7..026aacf94 100644 --- a/src/query.cc +++ b/src/query.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "query.h" #include "indexer.h" diff --git a/src/query.h b/src/query.h index c7b694e7c..1513da0f0 100644 --- a/src/query.h +++ b/src/query.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "indexer.h" diff --git a/src/query_utils.cc b/src/query_utils.cc index e5a4887af..23349d7ce 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "query_utils.h" #include "pipeline.hh" diff --git a/src/query_utils.h b/src/query_utils.h index 884085ae6..262fbdfac 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "query.h" diff --git a/src/serializer.cc b/src/serializer.cc index 9ab01f06f..e99b3815e 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "serializer.h" #include "filesystem.hh" diff --git a/src/serializer.h b/src/serializer.h index 78eebd407..7e2487154 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "maybe.h" diff --git a/src/serializers/binary.h b/src/serializers/binary.h index a8d3a1e4d..1b86fac8c 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "serializer.h" diff --git a/src/serializers/json.h b/src/serializers/json.h index 092d9afe9..131556c26 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "serializer.h" diff --git a/src/symbol.h b/src/symbol.h index 3a79ba073..a4f3c05d6 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp.h" diff --git a/src/test.cc b/src/test.cc index 943c54b6a..d2fb971a1 100644 --- a/src/test.cc +++ b/src/test.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "test.h" #include "filesystem.hh" diff --git a/src/test.h b/src/test.h index 2d5bf610e..d22f1edd2 100644 --- a/src/test.h +++ b/src/test.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/threaded_queue.h b/src/threaded_queue.h index a149c928e..c14307a30 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "utils.h" diff --git a/src/utils.cc b/src/utils.cc index 5e92e699f..36a7e0e4d 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "utils.h" #include "filesystem.hh" diff --git a/src/utils.h b/src/utils.h index 4317e5eb5..973243fd9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include diff --git a/src/working_files.cc b/src/working_files.cc index 643388fb8..4f6ca27ae 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #include "working_files.h" #include "log.hh" diff --git a/src/working_files.h b/src/working_files.h index 804301a98..b0ed01c7b 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -1,3 +1,18 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + #pragma once #include "lsp_diagnostic.h" From ec2b893ee4a3a2d90a5458cc6bdc6a2c7379219f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 22 Aug 2018 17:40:50 -0700 Subject: [PATCH 177/378] Fix VarDef::is_local; default cacheDirectory to ".ccls-cache" --- src/config.h | 5 +++-- src/indexer.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/config.h b/src/config.h index d88ae7d56..ab5eb5eb5 100644 --- a/src/config.h +++ b/src/config.h @@ -45,8 +45,9 @@ struct Config { std::string compilationDatabaseCommand; // Directory containing compile_commands.json. std::string compilationDatabaseDirectory; - // Cache directory for indexed files. - std::string cacheDirectory; + // Cache directory for indexed files, either absolute or relative to the + // project root. + std::string cacheDirectory = ".ccls-cache"; // Cache serialization format. // // "json" generates `cacheDirectory/.../xxx.json` files which can be pretty diff --git a/src/indexer.h b/src/indexer.h index 8a5c399d0..151bb0b08 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -202,7 +202,7 @@ struct VarDef : NameMixin { uint8_t storage = clang::SC_None; bool is_local() const { - return spell && spell->kind != SymbolKind::File && + return spell && spell->kind == SymbolKind::Func && storage == clang::SC_None; } From 48c92c05a1f7b49eeab3ab0375a111215d172d05 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 23 Aug 2018 15:18:15 -0700 Subject: [PATCH 178/378] Add LLVM_ENABLE_RTTI (default: OFF) to allow linking against Arch Linux extra/{llvm,clang} (-DLLVM_ENABLE_RTTI=ON) --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa640b12..b202db78b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} option(SYSTEM_CLANG "Use system installation of Clang instead of \ downloading Clang" OFF) option(ASAN "Compile with address sanitizers" OFF) +option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) option(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" OFF) option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) @@ -34,8 +35,12 @@ if(NOT CYGWIN) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) endif() -# To link against LLVM libraries (usually compiled with -fno-rtti) -target_compile_options(ccls PRIVATE -fno-rtti) +if(NOT LLVM_ENABLE_RTTI) + # releases.llvm.org libraries are compiled with -fno-rtti + # The mismatch between lib{clang,LLVM}* and ccls can make libstdc++ std::make_shared return nullptr + # _Sp_counted_ptr_inplace::_M_get_deleter + target_compile_options(ccls PRIVATE -fno-rtti) +endif() # CMake sets MSVC for both MSVC and Clang(Windows) if(MSVC) From caddc18860bfd33488afeeb7934d92bd13574691 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 23 Aug 2018 20:33:58 -0700 Subject: [PATCH 179/378] Uniquify $ccls/inheritanceHierarchy and add flat to $ccls/memberHierarchy --- src/messages/ccls_inheritanceHierarchy.cc | 3 +++ src/messages/ccls_memberHierarchy.cc | 31 ++++++++++++++++++++--- src/messages/initialize.cc | 13 ++++++---- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index c169ab8fa..bea195154 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -199,6 +199,9 @@ struct Handler_CclsInheritanceHierarchy for (auto &entry1 : entry->children) q.push(&entry1); } + std::sort(out1.result.begin(), out1.result.end()); + out1.result.erase(std::unique(out1.result.begin(), out1.result.end()), + out1.result.end()); } pipeline::WriteStdout(kMethodType, out1); } diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_memberHierarchy.cc index 863678a6e..7de03d9e4 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_memberHierarchy.cc @@ -21,6 +21,7 @@ using namespace ccls; #include using namespace clang; +#include #include namespace { @@ -41,12 +42,12 @@ struct In_CclsMemberHierarchy : public RequestInMessage { bool qualified = false; int levels = 1; - }; - Params params; + bool flat = false; + } params; }; MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, - qualified, levels); + qualified, levels, flat); MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); @@ -276,7 +277,29 @@ struct Handler_CclsMemberHierarchy } } - pipeline::WriteStdout(kMethodType, out); + if (!params.flat) { + pipeline::WriteStdout(kMethodType, out); + return; + } + Out_LocationList out1; + out1.id = request->id; + if (out.result) { + std::queue q; + for (auto &entry1 : out.result->children) + q.push(&entry1); + while (q.size()) { + auto *entry = q.front(); + q.pop(); + if (entry->location.uri.raw_uri.size()) + out1.result.push_back({entry->location}); + for (auto &entry1 : entry->children) + q.push(&entry1); + } + std::sort(out1.result.begin(), out1.result.end()); + out1.result.erase(std::unique(out1.result.begin(), out1.result.end()), + out1.result.end()); + } + pipeline::WriteStdout(kMethodType, out1); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 09f235295..b687b6a9e 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -154,6 +154,8 @@ struct lsServerCapabilities { bool definitionProvider = true; // The server provides Goto Type Definition support. bool typeDefinitionProvider = true; + // The server provides Goto Implementation support. + bool implementationProvider = true; // The server provides find references support. bool referencesProvider = true; // The server provides document highlight support. @@ -182,11 +184,12 @@ struct lsServerCapabilities { }; MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, completionProvider, signatureHelpProvider, - definitionProvider, typeDefinitionProvider, - referencesProvider, documentHighlightProvider, - documentSymbolProvider, workspaceSymbolProvider, - codeActionProvider, codeLensProvider, - documentFormattingProvider, documentRangeFormattingProvider, + definitionProvider, implementationProvider, + typeDefinitionProvider, referencesProvider, + documentHighlightProvider, documentSymbolProvider, + workspaceSymbolProvider, codeActionProvider, + codeLensProvider, documentFormattingProvider, + documentRangeFormattingProvider, documentOnTypeFormattingProvider, renameProvider, documentLinkProvider, executeCommandProvider); From bd3e06796ee3445948958a7336e0b30bb052573a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 26 Aug 2018 17:22:45 -0700 Subject: [PATCH 180/378] SkipFunctionBodiesScope; improve fuzzy --- src/clang_tu.cc | 5 +++-- src/fuzzy_match.cc | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 28984f19e..741302961 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -109,9 +109,10 @@ std::unique_ptr ClangTranslationUnit::Create( /*CacheCodeCompletionResults=*/true, g_config->index.comments, /*AllowPCHWithCompilerErrors=*/true, #if LLVM_VERSION_MAJOR >= 7 - SkipFunctionBodiesScope::None, + diagnostic ? SkipFunctionBodiesScope::None + : SkipFunctionBodiesScope::PreambleAndMainFile, #else - false, + !diagnostic, #endif /*SingleFileParse=*/false, /*UserFilesAreVolatile=*/true, false, diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 3d69d925c..577f62238 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -43,7 +43,7 @@ void CalculateRoles(std::string_view s, int roles[], int *class_set) { if (cur == Other) return None; // U(U)L is Head while U(U)U is Tail - return pre == Other || (cur == Upper && (pre == Lower || suc != Upper)) + return pre == Other || (cur == Upper && (pre == Lower || suc == Lower)) ? Head : Tail; }; From f808dd8f8acacfef92c1a58fddd61ffcc2e69a52 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 27 Aug 2018 22:42:40 -0700 Subject: [PATCH 181/378] Use StoreInMemory Preamble for CodeComplete --- src/clang_complete.cc | 184 ++++++++++++++++++++++++++++-------------- src/clang_complete.h | 32 +++++++- src/clang_tu.cc | 5 +- src/working_files.cc | 8 ++ src/working_files.h | 1 + 5 files changed, 163 insertions(+), 67 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index c24f9c7af..e41c9fb97 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -22,6 +22,7 @@ limitations under the License. #include #include +#include #include #include #include @@ -320,12 +321,12 @@ class CaptureCompletionResults : public CodeCompleteConsumer { unsigned NumResults) override { ls_items.reserve(NumResults); for (unsigned i = 0; i != NumResults; i++) { + if (Results[i].Availability == CXAvailability_NotAccessible || + Results[i].Availability == CXAvailability_NotAvailable) + continue; CodeCompletionString *CCS = Results[i].CreateCodeCompletionString( S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); - if (CCS->getAvailability() == CXAvailability_NotAvailable) - continue; - lsCompletionItem ls_item; ls_item.kind = GetCompletionKind(Results[i].CursorKind); if (const char *brief = CCS->getBriefComment()) @@ -380,7 +381,7 @@ void TryEnsureDocumentParsed(ClangCompleteManager *manager, return; const auto &args = session->file.args; - WorkingFiles::Snapshot snapshot = session->working_files->AsSnapshot( + WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( {StripFileType(session->file.filename)}); LOG_S(INFO) << "create " << (diagnostic ? "diagnostic" : "completion") @@ -389,6 +390,23 @@ void TryEnsureDocumentParsed(ClangCompleteManager *manager, diagnostic); } +std::unique_ptr +buildCompilerInvocation(const std::vector &args, + IntrusiveRefCntPtr VFS) { + std::vector cargs; + for (auto &arg : args) + cargs.push_back(arg.c_str()); + IntrusiveRefCntPtr Diags( + CompilerInstance::createDiagnostics(new DiagnosticOptions)); + std::unique_ptr CI = + createInvocationFromCommandLine(cargs, Diags, VFS); + if (CI) { + CI->getLangOpts()->CommentOpts.ParseAllComments = true; + CI->getLangOpts()->SpellChecking = false; + } + return CI; +} + void CompletionPreloadMain(ClangCompleteManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. @@ -403,22 +421,14 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) { if (!session) continue; - // Note: we only preload completion. We emit diagnostics for the - // completion preload though. - CompletionSession::Tu *tu = &session->completion; - - // If we've parsed it more recently than the request time, don't bother - // reparsing. - if (tu->last_parsed_at && *tu->last_parsed_at > request.request_time) - continue; - - std::unique_ptr parsing; - TryEnsureDocumentParsed(completion_manager, session, &parsing, false); + const auto &args = session->file.args; + WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( + {StripFileType(session->file.filename)}); - // Activate new translation unit. - std::lock_guard lock(tu->lock); - tu->last_parsed_at = std::chrono::high_resolution_clock::now(); - tu->tu = std::move(parsing); + LOG_S(INFO) << "create completion session for " << session->file.filename; + if (std::unique_ptr CI = + buildCompilerInvocation(args, session->FS)) + session->BuildPreamble(*CI); } } @@ -441,48 +451,70 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { completion_manager->TryGetSession(path, true /*mark_as_completion*/, true /*create_if_needed*/); - std::lock_guard lock(session->completion.lock); - TryEnsureDocumentParsed(completion_manager, session, - &session->completion.tu, false); + std::unique_ptr CI = + buildCompilerInvocation(session->file.args, session->FS); + if (!CI) + continue; + clang::CodeCompleteOptions CCOpts; +#if LLVM_VERSION_MAJOR >= 7 + CCOpts.IncludeFixIts = true; +#endif + CCOpts.IncludeCodePatterns = true; + auto &FOpts = CI->getFrontendOpts(); + FOpts.DisableFree = false; + FOpts.CodeCompleteOpts = CCOpts; + FOpts.CodeCompletionAt.FileName = session->file.filename; + FOpts.CodeCompletionAt.Line = request->position.line + 1; + FOpts.CodeCompletionAt.Column = request->position.character + 1; - // It is possible we failed to create the document despite - // |TryEnsureDocumentParsed|. - if (ClangTranslationUnit *tu = session->completion.tu.get()) { - WorkingFiles::Snapshot snapshot = - completion_manager->working_files_->AsSnapshot({StripFileType(path)}); - IntrusiveRefCntPtr FileMgr(&tu->Unit->getFileManager()); - IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); - IntrusiveRefCntPtr Diag(new DiagnosticsEngine( - IntrusiveRefCntPtr(new DiagnosticIDs), &*DiagOpts)); - // StoreDiags Diags; - // IntrusiveRefCntPtr DiagE = - // CompilerInstance::createDiagnostics(DiagOpts.get(), &Diags, false); - - IntrusiveRefCntPtr SrcMgr( - new SourceManager(*Diag, *FileMgr)); - std::vector Remapped = GetRemapped(snapshot); - SmallVector Diagnostics; - SmallVector TemporaryBuffers; - - CodeCompleteOptions Opts; - LangOptions LangOpts; - Opts.IncludeBriefComments = true; + WorkingFiles::Snapshot snapshot = + completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + + std::vector> Bufs; + for (auto &file : snapshot.files) { + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); + if (file.filename == session->file.filename) { + if (auto Preamble = session->GetPreamble()) { #if LLVM_VERSION_MAJOR >= 7 - Opts.LoadExternal = true; - Opts.IncludeFixIts = true; + Preamble->Preamble.OverridePreamble(*CI, session->FS, + Bufs.back().get()); +#else + Preamble->Preamble.AddImplicitPreamble(*CI, session->FS, + Bufs.back().get()); #endif - CaptureCompletionResults capture(Opts); - tu->Unit->CodeComplete(session->file.filename, request->position.line + 1, - request->position.character + 1, Remapped, - /*IncludeMacros=*/true, - /*IncludeCodePatterns=*/false, - /*IncludeBriefComments=*/g_config->index.comments, - capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr, - *FileMgr, Diagnostics, TemporaryBuffers); - request->on_complete(capture.ls_items, false /*is_cached_result*/); - // completion_manager->on_diagnostic_(session->file.filename, - // Diags.take()); + } + else { + CI->getPreprocessorOpts().addRemappedFile( + CI->getFrontendOpts().Inputs[0].getFile(), Bufs.back().get()); + } + } else { + CI->getPreprocessorOpts().addRemappedFile(file.filename, + Bufs.back().get()); + } } + + IgnoringDiagConsumer DC; + auto Clang = std::make_unique(session->PCH); + Clang->setInvocation(std::move(CI)); + Clang->createDiagnostics(&DC, false); + auto Consumer = new CaptureCompletionResults(CCOpts); + Clang->setCodeCompletionConsumer(Consumer); + Clang->setVirtualFileSystem(session->FS); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); + if (!Clang->hasTarget()) + continue; + + SyntaxOnlyAction Action; + if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) + continue; + if (!Action.Execute()) + continue; + Action.EndSourceFile(); + for (auto &Buf : Bufs) + Buf.release(); + + request->on_complete(Consumer->ls_items, false /*is_cached_result*/); } } @@ -573,6 +605,37 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { } // namespace +std::shared_ptr CompletionSession::GetPreamble() { + std::lock_guard lock(completion.lock); + return completion.preamble; +} + +void CompletionSession::BuildPreamble(CompilerInvocation &CI) { + std::shared_ptr OldP = GetPreamble(); + std::string contents = wfiles->GetContent(file.filename); + std::unique_ptr Buf = + llvm::MemoryBuffer::getMemBuffer(contents); + auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); + if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) + return; + CI.getFrontendOpts().SkipFunctionBodies = true; +#if LLVM_VERSION_MAJOR >= 7 + CI.getPreprocessorOpts().WriteCommentListToPCH = false; +#endif + + DiagnosticConsumer DC; + IntrusiveRefCntPtr PreambleDE = + CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), + &DC, false); + PreambleCallbacks PP; + if (auto NewPreamble = PrecompiledPreamble::Build( + CI, Buf.get(), Bounds, *PreambleDE, FS, PCH, true, PP)) { + std::lock_guard lock(completion.lock); + completion.preamble = + std::make_shared(std::move(*NewPreamble)); + } +} + ClangCompleteManager::ClangCompleteManager(Project *project, WorkingFiles *working_files, OnDiagnostic on_diagnostic, @@ -580,7 +643,8 @@ ClangCompleteManager::ClangCompleteManager(Project *project, : project_(project), working_files_(working_files), on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), preloaded_sessions_(kMaxPreloadedSessions), - completion_sessions_(kMaxCompletionSessions) { + completion_sessions_(kMaxCompletionSessions), + PCH(std::make_shared()) { std::thread([&]() { set_thread_name("comp-query"); CompletionQueryMain(this); @@ -682,7 +746,7 @@ bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( // No CompletionSession, create new one. auto session = std::make_shared( - project_->FindCompilationEntryForFile(filename), working_files_); + project_->FindCompilationEntryForFile(filename), working_files_, PCH); preloaded_sessions_.Insert(session->file.filename, session); return true; } @@ -713,7 +777,7 @@ ClangCompleteManager::TryGetSession(const std::string &filename, completion_sessions_.TryGet(filename); if (!completion_session && create_if_needed) { completion_session = std::make_shared( - project_->FindCompilationEntryForFile(filename), working_files_); + project_->FindCompilationEntryForFile(filename), working_files_, PCH); completion_sessions_.Insert(filename, completion_session); } diff --git a/src/clang_complete.h b/src/clang_complete.h index d3f034927..5fa0ba390 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -23,11 +23,19 @@ limitations under the License. #include "threaded_queue.h" #include "working_files.h" +#include +#include + #include #include #include #include +struct PreambleData { + PreambleData(clang::PrecompiledPreamble P) : Preamble(std::move(P)) {} + clang::PrecompiledPreamble Preamble; +}; + struct CompletionSession : public std::enable_shared_from_this { // Translation unit for clang. @@ -40,14 +48,28 @@ struct CompletionSession std::unique_ptr tu; }; + struct CU { + std::mutex lock; + std::shared_ptr preamble; + }; + Project::Entry file; - WorkingFiles *working_files; + WorkingFiles *wfiles; + + // TODO share + llvm::IntrusiveRefCntPtr FS = + clang::vfs::getRealFileSystem(); + std::shared_ptr PCH; - Tu completion; + CU completion; Tu diagnostics; - CompletionSession(const Project::Entry &file, WorkingFiles *wfiles) - : file(file), working_files(wfiles) {} + CompletionSession(const Project::Entry &file, WorkingFiles *wfiles, + std::shared_ptr PCH) + : file(file), wfiles(wfiles), PCH(PCH) {} + + std::shared_ptr GetPreamble(); + void BuildPreamble(clang::CompilerInvocation &CI); }; struct ClangCompleteManager { @@ -145,6 +167,8 @@ struct ClangCompleteManager { // Parse requests. The path may already be parsed, in which case it should be // reparsed. ThreadedQueue preload_requests_; + + std::shared_ptr PCH; }; // Cached completion information, so we can give fast completion results when diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 741302961..35f969a4f 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -104,13 +104,12 @@ std::unique_ptr ClangTranslationUnit::Create( /*ResourceFilePath=*/g_config->clang.resourceDir, /*OnlyLocalDecls=*/false, /*CaptureDiagnostics=*/diagnostic, Remapped, - /*RemappedFilesKeepOriginalName=*/true, 1, + /*RemappedFilesKeepOriginalName=*/true, 0, diagnostic ? TU_Complete : TU_Prefix, /*CacheCodeCompletionResults=*/true, g_config->index.comments, /*AllowPCHWithCompilerErrors=*/true, #if LLVM_VERSION_MAJOR >= 7 - diagnostic ? SkipFunctionBodiesScope::None - : SkipFunctionBodiesScope::PreambleAndMainFile, + SkipFunctionBodiesScope::None, #else !diagnostic, #endif diff --git a/src/working_files.cc b/src/working_files.cc index 4f6ca27ae..74b9f30de 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -442,6 +442,14 @@ WorkingFiles::GetFileByFilenameNoLock(const std::string &filename) { return nullptr; } +std::string WorkingFiles::GetContent(const std::string &filename) { + std::lock_guard lock(files_mutex); + for (auto &file : files) + if (file->filename == filename) + return file->buffer_content; + return ""; +} + void WorkingFiles::DoAction(const std::function &action) { std::lock_guard lock(files_mutex); action(); diff --git a/src/working_files.h b/src/working_files.h index b0ed01c7b..dcd8fa843 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -108,6 +108,7 @@ struct WorkingFiles { // Find the file with the given filename. WorkingFile *GetFileByFilename(const std::string &filename); WorkingFile *GetFileByFilenameNoLock(const std::string &filename); + std::string GetContent(const std::string &filename); // Run |action| under the lock. void DoAction(const std::function &action); From 87c5491536f36368811a0fadca576a5b5dcb1c0e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 28 Aug 2018 22:49:53 -0700 Subject: [PATCH 182/378] New diagnostics --- src/clang_complete.cc | 341 ++++++++++++++++++++++++++---------------- src/clang_complete.h | 48 +++--- src/clang_tu.cc | 75 +--------- src/clang_tu.h | 23 +-- 4 files changed, 239 insertions(+), 248 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index e41c9fb97..b9d93b644 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -34,6 +34,7 @@ using namespace llvm; #include #include +namespace ccls { namespace { std::string StripFileType(const std::string &path) { @@ -304,6 +305,38 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, } } +bool LocationInRange(SourceLocation L, CharSourceRange R, + const SourceManager &M) { + assert(R.isCharRange()); + if (!R.isValid() || M.getFileID(R.getBegin()) != M.getFileID(R.getEnd()) || + M.getFileID(R.getBegin()) != M.getFileID(L)) + return false; + return L != R.getEnd() && M.isPointWithin(L, R.getBegin(), R.getEnd()); +} + +CharSourceRange DiagnosticRange(const clang::Diagnostic &D, const LangOptions &L) { + auto &M = D.getSourceManager(); + auto Loc = M.getFileLoc(D.getLocation()); + // Accept the first range that contains the location. + for (const auto &CR : D.getRanges()) { + auto R = Lexer::makeFileCharRange(CR, M, L); + if (LocationInRange(Loc, R, M)) + return R; + } + // The range may be given as a fixit hint instead. + for (const auto &F : D.getFixItHints()) { + auto R = Lexer::makeFileCharRange(F.RemoveRange, M, L); + if (LocationInRange(Loc, R, M)) + return R; + } + // If no suitable range is found, just use the token at the location. + auto R = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Loc), M, L); + if (!R.isValid()) // Fall back to location only, let the editor deal with it. + R = CharSourceRange::getCharRange(Loc); + return R; +} + + class CaptureCompletionResults : public CodeCompleteConsumer { std::shared_ptr Alloc; CodeCompletionTUInfo CCTUInfo; @@ -372,23 +405,83 @@ class CaptureCompletionResults : public CodeCompleteConsumer { CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } }; -void TryEnsureDocumentParsed(ClangCompleteManager *manager, - std::shared_ptr session, - std::unique_ptr *tu, - bool diagnostic) { - // Nothing to do. We already have a translation unit. - if (*tu) - return; - - const auto &args = session->file.args; - WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( - {StripFileType(session->file.filename)}); +class StoreDiags : public DiagnosticConsumer { + const LangOptions *LangOpts; + std::optional last; + std::vector output; + void Flush() { + if (!last) + return; + bool mentions = last->inside_main || last->edits.size(); + if (!mentions) + for (auto &N : last->notes) + if (N.inside_main) + mentions = true; + if (mentions) + output.push_back(std::move(*last)); + last.reset(); + } +public: + std::vector Take() { + return std::move(output); + } + void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override { + LangOpts = &Opts; + } + void EndSourceFile() override { + Flush(); + } + void HandleDiagnostic(DiagnosticsEngine::Level Level, + const Diagnostic &Info) override { + DiagnosticConsumer::HandleDiagnostic(Level, Info); + SourceLocation L = Info.getLocation(); + if (!L.isValid()) return; + const SourceManager &SM = Info.getSourceManager(); + bool inside_main = SM.isInMainFile(L); + auto fillDiagBase = [&](DiagBase &d) { + llvm::SmallString<64> Message; + Info.FormatDiagnostic(Message); + d.range = + FromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts)); + d.message = Message.str(); + d.inside_main = inside_main; + d.file = SM.getFilename(Info.getLocation()); + d.level = Level; + d.category = DiagnosticIDs::getCategoryNumberForDiag(Info.getID()); + }; + + auto addFix = [&](bool SyntheticMessage) -> bool { + if (!inside_main) + return false; + for (const FixItHint &FixIt : Info.getFixItHints()) { + if (!SM.isInMainFile(FixIt.RemoveRange.getBegin())) + return false; + lsTextEdit edit; + edit.newText = FixIt.CodeToInsert; + auto r = FromCharSourceRange(SM, *LangOpts, FixIt.RemoveRange); + edit.range = + lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; + last->edits.push_back(std::move(edit)); + } + return true; + }; - LOG_S(INFO) << "create " << (diagnostic ? "diagnostic" : "completion") - << " TU for " << session->file.filename; - *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot, - diagnostic); -} + if (Level == DiagnosticsEngine::Note || Level == DiagnosticsEngine::Remark) { + if (Info.getFixItHints().size()) { + addFix(false); + } else { + Note &n = last->notes.emplace_back(); + fillDiagBase(n); + } + } else { + Flush(); + last = Diag(); + fillDiagBase(*last); + if (!Info.getFixItHints().empty()) + addFix(true); + } + } +}; std::unique_ptr buildCompilerInvocation(const std::vector &args, @@ -401,12 +494,61 @@ buildCompilerInvocation(const std::vector &args, std::unique_ptr CI = createInvocationFromCommandLine(cargs, Diags, VFS); if (CI) { + CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->CommentOpts.ParseAllComments = true; CI->getLangOpts()->SpellChecking = false; } return CI; } +std::unique_ptr +BuildCompilerInstance(CompletionSession &session, + std::unique_ptr CI, + DiagnosticConsumer &DC, + const WorkingFiles::Snapshot &snapshot, + std::vector> &Bufs) { + for (auto &file : snapshot.files) { + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); + if (file.filename == session.file.filename) { + if (auto Preamble = session.GetPreamble()) { +#if LLVM_VERSION_MAJOR >= 7 + Preamble->Preamble.OverridePreamble(*CI, session.FS, + Bufs.back().get()); +#else + Preamble->Preamble.AddImplicitPreamble(*CI, session->FS, + Bufs.back().get()); +#endif + } else { + CI->getPreprocessorOpts().addRemappedFile( + CI->getFrontendOpts().Inputs[0].getFile(), Bufs.back().get()); + } + } else { + CI->getPreprocessorOpts().addRemappedFile(file.filename, + Bufs.back().get()); + } + } + + auto Clang = std::make_unique(session.PCH); + Clang->setInvocation(std::move(CI)); + Clang->setVirtualFileSystem(session.FS); + Clang->createDiagnostics(&DC, false); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); + if (!Clang->hasTarget()) + return nullptr; + return Clang; +} + +bool Parse(CompilerInstance &Clang) { + SyntaxOnlyAction Action; + if (!Action.BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0])) + return false; + if (!Action.Execute()) + return false; + Action.EndSourceFile(); + return true; +} + void CompletionPreloadMain(ClangCompleteManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. @@ -461,56 +603,23 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { #endif CCOpts.IncludeCodePatterns = true; auto &FOpts = CI->getFrontendOpts(); - FOpts.DisableFree = false; FOpts.CodeCompleteOpts = CCOpts; FOpts.CodeCompletionAt.FileName = session->file.filename; FOpts.CodeCompletionAt.Line = request->position.line + 1; FOpts.CodeCompletionAt.Column = request->position.character + 1; + StoreDiags DC; WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); - std::vector> Bufs; - for (auto &file : snapshot.files) { - Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); - if (file.filename == session->file.filename) { - if (auto Preamble = session->GetPreamble()) { -#if LLVM_VERSION_MAJOR >= 7 - Preamble->Preamble.OverridePreamble(*CI, session->FS, - Bufs.back().get()); -#else - Preamble->Preamble.AddImplicitPreamble(*CI, session->FS, - Bufs.back().get()); -#endif - } - else { - CI->getPreprocessorOpts().addRemappedFile( - CI->getFrontendOpts().Inputs[0].getFile(), Bufs.back().get()); - } - } else { - CI->getPreprocessorOpts().addRemappedFile(file.filename, - Bufs.back().get()); - } - } + auto Clang = BuildCompilerInstance(*session, std::move(CI), DC, snapshot, Bufs); + if (!Clang) + continue; - IgnoringDiagConsumer DC; - auto Clang = std::make_unique(session->PCH); - Clang->setInvocation(std::move(CI)); - Clang->createDiagnostics(&DC, false); auto Consumer = new CaptureCompletionResults(CCOpts); Clang->setCodeCompletionConsumer(Consumer); - Clang->setVirtualFileSystem(session->FS); - Clang->setTarget(TargetInfo::CreateTargetInfo( - Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); - if (!Clang->hasTarget()) + if (!Parse(*Clang)) continue; - - SyntaxOnlyAction Action; - if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) - continue; - if (!Action.Execute()) - continue; - Action.EndSourceFile(); for (auto &Buf : Bufs) Buf.release(); @@ -530,51 +639,31 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { std::shared_ptr session = manager->TryGetSession( path, true /*mark_as_completion*/, true /*create_if_needed*/); - // At this point, we must have a translation unit. Block until we have one. - std::lock_guard lock(session->diagnostics.lock); - TryEnsureDocumentParsed(manager, session, &session->diagnostics.tu, true); - - // It is possible we failed to create the document despite - // |TryEnsureDocumentParsed|. - ClangTranslationUnit *tu = session->diagnostics.tu.get(); - if (!tu) + std::unique_ptr CI = + buildCompilerInvocation(session->file.args, session->FS); + if (!CI) continue; - + StoreDiags DC; WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); - llvm::CrashRecoveryContext CRC; - if (tu->Reparse(CRC, snapshot)) { - LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " - << path; + std::vector> Bufs; + auto Clang = BuildCompilerInstance(*session, std::move(CI), DC, snapshot, Bufs); + if (!Clang) continue; - } + if (!Parse(*Clang)) + continue; + for (auto &Buf : Bufs) + Buf.release(); - auto &LangOpts = tu->Unit->getLangOpts(); std::vector ls_diags; - for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(), - E = tu->Unit->stored_diag_end(); - I != E; ++I) { - FullSourceLoc FLoc = I->getLocation(); - if (!FLoc.isValid()) // why? - continue; - const FileEntry *FE = FLoc.getFileEntry(); - if (!FE || FileName(*FE) != path) + for (auto &d : DC.Take()) { + if (!d.inside_main) continue; - const auto &SM = FLoc.getManager(); - SourceRange R; - for (const auto &CR : I->getRanges()) { - auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); - if (SM.isPointWithin(FLoc, RT.getBegin(), RT.getEnd())) { - R = CR.getAsRange(); - break; - } - } - Range r = R.isValid() ? FromCharRange(SM, LangOpts, R) - : FromTokenRange(SM, LangOpts, {FLoc, FLoc}); - lsDiagnostic ls_diag; - ls_diag.range = - lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; - switch (I->getLevel()) { + lsDiagnostic &ls_diag = ls_diags.emplace_back(); + ls_diag.range = lsRange{{d.range.start.line, d.range.start.column}, + {d.range.end.line, d.range.end.column}}; + ls_diag.message = d.message; + switch (d.level) { case DiagnosticsEngine::Ignored: // llvm_unreachable case DiagnosticsEngine::Note: @@ -588,16 +677,8 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { case DiagnosticsEngine::Fatal: ls_diag.severity = lsDiagnosticSeverity::Error; } - ls_diag.message = I->getMessage().str(); - for (const FixItHint &FixIt : I->getFixIts()) { - lsTextEdit edit; - edit.newText = FixIt.CodeToInsert; - r = FromCharSourceRange(SM, LangOpts, FixIt.RemoveRange); - edit.range = - lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; - ls_diag.fixits_.push_back(edit); - } - ls_diags.push_back(ls_diag); + ls_diag.code = d.category; + ls_diag.fixits_ = d.edits; } manager->on_diagnostic_(path, ls_diags); } @@ -606,15 +687,15 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { } // namespace std::shared_ptr CompletionSession::GetPreamble() { - std::lock_guard lock(completion.lock); - return completion.preamble; + std::lock_guard lock(mutex); + return preamble; } void CompletionSession::BuildPreamble(CompilerInvocation &CI) { std::shared_ptr OldP = GetPreamble(); - std::string contents = wfiles->GetContent(file.filename); + std::string content = wfiles->GetContent(file.filename); std::unique_ptr Buf = - llvm::MemoryBuffer::getMemBuffer(contents); + llvm::MemoryBuffer::getMemBuffer(content); auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; @@ -623,19 +704,20 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { CI.getPreprocessorOpts().WriteCommentListToPCH = false; #endif - DiagnosticConsumer DC; - IntrusiveRefCntPtr PreambleDE = - CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), - &DC, false); + StoreDiags DC; + IntrusiveRefCntPtr DE = + CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &DC, false); PreambleCallbacks PP; - if (auto NewPreamble = PrecompiledPreamble::Build( - CI, Buf.get(), Bounds, *PreambleDE, FS, PCH, true, PP)) { - std::lock_guard lock(completion.lock); - completion.preamble = - std::make_shared(std::move(*NewPreamble)); + if (auto NewPreamble = PrecompiledPreamble::Build(CI, Buf.get(), Bounds, + *DE, FS, PCH, true, PP)) { + std::lock_guard lock(mutex); + preamble = + std::make_shared(std::move(*NewPreamble), DC.Take()); } } +} // namespace ccls + ClangCompleteManager::ClangCompleteManager(Project *project, WorkingFiles *working_files, OnDiagnostic on_diagnostic, @@ -647,17 +729,17 @@ ClangCompleteManager::ClangCompleteManager(Project *project, PCH(std::make_shared()) { std::thread([&]() { set_thread_name("comp-query"); - CompletionQueryMain(this); + ccls::CompletionQueryMain(this); }) .detach(); std::thread([&]() { set_thread_name("comp-preload"); - CompletionPreloadMain(this); + ccls::CompletionPreloadMain(this); }) .detach(); std::thread([&]() { set_thread_name("diag-query"); - DiagnosticQueryMain(this); + ccls::DiagnosticQueryMain(this); }) .detach(); } @@ -745,43 +827,42 @@ bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( } // No CompletionSession, create new one. - auto session = std::make_shared( + auto session = std::make_shared( project_->FindCompilationEntryForFile(filename), working_files_, PCH); preloaded_sessions_.Insert(session->file.filename, session); return true; } -std::shared_ptr +std::shared_ptr ClangCompleteManager::TryGetSession(const std::string &filename, bool mark_as_completion, bool create_if_needed) { std::lock_guard lock(sessions_lock_); // Try to find a preloaded session. - std::shared_ptr preloaded_session = + std::shared_ptr preloaded = preloaded_sessions_.TryGet(filename); - if (preloaded_session) { + if (preloaded) { // If this request is for a completion, we should move it to // |completion_sessions|. if (mark_as_completion) { preloaded_sessions_.TryTake(filename); - completion_sessions_.Insert(filename, preloaded_session); + completion_sessions_.Insert(filename, preloaded); } - - return preloaded_session; + return preloaded; } // Try to find a completion session. If none create one. - std::shared_ptr completion_session = + std::shared_ptr session = completion_sessions_.TryGet(filename); - if (!completion_session && create_if_needed) { - completion_session = std::make_shared( + if (!session && create_if_needed) { + session = std::make_shared( project_->FindCompilationEntryForFile(filename), working_files_, PCH); - completion_sessions_.Insert(filename, completion_session); + completion_sessions_.Insert(filename, session); } - return completion_session; + return session; } void ClangCompleteManager::FlushSession(const std::string &filename) { diff --git a/src/clang_complete.h b/src/clang_complete.h index 5fa0ba390..92716e418 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -31,27 +31,33 @@ limitations under the License. #include #include +namespace ccls { +struct DiagBase { + Range range; + std::string message; + std::string file; + clang::DiagnosticsEngine::Level level = clang::DiagnosticsEngine::Note; + unsigned category; + bool inside_main = false; +}; +struct Note : DiagBase {}; +struct Diag : DiagBase { + std::vector notes; + std::vector edits; +}; + struct PreambleData { - PreambleData(clang::PrecompiledPreamble P) : Preamble(std::move(P)) {} + PreambleData(clang::PrecompiledPreamble P, std::vector diags) + : Preamble(std::move(P)), diags(std::move(diags)) {} clang::PrecompiledPreamble Preamble; + std::vector diags; }; struct CompletionSession : public std::enable_shared_from_this { - // Translation unit for clang. - struct Tu { - // When |tu| was last parsed. - std::optional> - last_parsed_at; - // Acquired when |tu| is being used. - std::mutex lock; - std::unique_ptr tu; - }; - - struct CU { - std::mutex lock; - std::shared_ptr preamble; - }; + std::mutex mutex; + std::shared_ptr preamble; + std::vector diags; Project::Entry file; WorkingFiles *wfiles; @@ -61,9 +67,6 @@ struct CompletionSession clang::vfs::getRealFileSystem(); std::shared_ptr PCH; - CU completion; - Tu diagnostics; - CompletionSession(const Project::Entry &file, WorkingFiles *wfiles, std::shared_ptr PCH) : file(file), wfiles(wfiles), PCH(PCH) {} @@ -71,6 +74,7 @@ struct CompletionSession std::shared_ptr GetPreamble(); void BuildPreamble(clang::CompilerInvocation &CI); }; +} struct ClangCompleteManager { using OnDiagnostic = std::function TryGetSession(const std::string &filename, - bool mark_as_completion, - bool create_if_needed); + std::shared_ptr + TryGetSession(const std::string &filename, bool mark_as_completion, + bool create_if_needed); // Flushes all saved sessions with the supplied filename void FlushSession(const std::string &filename); @@ -149,7 +153,7 @@ struct ClangCompleteManager { OnDiagnostic on_diagnostic_; OnDropped on_dropped_; - using LruSessionCache = LruCache; + using LruSessionCache = LruCache; // CompletionSession instances which are preloaded, ie, files which the user // has viewed but not requested code completion for. diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 35f969a4f..3cb09e0e5 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -16,12 +16,8 @@ limitations under the License. #include "clang_tu.h" #include "clang_utils.h" -#include "log.hh" -#include "platform.h" -#include "utils.h" -#include "working_files.h" -#include +#include using namespace clang; #include @@ -67,72 +63,3 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R), UniqueID); } - -std::vector -GetRemapped(const WorkingFiles::Snapshot &snapshot) { - std::vector Remapped; - for (auto &file : snapshot.files) { - std::unique_ptr MB = - llvm::MemoryBuffer::getMemBufferCopy(file.content, file.filename); - Remapped.emplace_back(file.filename, MB.release()); - } - return Remapped; -} - -std::unique_ptr ClangTranslationUnit::Create( - const std::string &filepath, const std::vector &args, - const WorkingFiles::Snapshot &snapshot, bool diagnostic) { - std::vector Args; - for (auto &arg : args) - Args.push_back(arg.c_str()); - Args.push_back("-fallow-editor-placeholders"); - if (!diagnostic) - Args.push_back("-fno-spell-checking"); - - auto ret = std::make_unique(); - IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); - std::vector Remapped = GetRemapped(snapshot); - - ret->PCHCO = std::make_shared(); - std::unique_ptr ErrUnit, Unit; - llvm::CrashRecoveryContext CRC; - auto parse = [&]() { - Unit.reset(ASTUnit::LoadFromCommandLine( - Args.data(), Args.data() + Args.size(), - /*PCHContainerOpts=*/ret->PCHCO, Diags, - /*ResourceFilePath=*/g_config->clang.resourceDir, - /*OnlyLocalDecls=*/false, - /*CaptureDiagnostics=*/diagnostic, Remapped, - /*RemappedFilesKeepOriginalName=*/true, 0, - diagnostic ? TU_Complete : TU_Prefix, - /*CacheCodeCompletionResults=*/true, g_config->index.comments, - /*AllowPCHWithCompilerErrors=*/true, -#if LLVM_VERSION_MAJOR >= 7 - SkipFunctionBodiesScope::None, -#else - !diagnostic, -#endif - /*SingleFileParse=*/false, - /*UserFilesAreVolatile=*/true, false, - ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); - }; - if (!CRC.RunSafely(parse)) { - LOG_S(ERROR) << "clang crashed for " << filepath << "\n" - << StringJoin(args, " ") + " -fsyntax-only"; - return {}; - } - if (!Unit && !ErrUnit) - return {}; - - ret->Unit = std::move(Unit); - return ret; -} - -int ClangTranslationUnit::Reparse(llvm::CrashRecoveryContext &CRC, - const WorkingFiles::Snapshot &snapshot) { - int ret = 1; - (void)CRC.RunSafely( - [&]() { ret = Unit->Reparse(PCHCO, GetRemapped(snapshot)); }); - return ret; -} diff --git a/src/clang_tu.h b/src/clang_tu.h index fa7f4f7b3..def8a3972 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -15,19 +15,10 @@ limitations under the License. #pragma once #include "position.h" -#include "working_files.h" -#include -#include -#include +#include -#include #include -#include -#include - -std::vector -GetRemapped(const WorkingFiles::Snapshot &snapshot); Range FromCharSourceRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, @@ -41,15 +32,3 @@ Range FromCharRange(const clang::SourceManager &SM, Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); - -struct ClangTranslationUnit { - static std::unique_ptr - Create(const std::string &filepath, const std::vector &args, - const WorkingFiles::Snapshot &snapshot, bool diagnostic); - - int Reparse(llvm::CrashRecoveryContext &CRC, - const WorkingFiles::Snapshot &snapshot); - - std::shared_ptr PCHCO; - std::unique_ptr Unit; -}; From 74790e2421a67a74fade74f99deb9feaaef81eae Mon Sep 17 00:00:00 2001 From: firstlove <37442588+FirstLoveLife@users.noreply.github.com> Date: Wed, 29 Aug 2018 23:33:20 +0800 Subject: [PATCH 183/378] fix clang_tu.h && clang_complete.cc (#61) --- src/clang_complete.cc | 2 +- src/clang_tu.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index b9d93b644..c062071be 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -515,7 +515,7 @@ BuildCompilerInstance(CompletionSession &session, Preamble->Preamble.OverridePreamble(*CI, session.FS, Bufs.back().get()); #else - Preamble->Preamble.AddImplicitPreamble(*CI, session->FS, + Preamble->Preamble.AddImplicitPreamble(*CI, session.FS, Bufs.back().get()); #endif } else { diff --git a/src/clang_tu.h b/src/clang_tu.h index def8a3972..7d2b4b732 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -16,6 +16,7 @@ limitations under the License. #pragma once #include "position.h" +#include #include #include From 1ae97c64ed5a73878ecbf09411a21b0a4b5b589d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 29 Aug 2018 21:20:27 -0700 Subject: [PATCH 184/378] detailed_name: "{\n}" -> "{}" ; completion --- index_tests/enums/enum_class_decl.cc | 2 +- index_tests/enums/enum_decl.cc | 2 +- index_tests/enums/enum_inherit.cc | 4 ++-- index_tests/enums/enum_usage.cc | 2 +- index_tests/foobar.cc | 4 ++-- index_tests/multi_file/funky_enum.cc | 2 +- index_tests/multi_file/impl.cc | 2 +- index_tests/namespaces/function_declaration.cc | 2 +- index_tests/namespaces/function_definition.cc | 2 +- index_tests/namespaces/method_declaration.cc | 2 +- index_tests/namespaces/method_definition.cc | 2 +- index_tests/namespaces/method_inline_declaration.cc | 2 +- index_tests/namespaces/namespace_alias.cc | 6 +++--- index_tests/namespaces/namespace_reference.cc | 2 +- index_tests/outline/static_function_in_type.cc | 4 ++-- index_tests/templates/implicit_variable_instantiation.cc | 4 ++-- ...template_class_template_func_usage_folded_into_one.cc | 2 +- .../namespace_template_type_usage_folded_into_one.cc | 2 +- index_tests/templates/specialization.cc | 2 +- .../template_class_type_usage_folded_into_one.cc | 4 ++-- .../templates/template_var_usage_folded_into_one.cc | 4 ++-- index_tests/usage/var_usage_cstyle_cast.cc | 2 +- src/clang_complete.cc | 9 +++++---- src/indexer.cc | 6 ++++++ 24 files changed, 41 insertions(+), 34 deletions(-) diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 34a1c978e..3f3f78ca4 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -29,7 +29,7 @@ enum class Foo : uint8_t { "uses": [] }, { "usr": 16985894625255407295, - "detailed_name": "enum class Foo : uint8_t {\n}", + "detailed_name": "enum class Foo : uint8_t {}", "qual_name_offset": 11, "short_name": "Foo", "kind": 10, diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 3b28d1aaf..6e44da9b4 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -11,7 +11,7 @@ enum Foo { "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, - "detailed_name": "enum Foo {\n}", + "detailed_name": "enum Foo {}", "qual_name_offset": 5, "short_name": "Foo", "kind": 10, diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 195b93d96..08d840870 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -18,7 +18,7 @@ enum class E : int32_t { "usr2func": [], "usr2type": [{ "usr": 2986879766914123941, - "detailed_name": "enum class E : int32_t {\n}", + "detailed_name": "enum class E : int32_t {}", "qual_name_offset": 11, "short_name": "E", "kind": 10, @@ -52,7 +52,7 @@ enum class E : int32_t { "uses": [] }, { "usr": 16985894625255407295, - "detailed_name": "enum Foo : int {\n}", + "detailed_name": "enum Foo : int {}", "qual_name_offset": 5, "short_name": "Foo", "kind": 10, diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index 2d602b458..bcee0c009 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -13,7 +13,7 @@ Foo x = Foo::A; "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, - "detailed_name": "enum class Foo : int {\n}", + "detailed_name": "enum class Foo : int {}", "qual_name_offset": 11, "short_name": "Foo", "kind": 10, diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index b1e571d16..f5d2e47b8 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -16,7 +16,7 @@ Foo b; "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "enum A {\n}", + "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", "kind": 10, @@ -84,7 +84,7 @@ Foo b; "uses": [] }, { "usr": 13892793056005362145, - "detailed_name": "enum B {\n}", + "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", "kind": 10, diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index c76b4d471..69f5ebdca 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -81,7 +81,7 @@ OUTPUT: funky_enum.cc "usr2func": [], "usr2type": [{ "usr": 16985894625255407295, - "detailed_name": "enum Foo {\n}", + "detailed_name": "enum Foo {}", "qual_name_offset": 5, "short_name": "Foo", "kind": 10, diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index cc53dabf6..12a625b34 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -76,7 +76,7 @@ OUTPUT: header.h "uses": [] }, { "usr": 4481210672785600703, - "detailed_name": "enum Foo3 {\n}", + "detailed_name": "enum Foo3 {}", "qual_name_offset": 5, "short_name": "Foo3", "kind": 10, diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 2438c99c5..ec694bc9e 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -23,7 +23,7 @@ void foo(int a, int b); }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "namespace hello {\n}", + "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", "kind": 3, diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index 7afe9d29e..ce7845557 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -25,7 +25,7 @@ void foo() {} }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "namespace hello {\n}", + "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", "kind": 3, diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index 48a8456e8..de02f813c 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -25,7 +25,7 @@ class Foo { }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "namespace hello {\n}", + "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", "kind": 3, diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 2506e411c..5a25f7a9f 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -29,7 +29,7 @@ void Foo::foo() {} }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "namespace hello {\n}", + "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", "kind": 3, diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index 55c951185..b4029c5f8 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -27,7 +27,7 @@ class Foo { }], "usr2type": [{ "usr": 2029211996748007610, - "detailed_name": "namespace hello {\n}", + "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", "kind": 3, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index b659f5533..314890b88 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -51,7 +51,7 @@ void func() { "uses": [] }, { "usr": 926793467007732869, - "detailed_name": "namespace foo {\n}", + "detailed_name": "namespace foo {}", "qual_name_offset": 10, "short_name": "foo", "kind": 3, @@ -81,7 +81,7 @@ void func() { "uses": ["13:11-13:14|10818727483146447186|3|4"] }, { "usr": 14450849931009540802, - "detailed_name": "namespace foo::bar::baz {\n}", + "detailed_name": "namespace foo::bar::baz {}", "qual_name_offset": 10, "short_name": "baz", "kind": 3, @@ -99,7 +99,7 @@ void func() { "uses": ["9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] }, { "usr": 17805385787823406700, - "detailed_name": "namespace foo::bar {\n}", + "detailed_name": "namespace foo::bar {}", "qual_name_offset": 10, "short_name": "bar", "kind": 3, diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 169494038..09919e037 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -62,7 +62,7 @@ void Runner() { "uses": [] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 89842296c..9826edca2 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -42,7 +42,7 @@ OUTPUT: static_function_in_type.h "uses": ["6:24-6:31|17262466801709381811|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, @@ -116,7 +116,7 @@ OUTPUT: static_function_in_type.cc "uses": ["5:20-5:27|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index db370e9f6..36a978218 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -37,7 +37,7 @@ namespace ns { "uses": [] }, { "usr": 1532099849728741556, - "detailed_name": "enum ns::VarType {\n}", + "detailed_name": "enum ns::VarType {}", "qual_name_offset": 5, "short_name": "VarType", "kind": 10, @@ -54,7 +54,7 @@ namespace ns { "uses": ["6:22-6:29|12688716854043726585|2|4", "6:44-6:51|12688716854043726585|2|4", "10:18-10:25|11072669167287398027|2|4"] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index 073ba3447..d0fb3cb45 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -49,7 +49,7 @@ namespace ns { "uses": [] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 5b141b398..0476c03ad 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -48,7 +48,7 @@ namespace ns { "uses": [] }, { "usr": 11072669167287398027, - "detailed_name": "namespace ns {\n}", + "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index f5ca0f26a..7b8960c13 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -204,7 +204,7 @@ void foo(float Value); "uses": ["21:16-21:22|0|1|4", "30:1-30:7|0|1|4", "32:1-32:7|0|1|4"] }, { "usr": 9201299975592934124, - "detailed_name": "enum Enum {\n}", + "detailed_name": "enum Enum {}", "qual_name_offset": 5, "short_name": "Enum", "kind": 10, diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 0dbec81c2..7115ebc92 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -35,7 +35,7 @@ VarDecl b "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "enum A {\n}", + "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", "kind": 10, @@ -86,7 +86,7 @@ VarDecl b "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] }, { "usr": 13892793056005362145, - "detailed_name": "enum B {\n}", + "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", "kind": 10, diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index e325205db..844baece5 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -38,7 +38,7 @@ UnexposedDecl var "usr2func": [], "usr2type": [{ "usr": 6697181287623958829, - "detailed_name": "enum A {\n}", + "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", "kind": 10, @@ -72,7 +72,7 @@ UnexposedDecl var "uses": [] }, { "usr": 13892793056005362145, - "detailed_name": "enum B {\n}", + "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", "kind": 10, diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 1233becc1..09991182c 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -15,7 +15,7 @@ const VarType Holder::static_var; "usr2func": [], "usr2type": [{ "usr": 5792006888140599735, - "detailed_name": "enum VarType {\n}", + "detailed_name": "enum VarType {}", "qual_name_offset": 5, "short_name": "VarType", "kind": 10, diff --git a/src/clang_complete.cc b/src/clang_complete.cc index c062071be..3cd01988c 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -354,14 +354,15 @@ class CaptureCompletionResults : public CodeCompleteConsumer { unsigned NumResults) override { ls_items.reserve(NumResults); for (unsigned i = 0; i != NumResults; i++) { - if (Results[i].Availability == CXAvailability_NotAccessible || - Results[i].Availability == CXAvailability_NotAvailable) + auto &R = Results[i]; + if (R.Availability == CXAvailability_NotAccessible || + R.Availability == CXAvailability_NotAvailable) continue; - CodeCompletionString *CCS = Results[i].CreateCodeCompletionString( + CodeCompletionString *CCS = R.CreateCodeCompletionString( S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); lsCompletionItem ls_item; - ls_item.kind = GetCompletionKind(Results[i].CursorKind); + ls_item.kind = GetCompletionKind(R.CursorKind); if (const char *brief = CCS->getBriefComment()) ls_item.documentation = brief; diff --git a/src/indexer.cc b/src/indexer.cc index d08936579..5c8993424 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -462,6 +462,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { std::string name = OS.str(); SimplifyAnonymous(name); + // Remove \n in DeclPrinter.cpp "{\n" + if(!TerseOutput)something + "}" + for (std::string::size_type i = 0;;) { + if ((i = name.find("{\n}", i)) == std::string::npos) + break; + name.replace(i, 3, "{}"); + } auto i = name.find(short_name); if (short_name.size()) while (i != std::string::npos && ((i && isalnum(name[i - 1])) || From 5cc3006a3ada2ef78044c3072d8da1d0d96d118a Mon Sep 17 00:00:00 2001 From: scturtle Date: Thu, 30 Aug 2018 23:47:48 +0800 Subject: [PATCH 185/378] Filter deps with `index.blacklist`. (#64) --- src/pipeline.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pipeline.cc b/src/pipeline.cc index 30c3e9782..1754540ad 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -153,7 +153,7 @@ std::unique_ptr RawCacheLoad(const std::string &path) { } bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, - Project *project, VFS *vfs) { + Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -167,6 +167,11 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, return false; } + if (std::string reason; !matcher.IsMatch(request.path, &reason)) { + LOG_S(INFO) << "skip " << request.path << " for " << reason; + return false; + } + Project::Entry entry; { std::lock_guard lock(project->mutex_); @@ -259,6 +264,12 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, std::string path = curr->path; if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; + if (std::string reason; !matcher.IsMatch(path, &reason)) { + LOG_S(INFO) << "skip emitting and storing index of " << path << " for " + << reason; + continue; + } + LOG_S(INFO) << "emit index for " << path; prev = RawCacheLoad(path); @@ -307,8 +318,9 @@ void Init() { void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, WorkingFiles *working_files) { + GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); while (true) - if (!Indexer_Parse(diag_pub, working_files, project, vfs)) + if (!Indexer_Parse(diag_pub, working_files, project, vfs, matcher)) indexer_waiter->Wait(index_request); } From 407c7cc29d009d92ba29eedbbd128d0731fe07c5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 30 Aug 2018 00:29:08 -0700 Subject: [PATCH 186/378] Remove ASTUnit from indexer and clean up --- index_tests/_empty_test.cc | 8 +--- src/clang_complete.cc | 44 +++++------------- src/clang_tu.cc | 17 +++++++ src/clang_tu.h | 5 ++ src/indexer.cc | 95 ++++++++++++-------------------------- src/indexer.h | 2 - src/pipeline.cc | 6 --- src/project.cc | 3 -- src/test.cc | 34 -------------- 9 files changed, 65 insertions(+), 149 deletions(-) diff --git a/index_tests/_empty_test.cc b/index_tests/_empty_test.cc index d1ae7a6c4..228b26748 100644 --- a/index_tests/_empty_test.cc +++ b/index_tests/_empty_test.cc @@ -1,10 +1,4 @@ /* OUTPUT: -{ - "includes": [], - "skipped_ranges": [], - "usr2func": [], - "usr2type": [], - "usr2var": [] -} +{} */ diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 3cd01988c..cc15089af 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -21,7 +21,6 @@ limitations under the License. #include "platform.h" #include -#include #include #include #include @@ -397,10 +396,6 @@ class CaptureCompletionResults : public CodeCompleteConsumer { } } - void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) override {} - CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } @@ -484,30 +479,10 @@ class StoreDiags : public DiagnosticConsumer { } }; -std::unique_ptr -buildCompilerInvocation(const std::vector &args, - IntrusiveRefCntPtr VFS) { - std::vector cargs; - for (auto &arg : args) - cargs.push_back(arg.c_str()); - IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); - std::unique_ptr CI = - createInvocationFromCommandLine(cargs, Diags, VFS); - if (CI) { - CI->getFrontendOpts().DisableFree = false; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; - CI->getLangOpts()->SpellChecking = false; - } - return CI; -} - -std::unique_ptr -BuildCompilerInstance(CompletionSession &session, - std::unique_ptr CI, - DiagnosticConsumer &DC, - const WorkingFiles::Snapshot &snapshot, - std::vector> &Bufs) { +std::unique_ptr BuildCompilerInstance( + CompletionSession &session, std::unique_ptr CI, + DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, + std::vector> &Bufs) { for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); if (file.filename == session.file.filename) { @@ -570,7 +545,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) { LOG_S(INFO) << "create completion session for " << session->file.filename; if (std::unique_ptr CI = - buildCompilerInvocation(args, session->FS)) + BuildCompilerInvocation(args, session->FS)) session->BuildPreamble(*CI); } } @@ -595,10 +570,12 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { true /*create_if_needed*/); std::unique_ptr CI = - buildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; + CI->getDiagnosticOpts().IgnoreWarnings = true; clang::CodeCompleteOptions CCOpts; + CCOpts.IncludeBriefComments = true; #if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; #endif @@ -608,6 +585,8 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { FOpts.CodeCompletionAt.FileName = session->file.filename; FOpts.CodeCompletionAt.Line = request->position.line + 1; FOpts.CodeCompletionAt.Column = request->position.character + 1; + FOpts.SkipFunctionBodies = true; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; StoreDiags DC; WorkingFiles::Snapshot snapshot = @@ -641,7 +620,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { path, true /*mark_as_completion*/, true /*create_if_needed*/); std::unique_ptr CI = - buildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; StoreDiags DC; @@ -701,6 +680,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; CI.getFrontendOpts().SkipFunctionBodies = true; + CI.getLangOpts()->CommentOpts.ParseAllComments = true; #if LLVM_VERSION_MAJOR >= 7 CI.getPreprocessorOpts().WriteCommentListToPCH = false; #endif diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 3cb09e0e5..be2f16793 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -63,3 +63,20 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R), UniqueID); } + +std::unique_ptr +BuildCompilerInvocation(const std::vector &args, + IntrusiveRefCntPtr VFS) { + std::vector cargs; + for (auto &arg : args) + cargs.push_back(arg.c_str()); + IntrusiveRefCntPtr Diags( + CompilerInstance::createDiagnostics(new DiagnosticOptions)); + std::unique_ptr CI = + createInvocationFromCommandLine(cargs, Diags, VFS); + if (CI) { + CI->getFrontendOpts().DisableFree = false; + CI->getLangOpts()->SpellChecking = false; + } + return CI; +} diff --git a/src/clang_tu.h b/src/clang_tu.h index 7d2b4b732..ec4b57707 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -18,6 +18,7 @@ limitations under the License. #include #include +#include #include @@ -33,3 +34,7 @@ Range FromCharRange(const clang::SourceManager &SM, Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); + +std::unique_ptr +BuildCompilerInvocation(const std::vector &args, + llvm::IntrusiveRefCntPtr VFS); diff --git a/src/indexer.cc b/src/indexer.cc index 5c8993424..ae53369fb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -22,8 +22,6 @@ limitations under the License. using ccls::Intern; #include -#include -#include #include #include #include @@ -57,13 +55,10 @@ struct IndexParam { }; std::unordered_map Decl2Info; - ASTUnit &Unit; ASTContext *Ctx; - FileConsumer *file_consumer = nullptr; - IndexParam(ASTUnit &Unit, FileConsumer *file_consumer) - : Unit(Unit), file_consumer(file_consumer) {} + IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {} IndexFile *ConsumeFile(const FileEntry &File) { IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents); @@ -1173,21 +1168,15 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, if (!g_config->index.enabled) return {}; - std::vector Args; - for (auto &arg : args) - Args.push_back(arg.c_str()); - auto PCHCO = std::make_shared(); - IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); - std::shared_ptr CI = - createInvocationFromCommandLine(Args, Diags); + auto PCH = std::make_shared(); + llvm::IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); + std::shared_ptr CI = BuildCompilerInvocation(args, FS); if (!CI) return {}; // -fparse-all-comments enables documentation in the indexer and in // code completion. if (g_config->index.comments > 1) CI->getLangOpts()->CommentOpts.ParseAllComments = true; - CI->getLangOpts()->SpellChecking = false; { // FileSystemOptions& FSOpts = CI->getFileSystemOpts(); // if (FSOpts.WorkingDir.empty()) @@ -1200,20 +1189,18 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, // HSOpts.ResourceDir = g_config->clang.resourceDir; } - std::vector> BufOwner; - for (auto &c : file_contents) { - std::unique_ptr MB = - llvm::MemoryBuffer::getMemBufferCopy(c.content, c.path); - CI->getPreprocessorOpts().addRemappedFile(c.path, MB.get()); - BufOwner.push_back(std::move(MB)); - } - - auto Unit = ASTUnit::create(CI, Diags, true, true); - if (!Unit) + DiagnosticConsumer DC; + auto Clang = std::make_unique(PCH); + Clang->setInvocation(std::move(CI)); + Clang->setVirtualFileSystem(FS); + Clang->createDiagnostics(&DC, false); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); + if (!Clang->hasTarget()) return {}; FileConsumer file_consumer(vfs, file); - IndexParam param(*Unit, &file_consumer); + IndexParam param(&file_consumer); auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; @@ -1224,36 +1211,30 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, IndexOpts.IndexImplicitInstantiation = true; #endif - std::unique_ptr IndexAction = createIndexingAction( + std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); - DiagnosticErrorTrap DiagTrap(*Diags); - llvm::CrashRecoveryContext CRC; - auto compile = [&]() { - ASTUnit::LoadFromCompilerInvocationAction( - std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), - /*Persistent=*/true, /*ResourceDir=*/"", - /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, - /*UserFilesAreVolatile=*/true); - }; - if (!CRC.RunSafely(compile)) { - LOG_S(ERROR) << "clang crashed for " << file; - return {}; + bool ok = false; + { + llvm::CrashRecoveryContext CRC; + auto parse = [&]() { + if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) + return; + if (!Action->Execute()) + return; + Action->EndSourceFile(); + ok = true; + }; + if (!CRC.RunSafely(parse)) { + LOG_S(ERROR) << "clang crashed for " << file; + return {}; + } } - if (!Unit) { + if (!ok) { LOG_S(ERROR) << "failed to index " << file; return {}; } - const SourceManager &SM = Unit->getSourceManager(); - const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID()); - IndexFile *main_file = param.ConsumeFile(*FE); - std::unordered_map inc_to_line; - if (main_file) - for (auto &inc : main_file->includes) - inc_to_line[inc.resolved_path] = inc.line; - auto result = param.file_consumer->TakeLocalState(); for (std::unique_ptr &entry : result) { entry->import_file = file; @@ -1276,22 +1257,6 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, for (auto &it : entry->usr2var) Uniquify(it.second.uses); - if (main_file) { - // If there are errors, show at least one at the include position. - auto it = inc_to_line.find(entry->path); - if (it != inc_to_line.end()) { - int line = it->second; - for (auto ls_diagnostic : entry->diagnostics_) { - if (ls_diagnostic.severity != lsDiagnosticSeverity::Error) - continue; - ls_diagnostic.range = - lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; - main_file->diagnostics_.push_back(ls_diagnostic); - break; - } - } - } - // Update file contents and modification time. entry->last_write_time = param.file2write_time[entry->path]; diff --git a/src/indexer.h b/src/indexer.h index 151bb0b08..70a407a53 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -263,8 +263,6 @@ struct IndexFile { std::unordered_map usr2type; std::unordered_map usr2var; - // Diagnostics found when indexing this file. Not serialized. - std::vector diagnostics_; // File contents at the time of index. Not serialized. std::string file_contents; diff --git a/src/pipeline.cc b/src/pipeline.cc index 1754540ad..e6f9b750c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -255,12 +255,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, } for (std::unique_ptr &curr : indexes) { - // Only emit diagnostics for non-interactive sessions, which makes it easier - // to identify indexing problems. For interactive sessions, diagnostics are - // handled by code completion. - if (!request.is_interactive) - diag_pub->Publish(working_files, curr->path, curr->diagnostics_); - std::string path = curr->path; if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; diff --git a/src/project.cc b/src/project.cc index 581a8a1b6..d7d6e3a57 100644 --- a/src/project.cc +++ b/src/project.cc @@ -128,9 +128,6 @@ struct ProjectProcessor { args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-working-directory=" + entry.directory); - // There could be a clang version mismatch between what the project uses and - // what ccls uses. Make sure we do not emit warnings for mismatched options. - args.push_back("-Wno-unknown-warning-option"); if (!command_set.insert(hash).second) { entry.args = std::move(args); diff --git a/src/test.cc b/src/test.cc index d2fb971a1..b93a21b99 100644 --- a/src/test.cc +++ b/src/test.cc @@ -307,42 +307,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { const std::string &expected_path = entry.first; std::string expected_output = text_replacer.Apply(entry.second); - // FIXME: promote to utils, find and remove duplicates (ie, - // ccls_call_tree.cc, maybe something in project.cc). - auto basename = [](const std::string &path) -> std::string { - size_t last_index = path.find_last_of('/'); - if (last_index == std::string::npos) - return path; - return path.substr(last_index + 1); - }; - // Get output from index operation. IndexFile *db = FindDbForPathEnding(expected_path, dbs); - if (db && !db->diagnostics_.empty()) { - printf("For %s\n", path.c_str()); - for (const lsDiagnostic &diagnostic : db->diagnostics_) { - printf(" "); - if (diagnostic.severity) - switch (*diagnostic.severity) { - case lsDiagnosticSeverity::Error: - printf("error "); - break; - case lsDiagnosticSeverity::Warning: - printf("warning "); - break; - case lsDiagnosticSeverity::Information: - printf("information "); - break; - case lsDiagnosticSeverity::Hint: - printf("hint "); - break; - } - printf("%s:%s-%s:%s\n", basename(db->path).c_str(), - diagnostic.range.start.ToString().c_str(), - diagnostic.range.end.ToString().c_str(), - diagnostic.message.c_str()); - } - } std::string actual_output = "{}"; if (db) { VerifySerializeToFrom(db); From 11e92d52a898cde8cb788390034a033441e4ba12 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 1 Sep 2018 15:37:09 -0700 Subject: [PATCH 187/378] README --- README.md | 29 ++++++++++++++++++----------- src/pipeline.cc | 3 --- src/serializer.cc | 6 +++--- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4f041e871..1f85d442d 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,21 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery), is a C/C++/Objective-C language server. * code completion (with both signature help and snippets) - * [definition](src/messages/text_document_definition.cc)/[references](src/messages/text_document_references.cc), and other cross references - * [call (caller/callee) hierarchy](src/messages/ccls_call_hierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance_hierarchy.cc), [member hierarchy](src/messages/ccls_member_hierarchy.cc) - * [symbol rename](src/messages/text_document_rename.cc) - * [document symbols](src/messages/text_document_document_symbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) - * [hover information](src/messages/text_document_hover.cc) - * diagnostics - * code actions (clang FixIts) - * preprocessor skipped regions - * semantic highlighting, including support for [rainbow semantic highlighting](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e) - -It makes use of C++17 features, has less third-party dependencies and slimmed-down code base. Cross reference features are strengthened, (see [wiki/FAQ](../../wiki/FAQ)). It currently uses libclang to index C++ code but will switch to Clang C++ API. Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. + * [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDcument_references.cc), and other cross references + * hierarchies: [call (caller/callee) hierarchy](src/messages/ccls_callHierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritanceHierarchy.cc), [member hierarchy](src/messages/ccls_memberHierarchy.cc) + * [symbol rename](src/messages/text_documentRename.cc) + * [document symbols](src/messages/textDocument_documentSymbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) + * [hover information](src/messages/textDocument_hover.cc) + * diagnostics and code actions (clang FixIts) + * semantic highlighting and preprocessor skipped regions + +It has a global view of the code base and support a lot of cross reference features, see [wiki/FAQ](../../wiki/FAQ). +It starts indexing the whole project (including subprojects if exist) parallelly when you open the first file, while the main thread can serve requests before the indexing is complete. +Saving files will incrementally update the index. + +Compared with cquery, it makes use of C++17 features, has less third-party dependencies and slimmed-down code base. +It leverages Clang C++ API as [clangd](https://clang.llvm.org/extra/clangd.html) does, which provides better support for code completion and diagnostics. +Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. The comparison with cquery as noted on 2018-07-15: @@ -35,4 +39,7 @@ cquery has system include path detection (through running the compiler driver) w * [Build](../../wiki/Build) * [Emacs](../../wiki/Emacs) +* [LanguageClient-neovim](../../wiki/LanguageClient-neovim) * [FAQ](../../wiki/FAQ) + +ccls can index itself (~180MiB RSS when ide, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See [wiki/compile_commands.json](../../wiki/compile_commands.json) for examples. diff --git a/src/pipeline.cc b/src/pipeline.cc index e6f9b750c..89eca5662 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -270,13 +270,10 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, // Write current index to disk if requested. LOG_S(INFO) << "store index for " << path; { - static Timer timer("write", "store index"); - timer.startTimer(); std::string cache_path = GetCachePath(path); WriteToFile(cache_path, curr->file_contents); WriteToFile(AppendSerializationFormat(cache_path), Serialize(g_config->cacheFormat, *curr)); - timer.stopTimer(); } vfs->Reset(path); diff --git a/src/serializer.cc b/src/serializer.cc index e99b3815e..487650b0a 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -324,9 +324,9 @@ template void Reflect(TVisitor &visitor, IndexFile &value) { REFLECT_MEMBER_END(); } -void Reflect(Reader &visitor, SerializeFormat &value) { - std::string fmt = visitor.GetString(); - value = fmt[0] == 'b' ? SerializeFormat::Binary : SerializeFormat::Json; +void Reflect(Reader &vis, SerializeFormat &v) { + v = vis.GetString()[0] == 'j' ? SerializeFormat::Json + : SerializeFormat::Binary; } void Reflect(Writer &visitor, SerializeFormat &value) { From 145630ba1ad6c8132578f300b2eeb67cfec19a64 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 2 Sep 2018 14:51:25 -0700 Subject: [PATCH 188/378] Fix unaligned load/store; add index.multiVersion prototype, rename index.onParse to index.OnOpen Don't call getFieldOffset() on RD->isInvalidDecl() --- src/config.h | 22 +++--- src/indexer.cc | 101 ++++++++++++++++----------- src/indexer.h | 2 +- src/language.h | 2 +- src/messages/textDocument_didOpen.cc | 2 +- src/query.cc | 2 +- src/serializers/binary.h | 7 +- 7 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/config.h b/src/config.h index ab5eb5eb5..67cf09725 100644 --- a/src/config.h +++ b/src/config.h @@ -149,8 +149,8 @@ struct Config { // xxx: at most every xxx milliseconds int frequencyMs = 0; - // If true, diagnostics from a full document parse will be reported. - bool onParse = true; + // If true, diagnostics will be reported in textDocument/didOpen. + bool onOpen = true; // If true, diagnostics from typing will be reported. bool onType = true; @@ -171,14 +171,6 @@ struct Config { } highlight; struct Index { - // Attempt to convert calls of make* functions to constructors based on - // hueristics. - // - // For example, this will show constructor calls for std::make_unique - // invocations. Specifically, ccls will try to attribute a ctor call - // whenever the function name starts with make (ignoring case). - 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. @@ -196,6 +188,9 @@ struct Config { // If false, the indexer will be disabled. bool enabled = true; + // If not 0, a file will be indexed in each tranlation unit that includes it. + int multiVersion = 0; + // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onDidChange = false; @@ -238,12 +233,11 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, detailedLabel, filterAndSort, includeBlacklist, includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); -MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onParse, +MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onOpen, onType, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) -MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist, - comments, enabled, onDidChange, reparseForDependency, - threads, whitelist); +MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, + onDidChange, reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, diff --git a/src/indexer.cc b/src/indexer.cc index ae53369fb..581b1baff 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -60,9 +60,7 @@ struct IndexParam { IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {} - IndexFile *ConsumeFile(const FileEntry &File) { - IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents); - + void SeenFile(const FileEntry &File) { // If this is the first time we have seen the file (ignoring if we are // generating an index for it): auto [it, inserted] = SeenUniqueID.try_emplace(File.getUniqueID()); @@ -77,8 +75,11 @@ struct IndexParam { if (write_time) file2write_time[file_name] = *write_time; } + } - return db; + IndexFile *ConsumeFile(const FileEntry &File) { + SeenFile(File); + return file_consumer->TryConsumeFile(File, &file_contents); } }; @@ -407,20 +408,20 @@ class IndexDataConsumer : public index::IndexDataConsumer { return it->second.usr; } - Use GetUse(IndexFile *db, Range range, const DeclContext *DC, + Use GetUse(IndexFile *db, int lid, Range range, const DeclContext *DC, Role role) const { if (!DC) - return Use{{range, 0, SymbolKind::File, role}}; + return {{range, 0, SymbolKind::File, role}, lid}; const Decl *D = cast(DC); switch (GetSymbolKind(D)) { case SymbolKind::Func: - return Use{{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}}; + return {{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}, lid}; case SymbolKind::Type: - return Use{{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}}; + return {{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}, lid}; case SymbolKind::Var: - return Use{{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}}; + return {{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}, lid}; default: - return Use{{range, 0, SymbolKind::File, role}}; + return {{range, 0, SymbolKind::File, role}, lid}; } } @@ -550,26 +551,32 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } - void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, - SourceLocation Spell) const { - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); - if (!FE) - return; - auto UID = FE->getUniqueID(); - auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID); + static int GetFileLID(IndexFile *db, SourceManager &SM, const FileEntry &FE) { + auto [it, inserted] = db->uid2lid_and_path.try_emplace(FE.getUniqueID()); if (inserted) { it->second.first = db->uid2lid_and_path.size() - 1; - SmallString<256> Path = FE->tryGetRealPathName(); + SmallString<256> Path = FE.tryGetRealPathName(); if (Path.empty()) - Path = FE->getName(); + Path = FE.getName(); if (!llvm::sys::path::is_absolute(Path) && !SM.getFileManager().makeAbsolutePath(Path)) - return; + return -1; it->second.second = Path.str(); } + return it->second.first; + } + + void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, + SourceLocation Spell) const { + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); + if (!FE) + return; + int lid = GetFileLID(db, SM, *FE); + if (lid < 0) + return; Range spell = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); - Use use{{spell, 0, SymbolKind::File, Role::Dynamic}, it->second.first}; + Use use{{spell, 0, SymbolKind::File, Role::Dynamic}, lid}; switch (kind) { case SymbolKind::Func: db->ToFunc(usr).uses.push_back(use); @@ -630,15 +637,26 @@ class IndexDataConsumer : public index::IndexDataConsumer { FE = SM.getFileEntryForID(LocFID); if (!FE) return true; - IndexFile *db = param.ConsumeFile(*FE); - if (!db) - return true; + int lid = -1; + IndexFile *db; + if (g_config->index.multiVersion) { + db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID())); + if (!db) + return true; + param.SeenFile(*FE); + if (!SM.isInMainFile(R.getBegin())) + lid = GetFileLID(db, SM, *FE); + } else { + db = param.ConsumeFile(*FE); + if (!db) + return true; + } const Decl *OrigD = ASTNode.OrigD; const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *LexDC = ASTNode.ContainerDC; Role role = static_cast(Roles); - db->language = std::max(db->language, GetDeclLanguage(OrigD)); + db->language = LanguageId((int)db->language | (int)GetDeclLanguage(OrigD)); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); @@ -653,18 +671,18 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto do_def_decl = [&](auto *entity) { if (is_def) { - entity->def.spell = GetUse(db, loc, SemDC, role); + entity->def.spell = GetUse(db, lid, loc, SemDC, role); SourceRange R = OrigD->getSourceRange(); entity->def.extent = - GetUse(db, + GetUse(db, lid, R.getBegin().isFileID() ? FromTokenRange(SM, Lang, OrigD->getSourceRange()) : loc, LexDC, Role::None); } else if (is_decl) { - entity->declarations.push_back(GetUse(db, loc, LexDC, role)); + entity->declarations.push_back(GetUse(db, lid, loc, LexDC, role)); } else { - entity->uses.push_back(GetUse(db, loc, LexDC, role)); + entity->uses.push_back(GetUse(db, lid, loc, LexDC, role)); return; } if (entity->def.comments[0] == '\0' && g_config->index.comments) @@ -750,10 +768,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (SM.getFileID(R1.getBegin()) == LocFID) { IndexType &type1 = db->ToType(usr1); SourceLocation L1 = D1->getLocation(); - type1.def.spell = GetUse(db, FromTokenRange(SM, Lang, {L1, L1}), - SemDC, Role::Definition); - type1.def.extent = - GetUse(db, FromTokenRange(SM, Lang, R1), LexDC, Role::None); + type1.def.spell = + GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, + Role::Definition); + type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), + LexDC, Role::None); type1.def.detailed_name = Intern(info1->short_name); type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.kind = lsSymbolKind::TypeParameter; @@ -768,10 +787,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { // e.g. lambda parameter SourceLocation L = OrigD->getLocation(); if (SM.getFileID(L) == LocFID) { - var->def.spell = GetUse(db, FromTokenRange(SM, Lang, {L, L}), SemDC, - Role::Definition); + var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}), + SemDC, Role::Definition); var->def.extent = - GetUse(db, FromTokenRange(SM, Lang, OrigD->getSourceRange()), + GetUse(db, lid, FromTokenRange(SM, Lang, OrigD->getSourceRange()), LexDC, Role::None); } } @@ -868,10 +887,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { std::tie(RD, offset) = Stack.back(); Stack.pop_back(); if (!RD->isCompleteDefinition() || RD->isDependentType() || - !ValidateRecord(RD)) + RD->isInvalidDecl() || !ValidateRecord(RD)) offset = -1; for (FieldDecl *FD : RD->fields()) { - int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; + int offset1 = offset < 0 ? -1 : offset + Ctx->getFieldOffset(FD); if (FD->getIdentifier()) type->def.vars.emplace_back(GetUsr(FD), offset1); else if (const auto *RT1 = FD->getType()->getAs()) { @@ -928,7 +947,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); if (SM.getFileID(L1) == LocFID) { Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); - type1.uses.push_back(GetUse(db, loc1, LexDC, Role::Reference)); + type1.uses.push_back( + GetUse(db, lid, loc1, LexDC, Role::Reference)); } } } @@ -1081,8 +1101,7 @@ class IndexPPCallbacks : public PPCallbacks { if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { - auto [Name, usr] = GetMacro(Tok); - IndexVar &var = db->ToVar(usr); + IndexVar &var = db->ToVar(GetMacro(Tok).second); var.uses.push_back( {{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), 0, SymbolKind::File, Role::Dynamic}}); diff --git a/src/indexer.h b/src/indexer.h index 70a407a53..d1b1e7125 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -241,7 +241,7 @@ struct IndexFile { std::string path; std::vector args; int64_t last_write_time = 0; - LanguageId language = LanguageId::Unknown; + LanguageId language = LanguageId::C; // uid2lid_and_path is used to generate lid2path, but not serialized. std::unordered_map> diff --git a/src/language.h b/src/language.h index 846185b57..d53b79203 100644 --- a/src/language.h +++ b/src/language.h @@ -22,7 +22,7 @@ limitations under the License. // Used to identify the language at a file level. The ordering is important, as // a file previously identified as `C`, will be changed to `Cpp` if it // encounters a c++ declaration. -enum class LanguageId { Unknown = 0, C = 1, Cpp = 2, ObjC = 3, ObjCpp = 4 }; +enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 }; MAKE_REFLECT_TYPE_PROXY(LanguageId); LanguageId SourceFileLanguage(std::string_view path); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index c9d63e8ea..8120f4be5 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -78,7 +78,7 @@ struct Handler_TextDocumentDidOpen } clang_complete->NotifyView(path); - if (g_config->diagnostics.onParse) + if (g_config->diagnostics.onOpen) clang_complete->DiagnosticsUpdate({params.textDocument.uri}); } }; diff --git a/src/query.cc b/src/query.cc index 026aacf94..1ce07c5fa 100644 --- a/src/query.cc +++ b/src/query.cc @@ -29,7 +29,7 @@ limitations under the License. namespace { -void AssignFileId(const Lid2file_id &, int file_id, SymbolRef &ref) { +void AssignFileId(const Lid2file_id &lid2file_id, int file_id, SymbolRef &ref) { if (ref.kind == SymbolKind::File) ref.usr = file_id; } diff --git a/src/serializers/binary.h b/src/serializers/binary.h index 1b86fac8c..a1c9266fa 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -17,13 +17,14 @@ limitations under the License. #include "serializer.h" -#include +#include class BinaryReader : public Reader { const char *p_; template T Get() { - auto ret = *reinterpret_cast(p_); + T ret; + memcpy(&ret, p_, sizeof(T)); p_ += sizeof(T); return ret; } @@ -89,7 +90,7 @@ class BinaryWriter : public Writer { template void Pack(T x) { auto i = buf_.size(); buf_.resize(i + sizeof(x)); - *reinterpret_cast(buf_.data() + i) = x; + memcpy(buf_.data() + i, &x, sizeof(x)); } void VarUInt(uint64_t n) { From a33f4df404a9a129e566a65b3fea0bab3ce9b809 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 2 Sep 2018 19:11:10 -0700 Subject: [PATCH 189/378] index.multiVersion: int Before, QueryFile::Def::{all_symbols,outline} were built by indexers. Now, {symbol,outline}2refcnt are used instead, built by main thread. *_removed are augmented with Query*:Def to allow removal of old {symbol,outline}2refcnt entries. --- src/indexer.cc | 6 +- src/message_handler.cc | 4 +- src/messages/ccls_fileInfo.cc | 4 +- src/messages/textDocument_codeLens.cc | 3 +- src/messages/textDocument_definition.cc | 10 +- src/messages/textDocument_documentSymbol.cc | 19 +- src/query.cc | 252 ++++++++++---------- src/query.h | 31 ++- src/query_utils.cc | 25 +- 9 files changed, 181 insertions(+), 173 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 581b1baff..4f3849e2a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -77,9 +77,9 @@ struct IndexParam { } } - IndexFile *ConsumeFile(const FileEntry &File) { - SeenFile(File); - return file_consumer->TryConsumeFile(File, &file_contents); + IndexFile *ConsumeFile(const FileEntry &FE) { + SeenFile(FE); + return file_consumer->TryConsumeFile(FE, &file_contents); } }; diff --git a/src/message_handler.cc b/src/message_handler.cc index 706bfe91b..f4d6aae03 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -209,7 +209,9 @@ void EmitSemanticHighlighting(DB *db, // Group symbols together. std::unordered_map grouped_symbols; - for (SymbolRef sym : file->def->all_symbols) { + for (auto &sym_refcnt : file->symbol2refcnt) { + if (sym_refcnt.second <= 0) continue; + SymbolRef sym = sym_refcnt.first; std::string_view detailed_name; lsSymbolKind parent_kind = lsSymbolKind::Unknown; lsSymbolKind kind = lsSymbolKind::Unknown; diff --git a/src/messages/ccls_fileInfo.cc b/src/messages/ccls_fileInfo.cc index 493d7b27f..5e4f546ac 100644 --- a/src/messages/ccls_fileInfo.cc +++ b/src/messages/ccls_fileInfo.cc @@ -18,8 +18,8 @@ limitations under the License. #include "query_utils.h" using namespace ccls; -MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, outline, all_symbols, - skipped_ranges, dependencies); +MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, + dependencies); namespace { MethodType kMethodType = "$ccls/fileInfo"; diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index e28928e48..0410c32cc 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -116,7 +116,8 @@ struct Handler_TextDocumentCodeLens common.working_files = working_files; common.working_file = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : file->def->outline) { + for (auto [sym, refcnt] : file->outline2refcnt) { + if (refcnt <= 0) continue; // NOTE: We OffsetColumn so that the code lens always show up in a // predictable order. Otherwise, the client may randomize it. Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id}; diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 7794bfd14..234a0a166 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -117,12 +117,14 @@ struct Handler_TextDocumentDefinition } auto locs = GetLsLocationExs(db, working_files, uses); out.result.insert(out.result.end(), locs.begin(), locs.end()); - if (!out.result.empty()) - break; } - // No symbols - check for includes. - if (out.result.empty()) { + if (out.result.size()) { + std::sort(out.result.begin(), out.result.end()); + out.result.erase(std::unique(out.result.begin(), out.result.end()), + out.result.end()); + } else { + // Check #include for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { lsLocationEx result; diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 2704d9141..51199c0cc 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -65,20 +65,20 @@ struct Handler_TextDocumentDocumentSymbol if (params.startLine >= 0) { Out_SimpleDocumentSymbol out; out.id = request->id; - for (SymbolRef sym : file->def->all_symbols) - if (std::optional location = GetLsLocation( - db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { - if (params.startLine <= sym.range.start.line && - sym.range.start.line <= params.endLine) - out.result.push_back(location->range); - } + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && params.startLine <= sym.range.start.line && + sym.range.start.line <= params.endLine) + if (auto ls_loc = GetLsLocation( + db, working_files, + Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) + out.result.push_back(ls_loc->range); std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); } else { Out_TextDocumentDocumentSymbol out; out.id = request->id; - for (SymbolRef sym : file->def->outline) + for (auto [sym, refcnt] : file->outline2refcnt) { + if (refcnt <= 0) continue; if (std::optional info = GetSymbolInfo(db, working_files, sym, false)) { if (sym.kind == SymbolKind::Var) { @@ -94,6 +94,7 @@ struct Handler_TextDocumentDocumentSymbol out.result.push_back(*info); } } + } pipeline::WriteStdout(kMethodType, out); } } diff --git a/src/query.cc b/src/query.cc index 1ce07c5fa..7b349061d 100644 --- a/src/query.cc +++ b/src/query.cc @@ -29,34 +29,13 @@ limitations under the License. namespace { -void AssignFileId(const Lid2file_id &lid2file_id, int file_id, SymbolRef &ref) { - if (ref.kind == SymbolKind::File) - ref.usr = file_id; -} - void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) { - if (use.kind == SymbolKind::File) - use.usr = file_id; if (use.file_id == -1) use.file_id = file_id; else use.file_id = lid2file_id.find(use.file_id)->second; -} - -template -void AssignFileId(const Lid2file_id &, int file_id, T &) {} - -template -void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Maybe &x) { - if (x) - AssignFileId(lid2file_id, file_id, *x); -} - -template -void AssignFileId(const Lid2file_id &lid2file_id, int file_id, - std::vector &xs) { - for (T &x : xs) - AssignFileId(lid2file_id, file_id, x); + if (use.kind == SymbolKind::File) + use.usr = use.file_id; } void AddRange(std::vector &into, const std::vector &from) { @@ -90,79 +69,6 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile &indexed) { for (auto &dep : indexed.dependencies) def.dependencies.push_back(dep.first()); def.language = indexed.language; - - auto add_all_symbols = [&](Use use, Usr usr, SymbolKind kind) { - def.all_symbols.push_back(SymbolRef{{use.range, usr, kind, use.role}}); - }; - auto add_outline = [&](Use use, Usr usr, SymbolKind kind) { - def.outline.push_back(SymbolRef{{use.range, usr, kind, use.role}}); - }; - - for (auto &it : indexed.usr2type) { - const IndexType &type = it.second; - if (type.def.spell) - add_all_symbols(*type.def.spell, type.usr, SymbolKind::Type); - if (type.def.extent) - add_outline(*type.def.extent, type.usr, SymbolKind::Type); - for (Use decl : type.declarations) { - add_all_symbols(decl, type.usr, SymbolKind::Type); - // Constructor positions have references to the class, - // which we do not want to show in textDocument/documentSymbol - if (!(decl.role & Role::Reference)) - add_outline(decl, type.usr, SymbolKind::Type); - } - for (Use use : type.uses) - if (use.file_id == -1) - add_all_symbols(use, type.usr, SymbolKind::Type); - } - for (auto &it : indexed.usr2func) { - const IndexFunc &func = it.second; - if (func.def.spell) - add_all_symbols(*func.def.spell, func.usr, SymbolKind::Func); - if (func.def.extent) - add_outline(*func.def.extent, func.usr, SymbolKind::Func); - for (Use use : func.declarations) { - add_all_symbols(use, func.usr, SymbolKind::Func); - add_outline(use, func.usr, SymbolKind::Func); - } - for (Use use : func.uses) - if (use.file_id == -1) { - // Make ranges of implicit function calls larger (spanning one more - // column to the left/right). This is hacky but useful. e.g. - // textDocument/definition on the space/semicolon in `A a;` or `return - // 42;` will take you to the constructor. - if (use.role & Role::Implicit) { - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; - } - add_all_symbols(use, func.usr, SymbolKind::Func); - } - } - for (auto &it : indexed.usr2var) { - const IndexVar &var = it.second; - if (var.def.spell) - add_all_symbols(*var.def.spell, var.usr, SymbolKind::Var); - if (var.def.extent) - add_outline(*var.def.extent, var.usr, SymbolKind::Var); - for (Use decl : var.declarations) { - add_all_symbols(decl, var.usr, SymbolKind::Var); - add_outline(decl, var.usr, SymbolKind::Var); - } - for (Use use : var.uses) - if (use.file_id == -1) - add_all_symbols(use, var.usr, SymbolKind::Var); - } - - std::sort(def.outline.begin(), def.outline.end(), - [](const SymbolRef &a, const SymbolRef &b) { - return a.range.start < b.range.start; - }); - std::sort(def.all_symbols.begin(), def.all_symbols.end(), - [](const SymbolRef &a, const SymbolRef &b) { - return a.range.start < b.range.start; - }); - return {std::move(def), std::move(indexed.file_contents)}; } @@ -194,7 +100,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { for (auto &it : previous->usr2func) { auto &func = it.second; if (func.def.detailed_name[0]) - r.funcs_removed.push_back(func.usr); + r.funcs_removed.emplace_back(func.usr, func.def); r.funcs_declarations[func.usr].first = std::move(func.declarations); r.funcs_uses[func.usr].first = std::move(func.uses); r.funcs_derived[func.usr].first = std::move(func.derived); @@ -212,7 +118,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { for (auto &it : previous->usr2type) { auto &type = it.second; if (type.def.detailed_name[0]) - r.types_removed.push_back(type.usr); + r.types_removed.emplace_back(type.usr, type.def); r.types_declarations[type.usr].first = std::move(type.declarations); r.types_uses[type.usr].first = std::move(type.uses); r.types_derived[type.usr].first = std::move(type.derived); @@ -232,7 +138,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { for (auto &it : previous->usr2var) { auto &var = it.second; if (var.def.detailed_name[0]) - r.vars_removed.push_back(var.usr); + r.vars_removed.emplace_back(var.usr, var.def); r.vars_declarations[var.usr].first = std::move(var.declarations); r.vars_uses[var.usr].first = std::move(var.uses); } @@ -247,11 +153,12 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { return r; } +template void DB::RemoveUsrs(SymbolKind kind, int file_id, - const std::vector &to_remove) { + const std::vector> &to_remove) { switch (kind) { case SymbolKind::Func: { - for (Usr usr : to_remove) { + for (auto &[usr, _] : to_remove) { // FIXME if (!HasFunc(usr)) continue; @@ -265,7 +172,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id, break; } case SymbolKind::Type: { - for (Usr usr : to_remove) { + for (auto &[usr, _] : to_remove) { // FIXME if (!HasType(usr)) continue; @@ -279,7 +186,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id, break; } case SymbolKind::Var: { - for (Usr usr : to_remove) { + for (auto &[usr, _] : to_remove) { // FIXME if (!HasVar(usr)) continue; @@ -304,43 +211,68 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { if (R.second) \ C##s.emplace_back().usr = it.first; \ auto &entity = C##s[R.first->second]; \ - AssignFileId(prev_lid2file_id, u->file_id, it.second.first); \ RemoveRange(entity.F, it.second.first); \ - AssignFileId(lid2file_id, u->file_id, it.second.second); \ AddRange(entity.F, it.second.second); \ } std::unordered_map prev_lid2file_id, lid2file_id; for (auto &[lid, path] : u->prev_lid2path) prev_lid2file_id[lid] = GetFileId(path); - for (auto &[lid, path] : u->lid2path) - lid2file_id[lid] = GetFileId(path); + for (auto &[lid, path] : u->lid2path) { + int file_id = GetFileId(path); + lid2file_id[lid] = file_id; + if (!files[file_id].def) { + files[file_id].def = QueryFile::Def(); + files[file_id].def->path = path; + } + } + + // References (Use &use) in this function are important to update file_id. + auto Ref = [&](std::unordered_map &lid2fid, Usr usr, + SymbolKind kind, Use &use, int delta) { + use.file_id = + use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; + int &v = + files[use.file_id] + .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]; + v += delta; + assert(v >= 0); + }; + auto RefO = [&](std::unordered_map &lid2fid, Usr usr, + SymbolKind kind, Use &use, int delta) { + use.file_id = + use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; + files[use.file_id] + .outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta; + }; auto UpdateUses = [&](Usr usr, SymbolKind kind, llvm::DenseMap &entity_usr, - auto &entities, auto &p) { + auto &entities, auto &p, bool hint_implicit) { auto R = entity_usr.try_emplace({usr}, entity_usr.size()); if (R.second) vars.emplace_back().usr = usr; auto &entity = entities[R.first->second]; for (Use &use : p.first) { - if (use.file_id == -1) - use.file_id = u->file_id; - else { - use.file_id = prev_lid2file_id.find(use.file_id)->second; - files[use.file_id] - .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]--; + if (hint_implicit && use.role & Role::Implicit) { + // Make ranges of implicit function calls larger (spanning one more + // column to the left/right). This is hacky but useful. e.g. + // textDocument/definition on the space/semicolon in `A a;` or ` 42;` + // will take you to the constructor. + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; } + Ref(prev_lid2file_id, usr, kind, use, -1); } RemoveRange(entity.uses, p.first); for (Use &use : p.second) { - if (use.file_id == -1) - use.file_id = u->file_id; - else { - use.file_id = lid2file_id.find(use.file_id)->second; - files[use.file_id] - .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]++; + if (hint_implicit && use.role & Role::Implicit) { + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; } + Ref(lid2file_id, usr, kind, use, 1); } AddRange(entity.uses, p.second); }; @@ -359,36 +291,72 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { funcs.reserve(t); func_usr.reserve(t); } + for (auto &[usr, def] : u->funcs_removed) { + if (def.spell) + Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); + if (def.extent) + RefO(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1); + } RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); + for (auto &[usr, del_add]: u->funcs_declarations) { + for (Use &use : del_add.first) + Ref(prev_lid2file_id, usr, SymbolKind::Func, use, -1); + for (Use &use : del_add.second) + Ref(lid2file_id, usr, SymbolKind::Func, use, 1); + } REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); for (auto &[usr, p] : u->funcs_uses) - UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p); + UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p, true); if ((t = types.size() + u->types_hint) > types.capacity()) { t = size_t(t * grow); types.reserve(t); type_usr.reserve(t); } + for (auto &[usr, def] : u->types_removed) { + if (def.spell) + Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); + if (def.extent) + RefO(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1); + } RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); Update(lid2file_id, u->file_id, std::move(u->types_def_update)); + for (auto &[usr, del_add]: u->types_declarations) { + for (Use &use : del_add.first) + Ref(prev_lid2file_id, usr, SymbolKind::Type, use, -1); + for (Use &use : del_add.second) + Ref(lid2file_id, usr, SymbolKind::Type, use, 1); + } REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); REMOVE_ADD(type, instances); for (auto &[usr, p] : u->types_uses) - UpdateUses(usr, SymbolKind::Type, type_usr, types, p); + UpdateUses(usr, SymbolKind::Type, type_usr, types, p, false); if ((t = vars.size() + u->vars_hint) > vars.capacity()) { t = size_t(t * grow); vars.reserve(t); var_usr.reserve(t); } + for (auto &[usr, def] : u->vars_removed) { + if (def.spell) + Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); + if (def.extent) + RefO(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1); + } RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); + for (auto &[usr, del_add]: u->vars_declarations) { + for (Use &use : del_add.first) + Ref(prev_lid2file_id, usr, SymbolKind::Var, use, -1); + for (Use &use : del_add.second) + Ref(lid2file_id, usr, SymbolKind::Var, use, 1); + } REMOVE_ADD(var, declarations); for (auto &[usr, p] : u->vars_uses) - UpdateUses(usr, SymbolKind::Var, var_usr, vars, p); + UpdateUses(usr, SymbolKind::Var, var_usr, vars, p, false); #undef REMOVE_ADD } @@ -414,9 +382,17 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; - AssignFileId(lid2file_id, file_id, def.spell); - AssignFileId(lid2file_id, file_id, def.extent); - AssignFileId(lid2file_id, file_id, def.callees); + if (def.spell) { + AssignFileId(lid2file_id, file_id, *def.spell); + files[def.spell->file_id].symbol2refcnt[{ + {def.spell->range, u.first, SymbolKind::Func, def.spell->role}}]++; + } + if (def.extent) { + AssignFileId(lid2file_id, file_id, *def.extent); + files[def.extent->file_id].outline2refcnt[{ + {def.extent->range, u.first, SymbolKind::Func, def.extent->role}}]++; + } + auto R = func_usr.try_emplace({u.first}, func_usr.size()); if (R.second) funcs.emplace_back(); @@ -433,8 +409,16 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; - AssignFileId(lid2file_id, file_id, def.spell); - AssignFileId(lid2file_id, file_id, def.extent); + if (def.spell) { + AssignFileId(lid2file_id, file_id, *def.spell); + files[def.spell->file_id].symbol2refcnt[{ + {def.spell->range, u.first, SymbolKind::Type, def.spell->role}}]++; + } + if (def.extent) { + AssignFileId(lid2file_id, file_id, *def.extent); + files[def.extent->file_id].outline2refcnt[{ + {def.extent->range, u.first, SymbolKind::Type, def.extent->role}}]++; + } auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) types.emplace_back(); @@ -451,8 +435,16 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, auto &def = u.second; assert(def.detailed_name[0]); u.second.file_id = file_id; - AssignFileId(lid2file_id, file_id, def.spell); - AssignFileId(lid2file_id, file_id, def.extent); + if (def.spell) { + AssignFileId(lid2file_id, file_id, *def.spell); + files[def.spell->file_id].symbol2refcnt[{ + {def.spell->range, u.first, SymbolKind::Var, def.spell->role}}]++; + } + if (def.extent) { + AssignFileId(lid2file_id, file_id, *def.extent); + files[def.extent->file_id].outline2refcnt[{ + {def.extent->range, u.first, SymbolKind::Var, def.extent->role}}]++; + } auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) vars.emplace_back(); diff --git a/src/query.h b/src/query.h index 1513da0f0..5f0a5d240 100644 --- a/src/query.h +++ b/src/query.h @@ -21,6 +21,21 @@ limitations under the License. #include #include +namespace llvm { +template <> struct DenseMapInfo { + static inline SymbolRef getEmptyKey() { return {}; } + static inline SymbolRef getTombstoneKey() { + SymbolRef ret{}; + ret.usr = -1; + return ret; + } + static unsigned getHashValue(SymbolRef sym) { + return std::hash()(sym); + } + static bool isEqual(SymbolRef l, SymbolRef r) { return l == r; } +}; +} + struct QueryFile { struct Def { std::string path; @@ -28,10 +43,6 @@ struct QueryFile { LanguageId language; // Includes in the file. std::vector includes; - // Outline of the file (ie, for code lens). - std::vector outline; - // Every symbol found in the file (ie, for goto definition) - std::vector all_symbols; // Parts of the file which are disabled. std::vector skipped_ranges; // Used by |$ccls/freshenIndex|. @@ -42,7 +53,8 @@ struct QueryFile { int id = -1; std::optional def; - std::unordered_map symbol2refcnt; + llvm::DenseMap symbol2refcnt; + llvm::DenseMap outline2refcnt; }; template struct QueryEntity { @@ -109,7 +121,7 @@ struct IndexUpdate { // Function updates. int funcs_hint; - std::vector funcs_removed; + std::vector> funcs_removed; std::vector> funcs_def_update; UseUpdate funcs_declarations; UseUpdate funcs_uses; @@ -117,7 +129,7 @@ struct IndexUpdate { // Type updates. int types_hint; - std::vector types_removed; + std::vector> types_removed; std::vector> types_def_update; UseUpdate types_declarations; UseUpdate types_uses; @@ -126,7 +138,7 @@ struct IndexUpdate { // Variable updates. int vars_hint; - std::vector vars_removed; + std::vector> vars_removed; std::vector> vars_def_update; UseUpdate vars_declarations; UseUpdate vars_uses; @@ -154,8 +166,9 @@ struct DB { std::vector types; std::vector vars; + template void RemoveUsrs(SymbolKind kind, int file_id, - const std::vector &to_remove); + const std::vector> &to_remove); // Insert the contents of |update| into |db|. void ApplyIndexUpdate(IndexUpdate *update); int GetFileId(const std::string &path); diff --git a/src/query_utils.cc b/src/query_utils.cc index 23349d7ce..c4fdc5d70 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -159,29 +159,28 @@ std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { return ret; } -std::optional GetLsPosition(WorkingFile *working_file, +std::optional GetLsPosition(WorkingFile *wfile, const Position &position) { - if (!working_file) + if (!wfile || wfile->index_lines.empty()) return lsPosition{position.line, position.column}; int column = position.column; if (std::optional start = - working_file->GetBufferPosFromIndexPos(position.line, &column, false)) + wfile->GetBufferPosFromIndexPos(position.line, &column, false)) return lsPosition{*start, column}; return std::nullopt; } -std::optional GetLsRange(WorkingFile *working_file, +std::optional GetLsRange(WorkingFile *wfile, const Range &location) { - if (!working_file) { + if (!wfile || wfile->index_lines.empty()) return lsRange{lsPosition{location.start.line, location.start.column}, lsPosition{location.end.line, location.end.column}}; - } int start_column = location.start.column, end_column = location.end.column; - std::optional start = working_file->GetBufferPosFromIndexPos( + std::optional start = wfile->GetBufferPosFromIndexPos( location.start.line, &start_column, false); - std::optional end = working_file->GetBufferPosFromIndexPos( + std::optional end = wfile->GetBufferPosFromIndexPos( location.end.line, &end_column, true); if (!start || !end) return std::nullopt; @@ -315,12 +314,13 @@ std::optional GetSymbolInfo(DB *db, return std::nullopt; } -std::vector FindSymbolsAtLocation(WorkingFile *working_file, +std::vector FindSymbolsAtLocation(WorkingFile *wfile, QueryFile *file, lsPosition &ls_pos) { std::vector symbols; - if (working_file) { - if (auto line = working_file->GetIndexPosFromBufferPos( + // If multiVersion > 0, index may not exist and thus index_lines is empty. + if (wfile && wfile->index_lines.size()) { + if (auto line = wfile->GetIndexPosFromBufferPos( ls_pos.line, &ls_pos.character, false)) { ls_pos.line = *line; } else { @@ -329,9 +329,6 @@ std::vector FindSymbolsAtLocation(WorkingFile *working_file, } } - for (SymbolRef sym : file->def->all_symbols) - if (sym.range.Contains(ls_pos.line, ls_pos.character)) - symbols.push_back(sym); for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && sym.range.Contains(ls_pos.line, ls_pos.character)) symbols.push_back(sym); From aebf2dfaed4f0e7e92b21312d87ae1cbcb3fafff Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 3 Sep 2018 12:21:32 -0700 Subject: [PATCH 190/378] Add index.multiVersion{Black,White}list They allow files matching specified patterns to be indexed only once even if index.multiVersion > 0. An example is to exclude system headers with index.multiVersionBlacklist: ["^/usr/include"] --- src/config.h | 8 +++++++- src/indexer.cc | 18 +++++++++++++++++- src/indexer.h | 1 + src/messages/initialize.cc | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/config.h b/src/config.h index 67cf09725..c22a99f80 100644 --- a/src/config.h +++ b/src/config.h @@ -191,6 +191,11 @@ struct Config { // If not 0, a file will be indexed in each tranlation unit that includes it. int multiVersion = 0; + // If multiVersion != 0, files that match blacklist but not whitelist will + // still only be indexed for one version. + std::vector multiVersionBlacklist; + std::vector multiVersionWhitelist; + // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onDidChange = false; @@ -237,7 +242,8 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onOpen, onType, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, - onDidChange, reparseForDependency, threads, whitelist); + multiVersionBlacklist, multiVersionWhitelist, onDidChange, + reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, diff --git a/src/indexer.cc b/src/indexer.cc index 4f3849e2a..ff711a0c7 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -17,6 +17,7 @@ limitations under the License. #include "clang_tu.h" #include "log.hh" +#include "match.h" #include "platform.h" #include "serializer.h" using ccls::Intern; @@ -44,8 +45,11 @@ namespace { constexpr int kInitializerMaxLines = 3; +GroupMatch *multiVersionMatcher; + struct IndexParam { std::unordered_map SeenUniqueID; + std::unordered_map UID2multi; std::unordered_map file_contents; std::unordered_map file2write_time; struct DeclInfo { @@ -81,6 +85,13 @@ struct IndexParam { SeenFile(FE); return file_consumer->TryConsumeFile(FE, &file_contents); } + + bool UseMultiVersion(const FileEntry &FE) { + auto it = UID2multi.try_emplace(FE.getUniqueID()); + if (it.second) + it.first->second = multiVersionMatcher->IsMatch(FileName(FE)); + return it.first->second; + } }; StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, @@ -639,7 +650,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; int lid = -1; IndexFile *db; - if (g_config->index.multiVersion) { + if (g_config->index.multiVersion && param.UseMultiVersion(*FE)) { db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID())); if (!db) return true; @@ -1180,6 +1191,11 @@ template void Uniquify(std::vector &a) { } namespace ccls::idx { +void Init() { + multiVersionMatcher = new GroupMatch(g_config->index.multiVersionWhitelist, + g_config->index.multiVersionBlacklist); +} + std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/indexer.h b/src/indexer.h index d1b1e7125..355b5a984 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -277,6 +277,7 @@ struct IndexFile { }; namespace ccls::idx { +void Init(); std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index b687b6a9e..cfbca19ea 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -478,6 +478,7 @@ struct Handler_Initialize : BaseMessageHandler { EscapeFileName(g_config->projectRoot)); diag_pub->Init(); + idx::Init(); semantic_cache->Init(); // Open up / load the project. From e92378df9c58aa1519dff62e207c055cd45c6249 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 3 Sep 2018 14:17:03 -0700 Subject: [PATCH 191/378] Add all: boolean to textDocument/documentSymbol --- src/messages/textDocument_documentSymbol.cc | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 51199c0cc..53b639600 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -22,17 +22,19 @@ using namespace clang; namespace { MethodType kMethodType = "textDocument/documentSymbol"; -struct lsDocumentSymbolParams { - lsTextDocumentIdentifier textDocument; - int startLine = -1; - int endLine = -1; -}; -MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument, startLine, endLine); - struct In_TextDocumentDocumentSymbol : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } - lsDocumentSymbolParams params; + struct Params { + lsTextDocumentIdentifier textDocument; + // false: outline; true: all symbols + bool all = false; + // If >= 0, return Range[] instead of SymbolInformation[] to reduce output. + int startLine = -1; + int endLine = -1; + } params; }; +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol::Params, textDocument, all, + startLine, endLine); MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); @@ -62,10 +64,12 @@ struct Handler_TextDocumentDocumentSymbol params.textDocument.uri.GetPath(), &file, &file_id)) return; + const auto &symbol2refcnt = + params.all ? file->symbol2refcnt : file->outline2refcnt; if (params.startLine >= 0) { Out_SimpleDocumentSymbol out; out.id = request->id; - for (auto [sym, refcnt] : file->symbol2refcnt) + for (auto [sym, refcnt] : symbol2refcnt) if (refcnt > 0 && params.startLine <= sym.range.start.line && sym.range.start.line <= params.endLine) if (auto ls_loc = GetLsLocation( @@ -77,7 +81,7 @@ struct Handler_TextDocumentDocumentSymbol } else { Out_TextDocumentDocumentSymbol out; out.id = request->id; - for (auto [sym, refcnt] : file->outline2refcnt) { + for (auto [sym, refcnt] : symbol2refcnt) { if (refcnt <= 0) continue; if (std::optional info = GetSymbolInfo(db, working_files, sym, false)) { From 0a51424c5cdcd32be128129150e34d32462f3725 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 3 Sep 2018 15:08:34 -0700 Subject: [PATCH 192/378] Add $ccls/navigate and improve textDocument/definition --- CMakeLists.txt | 1 + src/messages/ccls_navigate.cc | 115 ++++++++++++++++++++++++ src/messages/textDocument_definition.cc | 11 ++- src/position.h | 1 + 4 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 src/messages/ccls_navigate.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index b202db78b..d48f36b67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,6 +216,7 @@ target_sources(ccls PRIVATE src/messages/ccls_freshenIndex.cc src/messages/ccls_inheritanceHierarchy.cc src/messages/ccls_memberHierarchy.cc + src/messages/ccls_navigate.cc src/messages/ccls_vars.cc src/messages/exit.cc src/messages/initialize.cc diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc new file mode 100644 index 000000000..921ffae11 --- /dev/null +++ b/src/messages/ccls_navigate.cc @@ -0,0 +1,115 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "message_handler.h" +#include "pipeline.hh" +#include "query_utils.h" +using namespace ccls; + +namespace { +MethodType kMethodType = "$ccls/navigate"; + +struct In_CclsNavigate : public RequestInMessage { + MethodType GetMethodType() const override { return kMethodType; } + struct Params { + lsTextDocumentIdentifier textDocument; + lsPosition position; + std::string direction; + } params; +}; +MAKE_REFLECT_STRUCT(In_CclsNavigate::Params, textDocument, position, direction); +MAKE_REFLECT_STRUCT(In_CclsNavigate, id, params); +REGISTER_IN_MESSAGE(In_CclsNavigate); + +struct Handler_CclsNavigate : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } + void Run(In_CclsNavigate *request) override { + auto ¶ms = request->params; + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + params.textDocument.uri.GetPath(), &file)) + return; + + WorkingFile *wfile = + working_files->GetFileByFilename(file->def->path); + lsPosition ls_pos = request->params.position; + if (wfile && wfile->index_lines.size()) + if (auto line = wfile->GetIndexPosFromBufferPos( + ls_pos.line, &ls_pos.character, false)) + ls_pos.line = *line; + Position pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; + + Maybe res; + switch (params.direction[0]) { + case 'D': { + Maybe parent; + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && sym.range.start <= pos && pos < sym.range.end && + (!parent || parent->start < sym.range.start)) + parent = sym.range; + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && pos < sym.range.start && + (!parent || sym.range.end <= parent->end) && + (!res || sym.range.start < res->start)) + res = sym.range; + break; + } + case 'L': + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && sym.range.end <= pos && + (!res || (res->end == sym.range.end ? sym.range.start < res->start + : res->end < sym.range.end))) + res = sym.range; + break; + case 'R': { + Maybe parent; + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && sym.range.start <= pos && pos < sym.range.end && + (!parent || parent->start < sym.range.start)) + parent = sym.range; + if (parent && parent->start.line == pos.line && pos < parent->end) { + pos = parent->end; + if (pos.column) + pos.column--; + } + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && pos < sym.range.start && + (!res || + (sym.range.start == res->start ? res->end < sym.range.end + : sym.range.start < res->start))) + res = sym.range; + break; + } + case 'U': + default: + for (auto [sym, refcnt] : file->outline2refcnt) + if (refcnt > 0 && sym.range.start < pos && pos < sym.range.end && + (!res || res->start < sym.range.start)) + res = sym.range; + break; + } + Out_LocationList out; + out.id = request->id; + if (res) + if (auto ls_range = GetLsRange(wfile, *res)) { + lsLocationEx &ls_loc = out.result.emplace_back(); + ls_loc.uri = params.textDocument.uri; + ls_loc.range = *ls_range; + } + pipeline::WriteStdout(kMethodType, out); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_CclsNavigate); +} // namespace diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 234a0a166..1b616c80c 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -75,14 +75,17 @@ struct Handler_TextDocumentDefinition Out_TextDocumentDefinition out; out.id = request->id; + Maybe range; Maybe on_def; - bool has_symbol = false; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); lsPosition &ls_pos = params.position; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { + if (!range) + range = sym.range; + else if (!(*range == sym.range)) + break; // Found symbol. Return definition. - has_symbol = true; // Special cases which are handled: // - symbol has declaration but no definition (ie, pure virtual) @@ -130,12 +133,12 @@ struct Handler_TextDocumentDefinition lsLocationEx result; result.uri = lsDocumentUri::FromPath(include.resolved_path); out.result.push_back(result); - has_symbol = true; + range = {{0, 0}, {0, 0}}; break; } } // Find the best match of the identifier at point. - if (!has_symbol) { + if (!range) { lsPosition position = request->params.position; const std::string &buffer = wfile->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); diff --git a/src/position.h b/src/position.h index 110676ca8..5ff535155 100644 --- a/src/position.h +++ b/src/position.h @@ -40,6 +40,7 @@ struct Position { return line < o.line; return column < o.column; } + bool operator<=(const Position &o) const { return !(o < *this); } }; MAKE_HASHABLE(Position, t.line, t.column); From 56da577df92281fc04c34785041037c06e686510 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 4 Sep 2018 13:02:48 -0700 Subject: [PATCH 193/378] Add clang.excludeArgs and rename diagnostics.onType to onChange --- src/clang_complete.cc | 2 +- src/config.h | 17 ++++++++++------- src/project.cc | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index cc15089af..39bc03c87 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -612,7 +612,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = manager->diagnostic_request_.Dequeue(); - if (!g_config->diagnostics.onType) + if (!g_config->diagnostics.onChange) continue; std::string path = request.document.uri.GetPath(); diff --git a/src/config.h b/src/config.h index c22a99f80..3e22a0e94 100644 --- a/src/config.h +++ b/src/config.h @@ -59,6 +59,9 @@ struct Config { SerializeFormat cacheFormat = SerializeFormat::Binary; struct Clang { + // Arguments that should be excluded, e.g. ["-fopenmp", "-Wall"] + std::vector excludeArgs; + // Additional arguments to pass to clang. std::vector extraArgs; @@ -149,11 +152,11 @@ struct Config { // xxx: at most every xxx milliseconds int frequencyMs = 0; - // If true, diagnostics will be reported in textDocument/didOpen. - bool onOpen = true; + // If true, diagnostics will be reported for textDocument/didChange. + bool onChange = true; - // If true, diagnostics from typing will be reported. - bool onType = true; + // If true, diagnostics will be reported for textDocument/didOpen. + bool onOpen = true; std::vector whitelist; } diagnostics; @@ -231,15 +234,15 @@ struct Config { int maxNum = 2000; } xref; }; -MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir); +MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, resourceDir); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, detailedLabel, filterAndSort, includeBlacklist, includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); -MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onOpen, - onType, whitelist) +MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, + onOpen, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onDidChange, diff --git a/src/project.cc b/src/project.cc index d7d6e3a57..c25e97c9b 100644 --- a/src/project.cc +++ b/src/project.cc @@ -32,6 +32,7 @@ using namespace ccls; #include #include #include +#include #include #include using namespace clang; @@ -96,7 +97,7 @@ struct ProjectProcessor { args.push_back(arg.substr(5)); } else if (arg == "%clang") { args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); - } else { + } else if (!llvm::is_contained(g_config->clang.excludeArgs, arg)) { args.push_back(arg); } } From b77fba6ea854f594d76ea9f092a607e351fa83d2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 6 Sep 2018 00:22:40 -0700 Subject: [PATCH 194/378] Improve hover and documentSymbol --- src/messages/textDocument_hover.cc | 5 ++++ src/query.cc | 40 ++++++++++++++---------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 71dd0919a..a368f846a 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -36,6 +36,11 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { break; } } + if (!def && entity.def.size()) { + def = &entity.def[0]; + if (def->comments[0]) + comments = def->comments; + } if (def) { lsMarkedString m; m.language = LanguageIdentifier(lang); diff --git a/src/query.cc b/src/query.cc index 7b349061d..88a7e809f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -229,21 +229,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { // References (Use &use) in this function are important to update file_id. auto Ref = [&](std::unordered_map &lid2fid, Usr usr, - SymbolKind kind, Use &use, int delta) { + SymbolKind kind, Use &use, int delta, int k = 1) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; - int &v = - files[use.file_id] + if (k & 1) { + int &v = + files[use.file_id] .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]; - v += delta; - assert(v >= 0); - }; - auto RefO = [&](std::unordered_map &lid2fid, Usr usr, - SymbolKind kind, Use &use, int delta) { - use.file_id = - use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; - files[use.file_id] - .outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta; + v += delta; + assert(v >= 0); + } + if (k & 2) + files[use.file_id] + .outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta; }; auto UpdateUses = [&](Usr usr, SymbolKind kind, @@ -295,15 +293,15 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { if (def.spell) Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); if (def.extent) - RefO(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1, 2); } RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); for (auto &[usr, del_add]: u->funcs_declarations) { for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Func, use, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Func, use, -1, 3); for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Func, use, 1); + Ref(lid2file_id, usr, SymbolKind::Func, use, 1, 3); } REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); @@ -319,15 +317,15 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { if (def.spell) Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); if (def.extent) - RefO(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1, 2); } RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); Update(lid2file_id, u->file_id, std::move(u->types_def_update)); for (auto &[usr, del_add]: u->types_declarations) { for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Type, use, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Type, use, -1, 3); for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Type, use, 1); + Ref(lid2file_id, usr, SymbolKind::Type, use, 1, 3); } REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); @@ -344,15 +342,15 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { if (def.spell) Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); if (def.extent) - RefO(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1, 2); } RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); for (auto &[usr, del_add]: u->vars_declarations) { for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Var, use, -1); + Ref(prev_lid2file_id, usr, SymbolKind::Var, use, -1, 3); for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Var, use, 1); + Ref(lid2file_id, usr, SymbolKind::Var, use, 1, 3); } REMOVE_ADD(var, declarations); for (auto &[usr, p] : u->vars_uses) From 8b3ebf234b6b1aeaeee8d6d6c5ccc86da51910aa Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 7 Sep 2018 14:38:08 -0700 Subject: [PATCH 195/378] Remove $ccls/base and clean up; deduplicate codeLens --- CMakeLists.txt | 1 - src/clang_complete.cc | 14 +++--- src/indexer.cc | 1 - src/messages/ccls_base.cc | 66 --------------------------- src/messages/ccls_callHierarchy.cc | 1 - src/messages/textDocument_codeLens.cc | 24 +++++----- 6 files changed, 19 insertions(+), 88 deletions(-) delete mode 100644 src/messages/ccls_base.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d48f36b67..9574aad8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,6 @@ target_sources(ccls PRIVATE ) target_sources(ccls PRIVATE - src/messages/ccls_base.cc src/messages/ccls_callHierarchy.cc src/messages/ccls_callers.cc src/messages/ccls_fileInfo.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 39bc03c87..4d6613af7 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -550,7 +550,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) { } } -void CompletionQueryMain(ClangCompleteManager *completion_manager) { +void CompletionMain(ClangCompleteManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. std::unique_ptr request = @@ -588,7 +588,7 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { FOpts.SkipFunctionBodies = true; CI->getLangOpts()->CommentOpts.ParseAllComments = true; - StoreDiags DC; + DiagnosticConsumer DC; WorkingFiles::Snapshot snapshot = completion_manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; @@ -607,7 +607,7 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { } } -void DiagnosticQueryMain(ClangCompleteManager *manager) { +void DiagnosticMain(ClangCompleteManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = @@ -709,8 +709,8 @@ ClangCompleteManager::ClangCompleteManager(Project *project, completion_sessions_(kMaxCompletionSessions), PCH(std::make_shared()) { std::thread([&]() { - set_thread_name("comp-query"); - ccls::CompletionQueryMain(this); + set_thread_name("comp"); + ccls::CompletionMain(this); }) .detach(); std::thread([&]() { @@ -719,8 +719,8 @@ ClangCompleteManager::ClangCompleteManager(Project *project, }) .detach(); std::thread([&]() { - set_thread_name("diag-query"); - ccls::DiagnosticQueryMain(this); + set_thread_name("diag"); + ccls::DiagnosticMain(this); }) .detach(); } diff --git a/src/indexer.cc b/src/indexer.cc index ff711a0c7..ce53ad164 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1014,7 +1014,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::EnumConstant: var->def.kind = lsSymbolKind::EnumMember; - // TODO Pretty printer may print = if (is_def && strchr(var->def.detailed_name, '=') == nullptr) { auto *ECD = cast(D); const auto &Val = ECD->getInitVal(); diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc deleted file mode 100644 index b5f2b8bb3..000000000 --- a/src/messages/ccls_base.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -namespace { - -MethodType kMethodType = "$ccls/base"; - -struct In_CclsBase : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_CclsBase, id, params); -REGISTER_IN_MESSAGE(In_CclsBase); - -struct Handler_CclsBase : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_CclsBase *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - Out_LocationList out; - out.id = request->id; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - if (sym.kind == SymbolKind::Type) { - if (const auto *def = db->GetType(sym).AnyDef()) - out.result = GetLsLocationExs(db, working_files, - GetTypeDeclarations(db, def->bases)); - break; - } else if (sym.kind == SymbolKind::Func) { - if (const auto *def = db->GetFunc(sym).AnyDef()) - out.result = GetLsLocationExs(db, working_files, - GetFuncDeclarations(db, def->bases)); - break; - } - } - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsBase); -} // namespace diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_callHierarchy.cc index 8b139eb4a..ce593425d 100644 --- a/src/messages/ccls_callHierarchy.cc +++ b/src/messages/ccls_callHierarchy.cc @@ -15,7 +15,6 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" -using namespace ccls; #include "query_utils.h" using namespace ccls; diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index 0410c32cc..730441e74 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -20,19 +20,19 @@ limitations under the License. #include "query_utils.h" using namespace ccls; +#include + namespace { MethodType kMethodType = "textDocument/codeLens"; -struct lsDocumentCodeLensParams { - lsTextDocumentIdentifier textDocument; -}; -MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument); - using TCodeLens = lsCodeLens; struct In_TextDocumentCodeLens : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } - lsDocumentCodeLensParams params; + struct Params { + lsTextDocumentIdentifier textDocument; + } params; }; +MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens::Params, textDocument); MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens, id, params); REGISTER_IN_MESSAGE(In_TextDocumentCodeLens); @@ -96,19 +96,17 @@ struct Handler_TextDocumentCodeLens : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentCodeLens *request) override { + auto ¶ms = request->params; Out_TextDocumentCodeLens out; out.id = request->id; - lsDocumentUri file_as_uri = request->params.textDocument.uri; - std::string path = file_as_uri.GetPath(); - + std::string path = params.textDocument.uri.GetPath(); clang_complete->NotifyView(path); QueryFile *file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { + params.textDocument.uri.GetPath(), &file)) return; - } CommonCodeLensParams common; common.result = &out.result; @@ -116,8 +114,10 @@ struct Handler_TextDocumentCodeLens common.working_files = working_files; common.working_file = working_files->GetFileByFilename(file->def->path); + std::unordered_set seen; for (auto [sym, refcnt] : file->outline2refcnt) { - if (refcnt <= 0) continue; + if (refcnt <= 0 || !seen.insert(sym.range).second) + continue; // NOTE: We OffsetColumn so that the code lens always show up in a // predictable order. Otherwise, the client may randomize it. Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id}; From e20a8e7a1b5a4c8e9975284e5bae992197a4bb14 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 7 Sep 2018 22:29:36 -0700 Subject: [PATCH 196/378] Add DeclUse as element type of declarations --- index_tests/class_forward_declaration.cc | 6 +- index_tests/constructors/constructor.cc | 24 ++-- index_tests/constructors/destructor.cc | 24 ++-- .../constructors/implicit_constructor.cc | 24 ++-- index_tests/constructors/invalid_reference.cc | 10 +- index_tests/constructors/make_functions.cc | 68 +++++------ .../declaration_vs_definition/class.cc | 6 +- .../declaration_vs_definition/class_member.cc | 8 +- .../class_member_static.cc | 12 +- index_tests/declaration_vs_definition/func.cc | 6 +- .../func_associated_function_params.cc | 14 +-- .../declaration_vs_definition/method.cc | 16 +-- index_tests/enums/enum_class_decl.cc | 16 +-- index_tests/enums/enum_decl.cc | 12 +- index_tests/enums/enum_inherit.cc | 28 ++--- index_tests/enums/enum_usage.cc | 20 +-- index_tests/foobar.cc | 40 +++--- index_tests/function_declaration.cc | 2 +- .../function_declaration_definition.cc | 6 +- index_tests/function_definition.cc | 4 +- index_tests/inheritance/class_inherit.cc | 10 +- .../class_inherit_templated_parent.cc | 30 ++--- .../inheritance/class_multiple_inherit.cc | 22 ++-- index_tests/inheritance/function_override.cc | 16 +-- .../inheritance/interface_pure_virtual.cc | 6 +- .../inheritance/multiple_base_functions.cc | 30 ++--- index_tests/lambdas/lambda.cc | 28 ++--- index_tests/macros/complex.cc | 24 ++-- index_tests/macros/foo.cc | 26 ++-- index_tests/method_declaration.cc | 6 +- index_tests/method_definition.cc | 12 +- index_tests/method_inline_declaration.cc | 8 +- index_tests/multi_file/funky_enum.cc | 16 +-- index_tests/multi_file/impl.cc | 54 ++++----- index_tests/multi_file/simple_impl.cc | 8 +- index_tests/multi_file/static.cc | 12 +- index_tests/namespaces/anonymous_function.cc | 2 +- .../namespaces/function_declaration.cc | 4 +- index_tests/namespaces/function_definition.cc | 6 +- index_tests/namespaces/method_declaration.cc | 8 +- index_tests/namespaces/method_definition.cc | 14 +-- .../namespaces/method_inline_declaration.cc | 10 +- index_tests/namespaces/namespace_alias.cc | 34 +++--- index_tests/namespaces/namespace_reference.cc | 24 ++-- index_tests/operators/operator.cc | 16 +-- .../outline/static_function_in_type.cc | 26 ++-- index_tests/preprocessor/include_guard.cc | 4 +- .../func_specialized_template_param.cc | 18 +-- .../implicit_variable_instantiation.cc | 30 ++--- .../templates/member_ref_in_template.cc | 18 +-- ...ass_template_func_usage_folded_into_one.cc | 22 ++-- ...ace_template_type_usage_folded_into_one.cc | 24 ++-- index_tests/templates/specialization.cc | 114 +++++++++--------- .../templates/specialized_func_definition.cc | 16 +-- ...mplate_class_func_usage_folded_into_one.cc | 20 +-- ...ass_template_func_usage_folded_into_one.cc | 20 +-- ...mplate_class_type_usage_folded_into_one.cc | 40 +++--- ...emplate_class_var_usage_folded_into_one.cc | 18 +-- .../template_func_usage_folded_into_one.cc | 14 +-- .../template_type_usage_folded_into_one.cc | 22 ++-- .../template_var_usage_folded_into_one.cc | 30 ++--- index_tests/types/anonymous_struct.cc | 24 ++-- index_tests/types/typedefs.cc | 8 +- index_tests/unions/union_decl.cc | 12 +- index_tests/unions/union_usage.cc | 26 ++-- .../usage/func_called_from_constructor.cc | 18 +-- .../usage/func_called_from_macro_argument.cc | 14 +-- .../usage/func_called_from_template.cc | 14 +-- .../usage/func_called_implicit_ctor.cc | 20 +-- index_tests/usage/func_usage_addr_func.cc | 20 +-- index_tests/usage/func_usage_addr_method.cc | 18 +-- index_tests/usage/func_usage_call_func.cc | 10 +- index_tests/usage/func_usage_call_method.cc | 20 +-- .../usage/func_usage_class_inline_var_def.cc | 14 +-- .../usage/func_usage_forward_decl_func.cc | 8 +- .../usage/func_usage_forward_decl_method.cc | 20 +-- index_tests/usage/func_usage_template_func.cc | 8 +- .../usage/type_usage_as_template_parameter.cc | 36 +++--- ...ype_usage_as_template_parameter_complex.cc | 48 ++++---- ...type_usage_as_template_parameter_simple.cc | 18 +-- .../usage/type_usage_declare_extern.cc | 8 +- index_tests/usage/type_usage_declare_field.cc | 22 ++-- index_tests/usage/type_usage_declare_local.cc | 22 ++-- index_tests/usage/type_usage_declare_param.cc | 22 ++-- .../type_usage_declare_param_prototype.cc | 14 +-- .../usage/type_usage_declare_param_unnamed.cc | 8 +- .../usage/type_usage_declare_qualifiers.cc | 34 +++--- .../usage/type_usage_declare_static.cc | 10 +- .../usage/type_usage_on_return_type.cc | 36 +++--- .../usage/type_usage_typedef_and_using.cc | 42 +++---- .../type_usage_typedef_and_using_template.cc | 16 +-- index_tests/usage/type_usage_various.cc | 18 +-- index_tests/usage/usage_inside_of_call.cc | 38 +++--- .../usage/usage_inside_of_call_simple.cc | 14 +-- index_tests/usage/var_usage_call_function.cc | 16 +-- index_tests/usage/var_usage_class_member.cc | 36 +++--- .../usage/var_usage_class_member_static.cc | 18 +-- index_tests/usage/var_usage_cstyle_cast.cc | 18 +-- index_tests/usage/var_usage_extern.cc | 8 +- index_tests/usage/var_usage_func_parameter.cc | 10 +- index_tests/usage/var_usage_local.cc | 10 +- index_tests/usage/var_usage_shadowed_local.cc | 16 +-- .../usage/var_usage_shadowed_parameter.cc | 16 +-- index_tests/usage/var_usage_static.cc | 10 +- index_tests/vars/class_member.cc | 10 +- index_tests/vars/class_static_member.cc | 12 +- .../vars/class_static_member_decl_only.cc | 6 +- index_tests/vars/deduce_auto_type.cc | 18 +-- index_tests/vars/function_local.cc | 12 +- index_tests/vars/function_param.cc | 16 +-- index_tests/vars/function_param_unnamed.cc | 4 +- index_tests/vars/function_shadow_local.cc | 16 +-- index_tests/vars/function_shadow_param.cc | 12 +- index_tests/vars/global_variable.cc | 4 +- index_tests/vars/global_variable_decl_only.cc | 2 +- .../vars/type_instance_on_using_type.cc | 20 +-- src/indexer.cc | 64 +++++++--- src/indexer.h | 13 +- src/query.cc | 39 +++--- src/query.h | 15 ++- src/query_utils.cc | 16 ++- 121 files changed, 1177 insertions(+), 1128 deletions(-) diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index fd80cefb5..0da901610 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -15,9 +15,9 @@ class Foo; "qual_name_offset": 6, "short_name": "Foo", "kind": 5, - "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], - "spell": "3:7-3:10|0|1|2", - "extent": "3:1-3:13|0|1|0", + "declarations": ["1:7-1:10|1:1-1:10|0|1|1|-1", "2:7-2:10|2:1-2:10|0|1|1|-1", "4:7-4:10|4:1-4:10|0|1|1|-1"], + "spell": "3:7-3:10|0|1|2|-1", + "extent": "3:1-3:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index cf764596a..72fcaf0dc 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -21,12 +21,12 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|1026", - "extent": "3:3-3:11|15041163540773201510|2|0", + "spell": "3:3-3:6|15041163540773201510|2|1026|-1", + "extent": "3:3-3:11|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["7:7-7:8|4259594751088586730|3|16676", "8:17-8:20|4259594751088586730|3|16676"], + "uses": ["7:7-7:8|4259594751088586730|3|16676|-1", "8:17-8:20|4259594751088586730|3|16676|-1"], "callees": [] }, { "usr": 4259594751088586730, @@ -36,8 +36,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "6:6-6:9|0|1|2", - "extent": "6:1-9:2|0|1|0", + "spell": "6:6-6:9|0|1|2|-1", + "extent": "6:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [10983126130596230582, 17165811951126099095], @@ -51,8 +51,8 @@ void foo() { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -60,7 +60,7 @@ void foo() { "funcs": [3385168158331140247], "vars": [], "instances": [10983126130596230582, 17165811951126099095], - "uses": ["3:3-3:6|15041163540773201510|2|4", "7:3-7:6|4259594751088586730|3|4", "8:3-8:6|4259594751088586730|3|4", "8:17-8:20|4259594751088586730|3|4"] + "uses": ["3:3-3:6|15041163540773201510|2|4|-1", "7:3-7:6|4259594751088586730|3|4|-1", "8:3-8:6|4259594751088586730|3|4|-1", "8:17-8:20|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 10983126130596230582, @@ -68,8 +68,8 @@ void foo() { "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "7:7-7:8|4259594751088586730|3|2", - "extent": "7:3-7:8|4259594751088586730|3|0", + "spell": "7:7-7:8|4259594751088586730|3|2|-1", + "extent": "7:3-7:8|4259594751088586730|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, @@ -81,8 +81,8 @@ void foo() { "short_name": "f2", "hover": "Foo *f2 = new Foo()", "declarations": [], - "spell": "8:8-8:10|4259594751088586730|3|2", - "extent": "8:3-8:22|4259594751088586730|3|0", + "spell": "8:8-8:10|4259594751088586730|3|2|-1", + "extent": "8:3-8:22|4259594751088586730|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index f7724c3b8..3bb394d20 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -26,12 +26,12 @@ void foo() { "kind": 9, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|1026", - "extent": "3:3-3:11|15041163540773201510|2|0", + "spell": "3:3-3:6|15041163540773201510|2|1026|-1", + "extent": "3:3-3:11|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["8:7-8:8|4259594751088586730|3|16676"], + "uses": ["8:7-8:8|4259594751088586730|3|16676|-1"], "callees": [] }, { "usr": 4259594751088586730, @@ -41,8 +41,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "7:6-7:9|0|1|2", - "extent": "7:1-9:2|0|1|0", + "spell": "7:6-7:9|0|1|2|-1", + "extent": "7:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [1893354193220338759], @@ -56,8 +56,8 @@ void foo() { "kind": 6, "storage": 0, "declarations": [], - "spell": "4:3-4:4|15041163540773201510|2|1026", - "extent": "4:3-4:12|15041163540773201510|2|0", + "spell": "4:3-4:4|15041163540773201510|2|1026|-1", + "extent": "4:3-4:12|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -71,8 +71,8 @@ void foo() { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-5:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -80,7 +80,7 @@ void foo() { "funcs": [3385168158331140247, 7440261702884428359], "vars": [], "instances": [1893354193220338759], - "uses": ["3:3-3:6|15041163540773201510|2|4", "4:4-4:7|15041163540773201510|2|4", "8:3-8:6|4259594751088586730|3|4"] + "uses": ["3:3-3:6|15041163540773201510|2|4|-1", "4:4-4:7|15041163540773201510|2|4|-1", "8:3-8:6|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 1893354193220338759, @@ -88,8 +88,8 @@ void foo() { "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "8:7-8:8|4259594751088586730|3|2", - "extent": "8:3-8:8|4259594751088586730|3|0", + "spell": "8:7-8:8|4259594751088586730|3|2|-1", + "extent": "8:3-8:8|4259594751088586730|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index be98be7fd..b3995cfd5 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -20,8 +20,8 @@ void Make() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2", - "extent": "5:1-8:2|0|1|0", + "spell": "5:6-5:10|0|1|2|-1", + "extent": "5:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [449111627548814328, 17097499197730163115], @@ -35,12 +35,12 @@ void Make() { "kind": 9, "storage": 0, "declarations": [], - "spell": "2:3-2:7|13487927231218873822|2|1026", - "extent": "2:3-2:12|13487927231218873822|2|0", + "spell": "2:3-2:7|13487927231218873822|2|1026|-1", + "extent": "2:3-2:12|13487927231218873822|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["6:8-6:12|3957104924306079513|3|16676", "7:15-7:19|3957104924306079513|3|16676"], + "uses": ["6:8-6:12|3957104924306079513|3|16676|-1", "7:15-7:19|3957104924306079513|3|16676|-1"], "callees": [] }], "usr2type": [{ @@ -50,8 +50,8 @@ void Make() { "short_name": "Type", "kind": 23, "declarations": [], - "spell": "1:8-1:12|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:12|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -59,7 +59,7 @@ void Make() { "funcs": [10530961286677896857], "vars": [], "instances": [449111627548814328, 17097499197730163115], - "uses": ["2:3-2:7|13487927231218873822|2|4", "6:3-6:7|3957104924306079513|3|4", "7:15-7:19|3957104924306079513|3|4"] + "uses": ["2:3-2:7|13487927231218873822|2|4|-1", "6:3-6:7|3957104924306079513|3|4|-1", "7:15-7:19|3957104924306079513|3|4|-1"] }], "usr2var": [{ "usr": 449111627548814328, @@ -67,8 +67,8 @@ void Make() { "qual_name_offset": 5, "short_name": "foo0", "declarations": [], - "spell": "6:8-6:12|3957104924306079513|3|2", - "extent": "6:3-6:12|3957104924306079513|3|0", + "spell": "6:8-6:12|3957104924306079513|3|2|-1", + "extent": "6:3-6:12|3957104924306079513|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, @@ -80,8 +80,8 @@ void Make() { "short_name": "foo1", "hover": "Type foo1 = Type()", "declarations": [], - "spell": "7:8-7:12|3957104924306079513|3|2", - "extent": "7:3-7:21|3957104924306079513|3|0", + "spell": "7:8-7:12|3957104924306079513|3|2|-1", + "extent": "7:3-7:21|3957104924306079513|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index c6c933e13..dfb742c2f 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -20,8 +20,8 @@ Foo::Foo() {} "kind": 9, "storage": 0, "declarations": [], - "spell": "4:6-4:9|15041163540773201510|2|1026", - "extent": "4:1-4:11|15041163540773201510|2|0", + "spell": "4:6-4:9|15041163540773201510|2|1026|-1", + "extent": "4:1-4:11|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -35,8 +35,8 @@ Foo::Foo() {} "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-1:14|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-1:14|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -44,7 +44,7 @@ Foo::Foo() {} "funcs": [17319723337446061757], "vars": [], "instances": [], - "uses": ["4:1-4:4|0|1|4", "4:6-4:9|15041163540773201510|2|4"] + "uses": ["4:1-4:4|0|1|4|-1", "4:6-4:9|15041163540773201510|2|4|-1"] }], "usr2var": [] } diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index e2e3be4ca..c285c1d5d 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -36,8 +36,8 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "7:3-7:9|14935975554338052500|2|1026", - "extent": "7:3-7:32|14935975554338052500|2|0", + "spell": "7:3-7:9|14935975554338052500|2|1026|-1", + "extent": "7:3-7:32|14935975554338052500|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -51,8 +51,8 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "6:3-6:9|14935975554338052500|2|1026", - "extent": "6:3-6:17|14935975554338052500|2|0", + "spell": "6:3-6:9|14935975554338052500|2|1026|-1", + "extent": "6:3-6:17|14935975554338052500|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -66,8 +66,8 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "5:3-5:9|14935975554338052500|2|1026", - "extent": "5:3-5:14|14935975554338052500|2|0", + "spell": "5:3-5:9|14935975554338052500|2|1026|-1", + "extent": "5:3-5:14|14935975554338052500|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -81,8 +81,8 @@ OUTPUT: make_functions.h "kind": 9, "storage": 0, "declarations": [], - "spell": "8:3-8:9|14935975554338052500|2|1026", - "extent": "8:3-8:30|14935975554338052500|2|0", + "spell": "8:3-8:9|14935975554338052500|2|1026|-1", + "extent": "8:3-8:30|14935975554338052500|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -96,8 +96,8 @@ OUTPUT: make_functions.h "short_name": "Bar", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-1:14|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-1:14|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -105,7 +105,7 @@ OUTPUT: make_functions.h "funcs": [], "vars": [], "instances": [], - "uses": ["7:17-7:20|14935975554338052500|2|4", "8:15-8:18|14935975554338052500|2|4"] + "uses": ["7:17-7:20|14935975554338052500|2|4|-1", "8:15-8:18|14935975554338052500|2|4|-1"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", @@ -113,8 +113,8 @@ OUTPUT: make_functions.h "short_name": "Foobar", "kind": 5, "declarations": [], - "spell": "3:7-3:13|0|1|2", - "extent": "3:1-9:2|0|1|0", + "spell": "3:7-3:13|0|1|2|-1", + "extent": "3:1-9:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -122,7 +122,7 @@ OUTPUT: make_functions.h "funcs": [13131778807733950299, 13028995015627606181, 3765833212244435302, 17321436359755983845], "vars": [], "instances": [], - "uses": ["5:3-5:9|14935975554338052500|2|4", "6:3-6:9|14935975554338052500|2|4", "7:3-7:9|14935975554338052500|2|4", "8:3-8:9|14935975554338052500|2|4"] + "uses": ["5:3-5:9|14935975554338052500|2|4|-1", "6:3-6:9|14935975554338052500|2|4|-1", "7:3-7:9|14935975554338052500|2|4|-1", "8:3-8:9|14935975554338052500|2|4|-1"] }], "usr2var": [] } @@ -154,12 +154,12 @@ OUTPUT: make_functions.cc "kind": 12, "storage": 0, "declarations": [], - "spell": "9:4-9:15|0|1|2", - "extent": "9:1-11:2|0|1|0", + "spell": "9:4-9:15|0|1|2|-1", + "extent": "9:1-11:2|0|1|0|-1", "bases": [], "derived": [], "vars": [3908732770590594660], - "uses": ["17:3-17:14|2816883305867289955|3|16420"], + "uses": ["17:3-17:14|2816883305867289955|3|16420|-1"], "callees": [] }, { "usr": 2816883305867289955, @@ -169,8 +169,8 @@ OUTPUT: make_functions.cc "kind": 12, "storage": 0, "declarations": [], - "spell": "13:6-13:14|0|1|2", - "extent": "13:1-18:2|0|1|0", + "spell": "13:6-13:14|0|1|2|-1", + "extent": "13:1-18:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -210,12 +210,12 @@ OUTPUT: make_functions.cc "kind": 12, "storage": 0, "declarations": [], - "spell": "4:4-4:14|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:4-4:14|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "bases": [], "derived": [], "vars": [8463700030555379526], - "uses": ["14:3-14:13|2816883305867289955|3|16420", "15:3-15:13|2816883305867289955|3|16420", "16:3-16:13|2816883305867289955|3|16420"], + "uses": ["14:3-14:13|2816883305867289955|3|16420|-1", "15:3-15:13|2816883305867289955|3|16420|-1", "16:3-16:13|2816883305867289955|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -262,7 +262,7 @@ OUTPUT: make_functions.cc "funcs": [], "vars": [], "instances": [], - "uses": ["16:29-16:32|2816883305867289955|3|4", "17:30-17:33|2816883305867289955|3|4"] + "uses": ["16:29-16:32|2816883305867289955|3|4|-1", "17:30-17:33|2816883305867289955|3|4|-1"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", @@ -277,7 +277,7 @@ OUTPUT: make_functions.cc "funcs": [], "vars": [], "instances": [], - "uses": ["14:14-14:20|2816883305867289955|3|4", "15:14-15:20|2816883305867289955|3|4", "16:14-16:20|2816883305867289955|3|4", "17:15-17:21|2816883305867289955|3|4"] + "uses": ["14:14-14:20|2816883305867289955|3|4|-1", "15:14-15:20|2816883305867289955|3|4|-1", "16:14-16:20|2816883305867289955|3|4|-1", "17:15-17:21|2816883305867289955|3|4|-1"] }], "usr2var": [{ "usr": 180270746871803062, @@ -285,8 +285,8 @@ OUTPUT: make_functions.cc "qual_name_offset": 4, "short_name": "args", "declarations": [], - "spell": "9:24-9:28|11363675606380070883|3|1026", - "extent": "9:16-9:28|11363675606380070883|3|0", + "spell": "9:24-9:28|11363675606380070883|3|1026|-1", + "extent": "9:16-9:28|11363675606380070883|3|0|-1", "type": 87, "uses": [], "kind": 253, @@ -297,8 +297,8 @@ OUTPUT: make_functions.cc "qual_name_offset": 6, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|768523651983844320|3|1026", - "extent": "4:15-4:29|768523651983844320|3|0", + "spell": "4:25-4:29|768523651983844320|3|1026|-1", + "extent": "4:15-4:29|768523651983844320|3|0|-1", "type": 0, "uses": [], "kind": 253, @@ -309,8 +309,8 @@ OUTPUT: make_functions.cc "qual_name_offset": 8, "short_name": "args", "declarations": [], - "spell": "9:24-9:28|2532818908869373467|3|1026", - "extent": "9:16-9:28|2532818908869373467|3|0", + "spell": "9:24-9:28|2532818908869373467|3|1026|-1", + "extent": "9:16-9:28|2532818908869373467|3|0|-1", "type": 0, "uses": [], "kind": 253, @@ -321,8 +321,8 @@ OUTPUT: make_functions.cc "qual_name_offset": 10, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|15793662558620604611|3|1026", - "extent": "4:15-4:29|15793662558620604611|3|0", + "spell": "4:25-4:29|15793662558620604611|3|1026|-1", + "extent": "4:15-4:29|15793662558620604611|3|0|-1", "type": 0, "uses": [], "kind": 253, @@ -333,8 +333,8 @@ OUTPUT: make_functions.cc "qual_name_offset": 6, "short_name": "args", "declarations": [], - "spell": "4:25-4:29|11138976705878544996|3|1026", - "extent": "4:15-4:29|11138976705878544996|3|0", + "spell": "4:25-4:29|11138976705878544996|3|1026|-1", + "extent": "4:15-4:29|11138976705878544996|3|0|-1", "type": 0, "uses": [], "kind": 253, diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index 42a44a882..51a356771 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -17,9 +17,9 @@ class Foo; "qual_name_offset": 6, "short_name": "Foo", "kind": 5, - "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], - "spell": "3:7-3:10|0|1|2", - "extent": "3:1-3:13|0|1|0", + "declarations": ["1:7-1:10|1:1-1:10|0|1|1|-1", "2:7-2:10|2:1-2:10|0|1|1|-1", "4:7-4:10|4:1-4:10|0|1|1|-1"], + "spell": "3:7-3:10|0|1|2|-1", + "extent": "3:1-3:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index a4333abcf..ef14ac7be 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -30,8 +30,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -50,8 +50,8 @@ class Foo { "qual_name_offset": 4, "short_name": "foo", "declarations": [], - "spell": "2:7-2:10|15041163540773201510|2|1026", - "extent": "2:3-2:10|15041163540773201510|2|0", + "spell": "2:7-2:10|15041163540773201510|2|1026|-1", + "extent": "2:3-2:10|15041163540773201510|2|0|-1", "type": 53, "uses": [], "kind": 8, diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index c0ae1aa75..4655b4be4 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -32,8 +32,8 @@ int Foo::foo; "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -41,16 +41,16 @@ int Foo::foo; "funcs": [], "vars": [], "instances": [], - "uses": ["5:5-5:8|0|1|4"] + "uses": ["5:5-5:8|0|1|4|-1"] }], "usr2var": [{ "usr": 8942920329766232482, "detailed_name": "static int Foo::foo", "qual_name_offset": 11, "short_name": "foo", - "declarations": ["2:14-2:17|15041163540773201510|2|1025"], - "spell": "5:10-5:13|15041163540773201510|2|1026", - "extent": "5:1-5:13|15041163540773201510|2|0", + "declarations": ["2:14-2:17|2:3-2:17|15041163540773201510|2|1025|-1"], + "spell": "5:10-5:13|15041163540773201510|2|1026|-1", + "extent": "5:1-5:13|15041163540773201510|2|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index 718eaffab..aacda01c1 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -16,9 +16,9 @@ void foo(); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-3:14|0|1|0", + "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1", "2:6-2:9|2:1-2:11|0|1|1|-1", "4:6-4:9|4:1-4:11|0|1|1|-1"], + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-3:14|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index a7cc5e0bc..0aa1487ee 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -16,9 +16,9 @@ int foo(int a, int b) { return 0; } "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], - "spell": "5:5-5:8|0|1|2", - "extent": "5:1-5:36|0|1|0", + "declarations": ["1:5-1:8|1:1-1:18|0|1|1|-1", "2:5-2:8|2:1-3:16|0|1|1|-1", "4:5-4:8|4:1-4:26|0|1|1|-1"], + "spell": "5:5-5:8|0|1|2|-1", + "extent": "5:1-5:36|0|1|0|-1", "bases": [], "derived": [], "vars": [14555488990109936920, 10963664335057337329], @@ -47,8 +47,8 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "b", "declarations": [], - "spell": "5:20-5:21|2747674671862363334|3|1026", - "extent": "5:16-5:21|2747674671862363334|3|0", + "spell": "5:20-5:21|2747674671862363334|3|1026|-1", + "extent": "5:16-5:21|2747674671862363334|3|0|-1", "type": 53, "uses": [], "kind": 253, @@ -59,8 +59,8 @@ int foo(int a, int b) { return 0; } "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:13-5:14|2747674671862363334|3|1026", - "extent": "5:9-5:14|2747674671862363334|3|0", + "spell": "5:13-5:14|2747674671862363334|3|1026|-1", + "extent": "5:9-5:14|2747674671862363334|3|0|-1", "type": 53, "uses": [], "kind": 253, diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 18aed73a6..da2b46fb9 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -18,7 +18,7 @@ void Foo::def() {} "short_name": "declonly", "kind": 6, "storage": 0, - "declarations": ["2:8-2:16|15041163540773201510|2|1025"], + "declarations": ["2:8-2:16|2:3-2:18|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -31,7 +31,7 @@ void Foo::def() {} "short_name": "purevirtual", "kind": 6, "storage": 0, - "declarations": ["3:16-3:27|15041163540773201510|2|1089"], + "declarations": ["3:16-3:27|3:3-3:33|15041163540773201510|2|1089|-1"], "bases": [], "derived": [], "vars": [], @@ -44,9 +44,9 @@ void Foo::def() {} "short_name": "def", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|15041163540773201510|2|1025"], - "spell": "7:11-7:14|15041163540773201510|2|1026", - "extent": "7:1-7:19|15041163540773201510|2|0", + "declarations": ["4:8-4:11|4:3-4:13|15041163540773201510|2|1025|-1"], + "spell": "7:11-7:14|15041163540773201510|2|1026|-1", + "extent": "7:1-7:19|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -60,8 +60,8 @@ void Foo::def() {} "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-5:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -69,7 +69,7 @@ void Foo::def() {} "funcs": [4012226004228259562, 10939323144126021546, 15416083548883122431], "vars": [], "instances": [], - "uses": ["7:6-7:9|0|1|4"] + "uses": ["7:6-7:9|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 3f3f78ca4..a31baff5d 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -17,8 +17,8 @@ enum class Foo : uint8_t { "short_name": "uint8_t", "kind": 252, "declarations": [], - "spell": "1:23-1:30|0|1|2", - "extent": "1:1-1:30|0|1|0", + "spell": "1:23-1:30|0|1|2|-1", + "extent": "1:1-1:30|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -34,8 +34,8 @@ enum class Foo : uint8_t { "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "2:12-2:15|0|1|2", - "extent": "2:1-5:2|0|1|0", + "spell": "2:12-2:15|0|1|2|-1", + "extent": "2:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -52,8 +52,8 @@ enum class Foo : uint8_t { "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026", - "extent": "3:3-3:4|16985894625255407295|2|0", + "spell": "3:3-3:4|16985894625255407295|2|1026|-1", + "extent": "3:3-3:4|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -64,8 +64,8 @@ enum class Foo : uint8_t { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "4:3-4:4|16985894625255407295|2|1026", - "extent": "4:3-4:9|16985894625255407295|2|0", + "spell": "4:3-4:4|16985894625255407295|2|1026|-1", + "extent": "4:3-4:9|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 6e44da9b4..bf760444e 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -16,8 +16,8 @@ enum Foo { "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -34,8 +34,8 @@ enum Foo { "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026", - "extent": "2:3-2:4|16985894625255407295|2|0", + "spell": "2:3-2:4|16985894625255407295|2|1026|-1", + "extent": "2:3-2:4|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -46,8 +46,8 @@ enum Foo { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026", - "extent": "3:3-3:9|16985894625255407295|2|0", + "spell": "3:3-3:4|16985894625255407295|2|1026|-1", + "extent": "3:3-3:9|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 08d840870..18cb37c06 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -23,8 +23,8 @@ enum class E : int32_t { "short_name": "E", "kind": 10, "declarations": [], - "spell": "8:12-8:13|0|1|2", - "extent": "8:1-11:2|0|1|0", + "spell": "8:12-8:13|0|1|2|-1", + "extent": "8:1-11:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -40,8 +40,8 @@ enum class E : int32_t { "short_name": "int32_t", "kind": 252, "declarations": [], - "spell": "6:13-6:20|0|1|2", - "extent": "6:1-6:20|0|1|0", + "spell": "6:13-6:20|0|1|2|-1", + "extent": "6:1-6:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -57,8 +57,8 @@ enum class E : int32_t { "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -75,8 +75,8 @@ enum class E : int32_t { "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026", - "extent": "2:3-2:4|16985894625255407295|2|0", + "spell": "2:3-2:4|16985894625255407295|2|1026|-1", + "extent": "2:3-2:4|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -87,8 +87,8 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026", - "extent": "3:3-3:9|16985894625255407295|2|0", + "spell": "3:3-3:4|16985894625255407295|2|1026|-1", + "extent": "3:3-3:9|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -100,8 +100,8 @@ enum class E : int32_t { "short_name": "E0", "hover": "E::E0 = 0", "declarations": [], - "spell": "9:3-9:5|2986879766914123941|2|1026", - "extent": "9:3-9:5|2986879766914123941|2|0", + "spell": "9:3-9:5|2986879766914123941|2|1026|-1", + "extent": "9:3-9:5|2986879766914123941|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -112,8 +112,8 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "E20", "declarations": [], - "spell": "10:3-10:6|2986879766914123941|2|1026", - "extent": "10:3-10:11|2986879766914123941|2|0", + "spell": "10:3-10:6|2986879766914123941|2|1026|-1", + "extent": "10:3-10:11|2986879766914123941|2|0|-1", "type": 0, "uses": [], "kind": 22, diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index bcee0c009..07475c77f 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -18,8 +18,8 @@ Foo x = Foo::A; "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:12-1:15|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:12-1:15|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -27,7 +27,7 @@ Foo x = Foo::A; "funcs": [], "vars": [], "instances": [10677751717622394455], - "uses": ["6:1-6:4|0|1|4", "6:9-6:12|0|1|4"] + "uses": ["6:1-6:4|0|1|4|-1", "6:9-6:12|0|1|4|-1"] }], "usr2var": [{ "usr": 439339022761937396, @@ -36,10 +36,10 @@ Foo x = Foo::A; "short_name": "A", "hover": "Foo::A = 0", "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026", - "extent": "2:3-2:4|16985894625255407295|2|0", + "spell": "2:3-2:4|16985894625255407295|2|1026|-1", + "extent": "2:3-2:4|16985894625255407295|2|0|-1", "type": 0, - "uses": ["6:14-6:15|0|1|4"], + "uses": ["6:14-6:15|0|1|4|-1"], "kind": 22, "storage": 0 }, { @@ -49,8 +49,8 @@ Foo x = Foo::A; "short_name": "x", "hover": "Foo x = Foo::A", "declarations": [], - "spell": "6:5-6:6|0|1|2", - "extent": "6:1-6:15|0|1|0", + "spell": "6:5-6:6|0|1|2|-1", + "extent": "6:1-6:15|0|1|0|-1", "type": 16985894625255407295, "uses": [], "kind": 13, @@ -61,8 +61,8 @@ Foo x = Foo::A; "qual_name_offset": 0, "short_name": "B", "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026", - "extent": "3:3-3:9|16985894625255407295|2|0", + "spell": "3:3-3:4|16985894625255407295|2|1026|-1", + "extent": "3:3-3:9|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index f5d2e47b8..e92f23cfb 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -21,8 +21,8 @@ Foo b; "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|0|1|2", - "extent": "1:1-1:10|0|1|0", + "spell": "1:6-1:7|0|1|2|-1", + "extent": "1:1-1:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -30,7 +30,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["9:5-9:6|0|1|4"] + "uses": ["9:5-9:6|0|1|4|-1"] }, { "usr": 7074603899792463171, "detailed_name": "Inner", @@ -38,8 +38,8 @@ Foo b; "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:10-6:15|0|1|2", - "extent": "6:3-6:18|0|1|0", + "spell": "6:10-6:15|0|1|2|-1", + "extent": "6:3-6:18|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -55,8 +55,8 @@ Foo b; "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:8-5:11|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -64,7 +64,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] + "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] }, { "usr": 11976530632376795217, "detailed_name": "Foo", @@ -72,8 +72,8 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "5:8-5:11|0|1|2", - "extent": "4:1-7:2|0|1|0", + "spell": "5:8-5:11|0|1|2|-1", + "extent": "4:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -89,8 +89,8 @@ Foo b; "short_name": "B", "kind": 10, "declarations": [], - "spell": "2:6-2:7|0|1|2", - "extent": "2:1-2:10|0|1|0", + "spell": "2:6-2:7|0|1|2|-1", + "extent": "2:1-2:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -98,7 +98,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["10:5-10:6|0|1|4"] + "uses": ["10:5-10:6|0|1|4|-1"] }, { "usr": 13938528237873543349, "detailed_name": "struct Foo::Inner {}", @@ -106,8 +106,8 @@ Foo b; "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|1026", - "extent": "6:3-6:18|10528472276654770367|2|0", + "spell": "6:10-6:15|10528472276654770367|2|1026|-1", + "extent": "6:3-6:18|10528472276654770367|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -115,7 +115,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["9:9-9:14|0|1|4"] + "uses": ["9:9-9:14|0|1|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -123,8 +123,8 @@ Foo b; "qual_name_offset": 7, "short_name": "b", "declarations": [], - "spell": "10:8-10:9|0|1|2", - "extent": "10:1-10:9|0|1|0", + "spell": "10:8-10:9|0|1|2|-1", + "extent": "10:1-10:9|0|1|0|-1", "type": 11976530632376795217, "uses": [], "kind": 13, @@ -135,8 +135,8 @@ Foo b; "qual_name_offset": 14, "short_name": "a", "declarations": [], - "spell": "9:15-9:16|0|1|2", - "extent": "9:1-9:16|0|1|0", + "spell": "9:15-9:16|0|1|2|-1", + "extent": "9:1-9:16|0|1|0|-1", "type": 7074603899792463171, "uses": [], "kind": 13, diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index 2d23e7d97..9c38f5741 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -12,7 +12,7 @@ void foo(int a, int b); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["1:6-1:9|0|1|1"], + "declarations": ["1:6-1:9|1:1-1:23|0|1|1|-1"], "bases": [], "derived": [], "vars": [], diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index c35a6f770..1eb2ba755 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -14,9 +14,9 @@ void foo() {} "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["1:6-1:9|0|1|1"], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-3:14|0|1|0", + "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1"], + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-3:14|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index 1662c48a8..7ceee6367 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -13,8 +13,8 @@ void foo() {} "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-1:14|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-1:14|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index e38b20bd8..701b03966 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -14,8 +14,8 @@ class Derived : public Parent {}; "short_name": "Parent", "kind": 5, "declarations": [], - "spell": "1:7-1:13|0|1|2", - "extent": "1:1-1:16|0|1|0", + "spell": "1:7-1:13|0|1|2|-1", + "extent": "1:1-1:16|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [10963370434658308541], @@ -23,7 +23,7 @@ class Derived : public Parent {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:30|10963370434658308541|2|2052"] + "uses": ["2:24-2:30|10963370434658308541|2|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Parent {}", @@ -31,8 +31,8 @@ class Derived : public Parent {}; "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "2:7-2:14|0|1|2", - "extent": "2:1-2:33|0|1|0", + "spell": "2:7-2:14|0|1|2|-1", + "extent": "2:1-2:33|0|1|0|-1", "alias_of": 0, "bases": [3866412049634585509], "derived": [], diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 33b80bbbd..4e20cd1b8 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -25,8 +25,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "short_name": "Derived1", "kind": 5, "declarations": [], - "spell": "8:7-8:15|0|1|2", - "extent": "8:1-8:29|0|1|0", + "spell": "8:7-8:15|0|1|2|-1", + "extent": "8:1-8:29|0|1|0|-1", "alias_of": 0, "bases": [11930058224338108382], "derived": [10963370434658308541], @@ -34,7 +34,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:43-13:51|10963370434658308541|2|2052"] + "uses": ["13:43-13:51|10963370434658308541|2|2052|-1"] }, { "usr": 10651399730831737929, "detailed_name": "class Derived2 : Base2 {}", @@ -42,8 +42,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "short_name": "Derived2", "kind": 5, "declarations": [], - "spell": "11:7-11:15|0|1|2", - "extent": "11:1-11:29|0|1|0", + "spell": "11:7-11:15|0|1|2|-1", + "extent": "11:1-11:29|0|1|0|-1", "alias_of": 0, "bases": [11118288764693061434], "derived": [10963370434658308541], @@ -51,7 +51,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:56-13:64|10963370434658308541|2|2052"] + "uses": ["13:56-13:64|10963370434658308541|2|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}", @@ -59,8 +59,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "13:7-13:14|0|1|2", - "extent": "13:1-13:76|0|1|0", + "spell": "13:7-13:14|0|1|2|-1", + "extent": "13:1-13:76|0|1|0|-1", "alias_of": 0, "bases": [11930058224338108382, 11118288764693061434, 5863733211528032190, 10651399730831737929], "derived": [], @@ -68,7 +68,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:33-13:40|10963370434658308541|2|2052", "13:65-13:72|10963370434658308541|2|2052"] + "uses": ["13:33-13:40|10963370434658308541|2|2052|-1", "13:65-13:72|10963370434658308541|2|2052|-1"] }, { "usr": 11118288764693061434, "detailed_name": "class Base2 {}", @@ -76,8 +76,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "short_name": "Base2", "kind": 5, "declarations": [], - "spell": "5:7-5:12|0|1|2", - "extent": "5:1-5:15|0|1|0", + "spell": "5:7-5:12|0|1|2|-1", + "extent": "5:1-5:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [10651399730831737929, 10963370434658308541], @@ -85,7 +85,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:27-13:32|10963370434658308541|2|2052"] + "uses": ["13:27-13:32|10963370434658308541|2|2052|-1"] }, { "usr": 11930058224338108382, "detailed_name": "class Base1 {}", @@ -93,8 +93,8 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "short_name": "Base1", "kind": 5, "declarations": [], - "spell": "2:7-2:12|0|1|2", - "extent": "2:1-2:15|0|1|0", + "spell": "2:7-2:12|0|1|2|-1", + "extent": "2:1-2:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [5863733211528032190, 10963370434658308541], @@ -102,7 +102,7 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "funcs": [], "vars": [], "instances": [], - "uses": ["13:17-13:22|10963370434658308541|2|2052"] + "uses": ["13:17-13:22|10963370434658308541|2|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index ee1603b3d..f8e171a2b 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -16,8 +16,8 @@ class Derived : public MiddleA, public MiddleB {}; "short_name": "Root", "kind": 5, "declarations": [], - "spell": "1:7-1:11|0|1|2", - "extent": "1:1-1:14|0|1|0", + "spell": "1:7-1:11|0|1|2|-1", + "extent": "1:1-1:14|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [11863524815063131483, 14022569716337624303], @@ -25,7 +25,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["2:24-2:28|11863524815063131483|2|2052", "3:24-3:28|14022569716337624303|2|2052"] + "uses": ["2:24-2:28|11863524815063131483|2|2052|-1", "3:24-3:28|14022569716337624303|2|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public MiddleA, public MiddleB {}", @@ -33,8 +33,8 @@ class Derived : public MiddleA, public MiddleB {}; "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "4:7-4:14|0|1|2", - "extent": "4:1-4:50|0|1|0", + "spell": "4:7-4:14|0|1|2|-1", + "extent": "4:1-4:50|0|1|0|-1", "alias_of": 0, "bases": [11863524815063131483, 14022569716337624303], "derived": [], @@ -50,8 +50,8 @@ class Derived : public MiddleA, public MiddleB {}; "short_name": "MiddleA", "kind": 5, "declarations": [], - "spell": "2:7-2:14|0|1|2", - "extent": "2:1-2:31|0|1|0", + "spell": "2:7-2:14|0|1|2|-1", + "extent": "2:1-2:31|0|1|0|-1", "alias_of": 0, "bases": [3897841498936210886], "derived": [10963370434658308541], @@ -59,7 +59,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:24-4:31|10963370434658308541|2|2052"] + "uses": ["4:24-4:31|10963370434658308541|2|2052|-1"] }, { "usr": 14022569716337624303, "detailed_name": "class MiddleB : public Root {}", @@ -67,8 +67,8 @@ class Derived : public MiddleA, public MiddleB {}; "short_name": "MiddleB", "kind": 5, "declarations": [], - "spell": "3:7-3:14|0|1|2", - "extent": "3:1-3:31|0|1|0", + "spell": "3:7-3:14|0|1|2|-1", + "extent": "3:1-3:31|0|1|0|-1", "alias_of": 0, "bases": [3897841498936210886], "derived": [10963370434658308541], @@ -76,7 +76,7 @@ class Derived : public MiddleA, public MiddleB {}; "funcs": [], "vars": [], "instances": [], - "uses": ["4:40-4:47|10963370434658308541|2|2052"] + "uses": ["4:40-4:47|10963370434658308541|2|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 982a2cf14..14a5661a7 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -18,8 +18,8 @@ class Derived : public Root { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:8-5:11|10963370434658308541|2|5186", - "extent": "5:3-5:25|10963370434658308541|2|0", + "spell": "5:8-5:11|10963370434658308541|2|5186|-1", + "extent": "5:3-5:25|10963370434658308541|2|0|-1", "bases": [9948027785633571339], "derived": [], "vars": [], @@ -32,7 +32,7 @@ class Derived : public Root { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:16-2:19|3897841498936210886|2|1089"], + "declarations": ["2:16-2:19|2:3-2:21|3897841498936210886|2|1089|-1"], "bases": [], "derived": [6666242542855173890], "vars": [], @@ -46,8 +46,8 @@ class Derived : public Root { "short_name": "Root", "kind": 5, "declarations": [], - "spell": "1:7-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [10963370434658308541], @@ -55,7 +55,7 @@ class Derived : public Root { "funcs": [9948027785633571339], "vars": [], "instances": [], - "uses": ["4:24-4:28|10963370434658308541|2|2052"] + "uses": ["4:24-4:28|10963370434658308541|2|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Root {}", @@ -63,8 +63,8 @@ class Derived : public Root { "short_name": "Derived", "kind": 5, "declarations": [], - "spell": "4:7-4:14|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:7-4:14|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "alias_of": 0, "bases": [3897841498936210886], "derived": [], diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index d002b0bd2..58ee1d4fb 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -14,7 +14,7 @@ class IFoo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:16-2:19|9949214233977131946|2|1089"], + "declarations": ["2:16-2:19|2:3-2:25|9949214233977131946|2|1089|-1"], "bases": [], "derived": [], "vars": [], @@ -28,8 +28,8 @@ class IFoo { "short_name": "IFoo", "kind": 5, "declarations": [], - "spell": "1:7-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index dcc0e7814..117194751 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -21,8 +21,8 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:12|15826803741381445676|2|1090", - "extent": "5:3-5:23|15826803741381445676|2|0", + "spell": "5:11-5:12|15826803741381445676|2|1090|-1", + "extent": "5:3-5:23|15826803741381445676|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -36,8 +36,8 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "8:3-8:4|10963370434658308541|2|5186", - "extent": "8:3-8:26|10963370434658308541|2|0", + "spell": "8:3-8:4|10963370434658308541|2|5186|-1", + "extent": "8:3-8:26|10963370434658308541|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -51,8 +51,8 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:11-2:12|11628904180681204356|2|1090", - "extent": "2:3-2:23|11628904180681204356|2|0", + "spell": "2:11-2:12|11628904180681204356|2|1090|-1", + "extent": "2:3-2:23|11628904180681204356|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -66,8 +66,8 @@ struct Derived : Base0, Base1 { "short_name": "Derived", "kind": 23, "declarations": [], - "spell": "7:8-7:15|0|1|2", - "extent": "7:1-9:2|0|1|0", + "spell": "7:8-7:15|0|1|2|-1", + "extent": "7:1-9:2|0|1|0|-1", "alias_of": 0, "bases": [11628904180681204356, 15826803741381445676], "derived": [], @@ -75,7 +75,7 @@ struct Derived : Base0, Base1 { "funcs": [13164726294460837993], "vars": [], "instances": [], - "uses": ["8:4-8:11|10963370434658308541|2|4"] + "uses": ["8:4-8:11|10963370434658308541|2|4|-1"] }, { "usr": 11628904180681204356, "detailed_name": "struct Base0 {}", @@ -83,8 +83,8 @@ struct Derived : Base0, Base1 { "short_name": "Base0", "kind": 23, "declarations": [], - "spell": "1:8-1:13|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:13|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [10963370434658308541], @@ -92,7 +92,7 @@ struct Derived : Base0, Base1 { "funcs": [16347272523198263017], "vars": [], "instances": [], - "uses": ["2:12-2:17|11628904180681204356|2|4", "7:18-7:23|10963370434658308541|2|2052"] + "uses": ["2:12-2:17|11628904180681204356|2|4|-1", "7:18-7:23|10963370434658308541|2|2052|-1"] }, { "usr": 15826803741381445676, "detailed_name": "struct Base1 {}", @@ -100,8 +100,8 @@ struct Derived : Base0, Base1 { "short_name": "Base1", "kind": 23, "declarations": [], - "spell": "4:8-4:13|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:8-4:13|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [10963370434658308541], @@ -109,7 +109,7 @@ struct Derived : Base0, Base1 { "funcs": [8401779086123965305], "vars": [], "instances": [], - "uses": ["5:12-5:17|15826803741381445676|2|4", "7:25-7:30|10963370434658308541|2|2052"] + "uses": ["5:12-5:17|15826803741381445676|2|4|-1", "7:25-7:30|10963370434658308541|2|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 357d6e321..2f5371f91 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -24,8 +24,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-12:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-12:2|0|1|0|-1", "bases": [], "derived": [], "vars": [12666114896600231317, 2981279427664991319], @@ -42,7 +42,7 @@ void foo() { "bases": [], "derived": [], "vars": [], - "uses": ["9:14-9:15|4259594751088586730|3|16420", "10:14-10:15|4259594751088586730|3|16420", "11:14-11:15|4259594751088586730|3|16420"], + "uses": ["9:14-9:15|4259594751088586730|3|16420|-1", "10:14-10:15|4259594751088586730|3|16420|-1", "11:14-11:15|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -67,8 +67,8 @@ void foo() { "short_name": "", "kind": 26, "declarations": [], - "spell": "4:22-4:23|4259594751088586730|3|2", - "extent": "4:22-4:23|4259594751088586730|3|0", + "spell": "4:22-4:23|4259594751088586730|3|2|-1", + "extent": "4:22-4:23|4259594751088586730|3|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -85,10 +85,10 @@ void foo() { "short_name": "dosomething", "hover": "(lambda) dosomething", "declarations": [], - "spell": "4:8-4:19|4259594751088586730|3|2", - "extent": "4:3-7:4|4259594751088586730|3|0", + "spell": "4:8-4:19|4259594751088586730|3|2|-1", + "extent": "4:3-7:4|4259594751088586730|3|0|-1", "type": 14635009347499519042, - "uses": ["9:3-9:14|4259594751088586730|3|4", "10:3-10:14|4259594751088586730|3|4", "11:3-11:14|4259594751088586730|3|4"], + "uses": ["9:3-9:14|4259594751088586730|3|4|-1", "10:3-10:14|4259594751088586730|3|4|-1", "11:3-11:14|4259594751088586730|3|4|-1"], "kind": 13, "storage": 0 }, { @@ -97,10 +97,10 @@ void foo() { "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2", - "extent": "2:3-2:8|4259594751088586730|3|0", + "spell": "2:7-2:8|4259594751088586730|3|2|-1", + "extent": "2:3-2:8|4259594751088586730|3|0|-1", "type": 53, - "uses": ["4:24-4:25|4259594751088586730|3|4", "5:7-5:8|4259594751088586730|3|28"], + "uses": ["4:24-4:25|4259594751088586730|3|4|-1", "5:7-5:8|4259594751088586730|3|28|-1"], "kind": 13, "storage": 0 }, { @@ -109,10 +109,10 @@ void foo() { "qual_name_offset": 4, "short_name": "y", "declarations": [], - "spell": "4:31-4:32|17926497908620168464|3|2", - "extent": "4:27-4:32|4259594751088586730|3|0", + "spell": "4:31-4:32|17926497908620168464|3|2|-1", + "extent": "4:27-4:32|4259594751088586730|3|0|-1", "type": 0, - "uses": ["6:7-6:8|4259594751088586730|3|28"], + "uses": ["6:7-6:8|4259594751088586730|3|28|-1"], "kind": 253, "storage": 0 }] diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index a74be500b..b88c3eaa7 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -23,9 +23,9 @@ FOO(make1(), make2); "short_name": "a", "kind": 12, "storage": 0, - "declarations": ["12:1-12:20|0|1|1"], - "spell": "12:1-12:20|0|1|2", - "extent": "12:1-12:20|0|1|0", + "declarations": ["12:1-12:20|12:1-12:20|0|1|1|-1"], + "spell": "12:1-12:20|0|1|2|-1", + "extent": "12:1-12:20|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -39,12 +39,12 @@ FOO(make1(), make2); "kind": 12, "storage": 0, "declarations": [], - "spell": "6:5-6:10|0|1|2", - "extent": "6:1-8:2|0|1|0", + "spell": "6:5-6:10|0|1|2|-1", + "extent": "6:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["12:5-12:10|9720930732776154610|3|16420", "12:5-12:10|0|1|64|0"], + "uses": ["12:5-12:10|9720930732776154610|3|16420|-1", "12:5-12:10|0|1|64|0"], "callees": [] }], "usr2type": [{ @@ -70,10 +70,10 @@ FOO(make1(), make2); "short_name": "make2", "hover": "const int make2 = 5", "declarations": [], - "spell": "9:11-9:16|0|1|2", - "extent": "9:1-9:20|0|1|0", + "spell": "9:11-9:16|0|1|2|-1", + "extent": "9:1-9:20|0|1|0|-1", "type": 53, - "uses": ["12:14-12:19|9720930732776154610|3|12", "12:14-12:19|0|1|64|0"], + "uses": ["12:14-12:19|9720930732776154610|3|12|-1", "12:14-12:19|0|1|64|0"], "kind": 13, "storage": 0 }, { @@ -83,10 +83,10 @@ FOO(make1(), make2); "short_name": "FOO", "hover": "#define FOO(aaa, bbb) \\\n int a();\\\n int a() { return aaa + bbb; }", "declarations": [], - "spell": "1:9-1:12|0|1|2", - "extent": "1:9-3:32|0|1|0", + "spell": "1:9-1:12|0|1|2|-1", + "extent": "1:9-3:32|0|1|0|-1", "type": 0, - "uses": ["12:1-12:4|0|1|64"], + "uses": ["12:1-12:4|0|1|64|-1"], "kind": 255, "storage": 0 }] diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 7b7c8b047..156ab2373 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -20,8 +20,8 @@ int x = A; "kind": 9, "storage": 0, "declarations": [], - "spell": "5:12-5:15|15041163540773201510|2|1026", - "extent": "5:12-5:15|15041163540773201510|2|0", + "spell": "5:12-5:15|15041163540773201510|2|1026|-1", + "extent": "5:12-5:15|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -50,8 +50,8 @@ int x = A; "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "4:8-4:11|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:8-4:11|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -59,7 +59,7 @@ int x = A; "funcs": [13788753348312146871], "vars": [], "instances": [], - "uses": ["5:12-5:15|15041163540773201510|2|4", "5:12-5:15|0|1|64|0"] + "uses": ["5:12-5:15|15041163540773201510|2|4|-1", "5:12-5:15|0|1|64|0"] }], "usr2var": [{ "usr": 1569772797058982873, @@ -68,10 +68,10 @@ int x = A; "short_name": "A", "hover": "#define A 5", "declarations": [], - "spell": "1:9-1:10|0|1|2", - "extent": "1:9-1:12|0|1|0", + "spell": "1:9-1:10|0|1|2|-1", + "extent": "1:9-1:12|0|1|0|-1", "type": 0, - "uses": ["8:9-8:10|0|1|64"], + "uses": ["8:9-8:10|0|1|64|-1"], "kind": 255, "storage": 0 }, { @@ -81,10 +81,10 @@ int x = A; "short_name": "DISALLOW", "hover": "#define DISALLOW(type) type(type&&) = delete;", "declarations": [], - "spell": "2:9-2:17|0|1|2", - "extent": "2:9-2:46|0|1|0", + "spell": "2:9-2:17|0|1|2|-1", + "extent": "2:9-2:46|0|1|0|-1", "type": 0, - "uses": ["5:3-5:11|0|1|64"], + "uses": ["5:3-5:11|0|1|64|-1"], "kind": 255, "storage": 0 }, { @@ -94,8 +94,8 @@ int x = A; "short_name": "x", "hover": "int x = A", "declarations": [], - "spell": "8:5-8:6|0|1|2", - "extent": "8:1-1:1|0|1|0", + "spell": "8:5-8:6|0|1|2|-1", + "extent": "8:1-1:1|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index 00edb4dee..fae12cdc6 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -18,7 +18,7 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1025"], + "declarations": ["2:8-2:11|2:3-2:13|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -32,8 +32,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index b79e9ba31..895eac04d 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -16,9 +16,9 @@ void Foo::foo() const {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1025"], - "spell": "5:11-5:14|15041163540773201510|2|1026", - "extent": "5:1-5:25|15041163540773201510|2|0", + "declarations": ["2:8-2:11|2:3-2:19|15041163540773201510|2|1025|-1"], + "spell": "5:11-5:14|15041163540773201510|2|1026|-1", + "extent": "5:1-5:25|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -32,8 +32,8 @@ void Foo::foo() const {} "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -41,7 +41,7 @@ void Foo::foo() const {} "funcs": [6446764306530590711], "vars": [], "instances": [], - "uses": ["5:6-5:9|0|1|4"] + "uses": ["5:6-5:9|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index 64ced29b4..f2294cd0b 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -15,8 +15,8 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:11|15041163540773201510|2|1026", - "extent": "2:3-2:16|15041163540773201510|2|0", + "spell": "2:8-2:11|15041163540773201510|2|1026|-1", + "extent": "2:3-2:16|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -30,8 +30,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 69f5ebdca..784f210da 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -35,8 +35,8 @@ OUTPUT: funky_enum.h "hover": "A = 0", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "4:1-4:2|16985894625255407295|2|1026", - "extent": "4:1-4:2|16985894625255407295|2|0", + "spell": "4:1-4:2|16985894625255407295|2|1026|-1", + "extent": "4:1-4:2|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -49,8 +49,8 @@ OUTPUT: funky_enum.h "hover": "C = 2", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "6:1-6:2|16985894625255407295|2|1026", - "extent": "6:1-6:2|16985894625255407295|2|0", + "spell": "6:1-6:2|16985894625255407295|2|1026|-1", + "extent": "6:1-6:2|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -63,8 +63,8 @@ OUTPUT: funky_enum.h "hover": "B = 1", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "declarations": [], - "spell": "5:1-5:2|16985894625255407295|2|1026", - "extent": "5:1-5:2|16985894625255407295|2|0", + "spell": "5:1-5:2|16985894625255407295|2|1026|-1", + "extent": "5:1-5:2|16985894625255407295|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -86,8 +86,8 @@ OUTPUT: funky_enum.cc "short_name": "Foo", "kind": 10, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 12a625b34..1ef51a205 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -17,8 +17,8 @@ OUTPUT: header.h "kind": 12, "storage": 0, "declarations": [], - "spell": "10:6-10:10|0|1|2", - "extent": "10:1-10:15|0|1|0", + "spell": "10:6-10:10|0|1|2|-1", + "extent": "10:1-10:15|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -47,8 +47,8 @@ OUTPUT: header.h "short_name": "Foo2", "kind": 23, "declarations": [], - "spell": "13:8-13:12|0|1|2", - "extent": "13:1-13:15|0|1|0", + "spell": "13:8-13:12|0|1|2|-1", + "extent": "13:1-13:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -64,8 +64,8 @@ OUTPUT: header.h "short_name": "Foo0", "kind": 252, "declarations": [], - "spell": "7:7-7:11|0|1|2", - "extent": "7:1-7:29|0|1|0", + "spell": "7:7-7:11|0|1|2|-1", + "extent": "7:1-7:29|0|1|0|-1", "alias_of": 16750616846959666305, "bases": [], "derived": [], @@ -81,8 +81,8 @@ OUTPUT: header.h "short_name": "Foo3", "kind": 10, "declarations": [], - "spell": "15:6-15:10|0|1|2", - "extent": "15:1-15:22|0|1|0", + "spell": "15:6-15:10|0|1|2|-1", + "extent": "15:1-15:22|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -98,8 +98,8 @@ OUTPUT: header.h "short_name": "Base", "kind": 23, "declarations": [], - "spell": "3:8-3:12|0|1|2", - "extent": "3:1-3:15|0|1|0", + "spell": "3:8-3:12|0|1|2|-1", + "extent": "3:1-3:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [16750616846959666305], @@ -107,7 +107,7 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["5:26-5:30|16750616846959666305|2|2052"] + "uses": ["5:26-5:30|16750616846959666305|2|2052|-1"] }, { "usr": 16750616846959666305, "detailed_name": "struct SameFileDerived : Base {}", @@ -115,8 +115,8 @@ OUTPUT: header.h "short_name": "SameFileDerived", "kind": 23, "declarations": [], - "spell": "5:8-5:23|0|1|2", - "extent": "5:1-5:33|0|1|0", + "spell": "5:8-5:23|0|1|2|-1", + "extent": "5:1-5:33|0|1|0|-1", "alias_of": 0, "bases": [8420119006782424779], "derived": [], @@ -124,7 +124,7 @@ OUTPUT: header.h "funcs": [], "vars": [], "instances": [], - "uses": ["7:14-7:29|0|1|4"] + "uses": ["7:14-7:29|0|1|4|-1"] }], "usr2var": [{ "usr": 2638219001294786365, @@ -132,8 +132,8 @@ OUTPUT: header.h "qual_name_offset": 4, "short_name": "Foo4", "declarations": [], - "spell": "17:5-17:9|0|1|2", - "extent": "17:1-17:9|0|1|0", + "spell": "17:5-17:9|0|1|2|-1", + "extent": "17:1-17:9|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -145,8 +145,8 @@ OUTPUT: header.h "short_name": "A", "hover": "A = 0", "declarations": [], - "spell": "15:13-15:14|4481210672785600703|2|1026", - "extent": "15:13-15:14|4481210672785600703|2|0", + "spell": "15:13-15:14|4481210672785600703|2|1026|-1", + "extent": "15:13-15:14|4481210672785600703|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -158,8 +158,8 @@ OUTPUT: header.h "short_name": "C", "hover": "C = 2", "declarations": [], - "spell": "15:19-15:20|4481210672785600703|2|1026", - "extent": "15:19-15:20|4481210672785600703|2|0", + "spell": "15:19-15:20|4481210672785600703|2|1026|-1", + "extent": "15:19-15:20|4481210672785600703|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -170,8 +170,8 @@ OUTPUT: header.h "qual_name_offset": 11, "short_name": "Foo5", "declarations": [], - "spell": "18:12-18:16|0|1|2", - "extent": "18:1-18:16|0|1|0", + "spell": "18:12-18:16|0|1|2|-1", + "extent": "18:1-18:16|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -183,8 +183,8 @@ OUTPUT: header.h "short_name": "B", "hover": "B = 1", "declarations": [], - "spell": "15:16-15:17|4481210672785600703|2|1026", - "extent": "15:16-15:17|4481210672785600703|2|0", + "spell": "15:16-15:17|4481210672785600703|2|1026|-1", + "extent": "15:16-15:17|4481210672785600703|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -206,8 +206,8 @@ OUTPUT: impl.cc "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:10|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -224,7 +224,7 @@ OUTPUT: impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:7|5817708529036841195|3|16420"], + "uses": ["4:3-4:7|5817708529036841195|3|16420|-1"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index df6d723e0..75b57e371 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -16,7 +16,7 @@ OUTPUT: simple_header.h "short_name": "header", "kind": 12, "storage": 0, - "declarations": ["3:6-3:12|0|1|1"], + "declarations": ["3:6-3:12|3:1-3:14|0|1|1|-1"], "bases": [], "derived": [], "vars": [], @@ -41,8 +41,8 @@ OUTPUT: simple_impl.cc "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:10|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -59,7 +59,7 @@ OUTPUT: simple_impl.cc "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:9|3373269392705484958|3|16420"], + "uses": ["4:3-4:9|3373269392705484958|3|16420|-1"], "callees": [] }], "usr2type": [], diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 7b255c5d4..7f8d6c72b 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -14,7 +14,7 @@ OUTPUT: static.h "short_name": "CreateSharedBuffer", "kind": 254, "storage": 0, - "declarations": ["4:15-4:33|9411323049603567600|2|1025"], + "declarations": ["4:15-4:33|4:3-4:35|9411323049603567600|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -28,8 +28,8 @@ OUTPUT: static.h "short_name": "Buffer", "kind": 23, "declarations": [], - "spell": "3:8-3:14|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:8-3:14|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -56,8 +56,8 @@ OUTPUT: static.cc "kind": 254, "storage": 0, "declarations": [], - "spell": "3:14-3:32|9411323049603567600|2|1026", - "extent": "3:1-3:37|9411323049603567600|2|0", + "spell": "3:14-3:32|9411323049603567600|2|1026|-1", + "extent": "3:1-3:37|9411323049603567600|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -78,7 +78,7 @@ OUTPUT: static.cc "funcs": [14576076421851654759], "vars": [], "instances": [], - "uses": ["3:6-3:12|0|1|4"] + "uses": ["3:6-3:12|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index eb89d959b..89d660a7a 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -14,7 +14,7 @@ void foo(); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["2:6-2:9|7144845543074395457|2|1"], + "declarations": ["2:6-2:9|2:1-2:11|7144845543074395457|2|1|-1"], "bases": [], "derived": [], "vars": [], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index ec694bc9e..9ca5a4d88 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -14,7 +14,7 @@ void foo(int a, int b); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["2:6-2:9|2029211996748007610|2|1025"], + "declarations": ["2:6-2:9|2:1-2:23|2029211996748007610|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -27,7 +27,7 @@ void foo(int a, int b); "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": ["1:11-1:16|0|1|1"], + "declarations": ["1:11-1:16|1:1-3:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index ce7845557..e732b06ec 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -15,8 +15,8 @@ void foo() {} "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:9|2029211996748007610|2|1026", - "extent": "2:1-2:14|2029211996748007610|2|0", + "spell": "2:6-2:9|2029211996748007610|2|1026|-1", + "extent": "2:1-2:14|2029211996748007610|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -29,7 +29,7 @@ void foo() {} "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": ["1:11-1:16|0|1|1"], + "declarations": ["1:11-1:16|1:1-3:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index de02f813c..b957b1d5f 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -16,7 +16,7 @@ class Foo { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|1025"], + "declarations": ["3:8-3:11|3:3-3:13|4508214972876735896|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -29,7 +29,7 @@ class Foo { "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": ["1:11-1:16|0|1|1"], + "declarations": ["1:11-1:16|1:1-5:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -45,8 +45,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026", - "extent": "2:1-4:2|2029211996748007610|2|0", + "spell": "2:7-2:10|2029211996748007610|2|1026|-1", + "extent": "2:1-4:2|2029211996748007610|2|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 5a25f7a9f..00f55200d 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -18,9 +18,9 @@ void Foo::foo() {} "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|4508214972876735896|2|1025"], - "spell": "6:11-6:14|4508214972876735896|2|1026", - "extent": "6:1-6:19|4508214972876735896|2|0", + "declarations": ["3:8-3:11|3:3-3:13|4508214972876735896|2|1025|-1"], + "spell": "6:11-6:14|4508214972876735896|2|1026|-1", + "extent": "6:1-6:19|4508214972876735896|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -33,7 +33,7 @@ void Foo::foo() {} "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": ["1:11-1:16|0|1|1"], + "declarations": ["1:11-1:16|1:1-7:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -49,8 +49,8 @@ void Foo::foo() {} "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026", - "extent": "2:1-4:2|2029211996748007610|2|0", + "spell": "2:7-2:10|2029211996748007610|2|1026|-1", + "extent": "2:1-4:2|2029211996748007610|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -58,7 +58,7 @@ void Foo::foo() {} "funcs": [10487325150128053272], "vars": [], "instances": [], - "uses": ["6:6-6:9|2029211996748007610|2|4"] + "uses": ["6:6-6:9|2029211996748007610|2|4|-1"] }], "usr2var": [] } diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index b4029c5f8..4d048be19 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -17,8 +17,8 @@ class Foo { "kind": 6, "storage": 0, "declarations": [], - "spell": "3:8-3:11|4508214972876735896|2|1026", - "extent": "3:3-3:16|4508214972876735896|2|0", + "spell": "3:8-3:11|4508214972876735896|2|1026|-1", + "extent": "3:3-3:16|4508214972876735896|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -31,7 +31,7 @@ class Foo { "qual_name_offset": 10, "short_name": "hello", "kind": 3, - "declarations": ["1:11-1:16|0|1|1"], + "declarations": ["1:11-1:16|1:1-5:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -47,8 +47,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026", - "extent": "2:1-4:2|2029211996748007610|2|0", + "spell": "2:7-2:10|2029211996748007610|2|1026|-1", + "extent": "2:1-4:2|2029211996748007610|2|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 314890b88..b8cbce9c6 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -26,8 +26,8 @@ void func() { "kind": 12, "storage": 0, "declarations": [], - "spell": "11:6-11:10|0|1|2", - "extent": "11:1-14:2|0|1|0", + "spell": "11:6-11:10|0|1|2|-1", + "extent": "11:1-14:2|0|1|0|-1", "bases": [], "derived": [], "vars": [6030927277961448585, 7657277353101371136], @@ -55,7 +55,7 @@ void func() { "qual_name_offset": 10, "short_name": "foo", "kind": 3, - "declarations": ["1:11-1:14|0|1|1"], + "declarations": ["1:11-1:14|1:1-7:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [17805385787823406700], @@ -63,14 +63,14 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["9:17-9:20|0|1|4", "12:11-12:14|10818727483146447186|3|4"] + "uses": ["9:17-9:20|0|1|4|-1", "12:11-12:14|10818727483146447186|3|4|-1"] }, { "usr": 11879713791858506216, "detailed_name": "namespace fbz = foo::bar::baz", "qual_name_offset": 10, "short_name": "fbz", "kind": 252, - "declarations": ["9:11-9:14|0|1|1"], + "declarations": ["9:11-9:14|9:1-9:30|0|1|1|-1"], "alias_of": 14450849931009540802, "bases": [], "derived": [], @@ -78,14 +78,14 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["13:11-13:14|10818727483146447186|3|4"] + "uses": ["13:11-13:14|10818727483146447186|3|4|-1"] }, { "usr": 14450849931009540802, "detailed_name": "namespace foo::bar::baz {}", "qual_name_offset": 10, "short_name": "baz", "kind": 3, - "declarations": ["3:20-3:23|17805385787823406700|2|1025"], + "declarations": ["3:20-3:23|3:10-5:11|17805385787823406700|2|1025|-1"], "alias_of": 0, "bases": [17805385787823406700], "derived": [], @@ -96,14 +96,14 @@ void func() { "R": -1 }], "instances": [], - "uses": ["9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] + "uses": ["9:27-9:30|0|1|4|-1", "12:21-12:24|10818727483146447186|3|4|-1"] }, { "usr": 17805385787823406700, "detailed_name": "namespace foo::bar {}", "qual_name_offset": 10, "short_name": "bar", "kind": 3, - "declarations": ["2:15-2:18|926793467007732869|2|1025"], + "declarations": ["2:15-2:18|2:5-6:6|926793467007732869|2|1025|-1"], "alias_of": 0, "bases": [926793467007732869], "derived": [14450849931009540802], @@ -111,7 +111,7 @@ void func() { "funcs": [], "vars": [], "instances": [], - "uses": ["9:22-9:25|0|1|4", "12:16-12:19|10818727483146447186|3|4"] + "uses": ["9:22-9:25|0|1|4|-1", "12:16-12:19|10818727483146447186|3|4|-1"] }], "usr2var": [{ "usr": 6030927277961448585, @@ -120,8 +120,8 @@ void func() { "short_name": "a", "hover": "int a = foo::bar::baz::qux", "declarations": [], - "spell": "12:7-12:8|10818727483146447186|3|2", - "extent": "12:3-12:29|10818727483146447186|3|0", + "spell": "12:7-12:8|10818727483146447186|3|2|-1", + "extent": "12:3-12:29|10818727483146447186|3|0|-1", "type": 53, "uses": [], "kind": 13, @@ -133,8 +133,8 @@ void func() { "short_name": "b", "hover": "int b = fbz::qux", "declarations": [], - "spell": "13:7-13:8|10818727483146447186|3|2", - "extent": "13:3-13:19|10818727483146447186|3|0", + "spell": "13:7-13:8|10818727483146447186|3|2|-1", + "extent": "13:3-13:19|10818727483146447186|3|0|-1", "type": 53, "uses": [], "kind": 13, @@ -146,10 +146,10 @@ void func() { "short_name": "qux", "hover": "int foo::bar::baz::qux = 42", "declarations": [], - "spell": "4:18-4:21|14450849931009540802|2|1026", - "extent": "4:14-4:26|14450849931009540802|2|0", + "spell": "4:18-4:21|14450849931009540802|2|1026|-1", + "extent": "4:14-4:26|14450849931009540802|2|0|-1", "type": 53, - "uses": ["12:26-12:29|10818727483146447186|3|12", "13:16-13:19|10818727483146447186|3|12"], + "uses": ["12:26-12:29|10818727483146447186|3|12|-1", "13:16-13:19|10818727483146447186|3|12|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 09919e037..4565040d4 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -22,8 +22,8 @@ void Runner() { "kind": 12, "storage": 0, "declarations": [], - "spell": "6:6-6:12|0|1|2", - "extent": "6:1-10:2|0|1|0", + "spell": "6:6-6:12|0|1|2|-1", + "extent": "6:1-10:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -37,12 +37,12 @@ void Runner() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:8-3:14|11072669167287398027|2|1026", - "extent": "3:3-3:24|11072669167287398027|2|0", + "spell": "3:8-3:14|11072669167287398027|2|1026|-1", + "extent": "3:3-3:24|11072669167287398027|2|0|-1", "bases": [], "derived": [], "vars": [3649375698083002347], - "uses": ["7:7-7:13|631910859630953711|3|16420", "9:3-9:9|631910859630953711|3|16420"], + "uses": ["7:7-7:13|631910859630953711|3|16420|-1", "9:3-9:9|631910859630953711|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -66,7 +66,7 @@ void Runner() { "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["1:11-1:13|0|1|1"], + "declarations": ["1:11-1:13|1:1-4:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -77,7 +77,7 @@ void Runner() { "R": -1 }], "instances": [], - "uses": ["7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] + "uses": ["7:3-7:5|631910859630953711|3|4|-1", "7:14-7:16|631910859630953711|3|4|-1", "8:19-8:21|631910859630953711|3|4|-1"] }], "usr2var": [{ "usr": 3649375698083002347, @@ -85,8 +85,8 @@ void Runner() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "3:19-3:20|17328473273923617489|3|1026", - "extent": "3:15-3:20|17328473273923617489|3|0", + "spell": "3:19-3:20|17328473273923617489|3|1026|-1", + "extent": "3:15-3:20|17328473273923617489|3|0|-1", "type": 53, "uses": [], "kind": 253, @@ -97,10 +97,10 @@ void Runner() { "qual_name_offset": 4, "short_name": "Foo", "declarations": [], - "spell": "2:7-2:10|11072669167287398027|2|1026", - "extent": "2:3-2:10|11072669167287398027|2|0", + "spell": "2:7-2:10|11072669167287398027|2|1026|-1", + "extent": "2:3-2:10|11072669167287398027|2|0|-1", "type": 53, - "uses": ["7:18-7:21|631910859630953711|3|12", "9:10-9:13|631910859630953711|3|12"], + "uses": ["7:18-7:21|631910859630953711|3|12|-1", "9:10-9:13|631910859630953711|3|12|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index e05be650a..3a569983e 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -18,7 +18,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["3:8-3:16|15041163540773201510|2|1025"], + "declarations": ["3:8-3:16|3:3-3:24|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -31,7 +31,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator()", "kind": 6, "storage": 0, - "declarations": ["4:7-4:15|15041163540773201510|2|1025"], + "declarations": ["4:7-4:15|4:3-4:31|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -45,8 +45,8 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:16|15041163540773201510|2|1026", - "extent": "2:3-2:27|15041163540773201510|2|0", + "spell": "2:8-2:16|15041163540773201510|2|1026|-1", + "extent": "2:3-2:27|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -59,7 +59,7 @@ Foo &operator += (const Foo&, const int&); "short_name": "operator+=", "kind": 12, "storage": 0, - "declarations": ["7:6-7:14|0|1|1"], + "declarations": ["7:6-7:14|7:1-7:42|0|1|1|-1"], "bases": [], "derived": [], "vars": [], @@ -73,8 +73,8 @@ Foo &operator += (const Foo&, const int&); "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-5:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -82,7 +82,7 @@ Foo &operator += (const Foo&, const int&); "funcs": [7874436189163837815, 3545323327609582678, 3986818119971932909], "vars": [], "instances": [], - "uses": ["7:1-7:4|0|1|4", "7:25-7:28|0|1|4"] + "uses": ["7:1-7:4|0|1|4|-1", "7:25-7:28|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 9826edca2..7bf971e6e 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -18,7 +18,7 @@ OUTPUT: static_function_in_type.h "short_name": "Register", "kind": 254, "storage": 0, - "declarations": ["6:15-6:23|17262466801709381811|2|1025"], + "declarations": ["6:15-6:23|6:3-6:33|17262466801709381811|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -31,7 +31,7 @@ OUTPUT: static_function_in_type.h "qual_name_offset": 6, "short_name": "Manager", "kind": 5, - "declarations": ["3:7-3:14|11072669167287398027|2|1025"], + "declarations": ["3:7-3:14|3:1-3:14|11072669167287398027|2|1025|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -39,14 +39,14 @@ OUTPUT: static_function_in_type.h "funcs": [], "vars": [], "instances": [], - "uses": ["6:24-6:31|17262466801709381811|2|4"] + "uses": ["6:24-6:31|17262466801709381811|2|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["1:11-1:13|0|1|1"], + "declarations": ["1:11-1:13|1:1-9:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -62,8 +62,8 @@ OUTPUT: static_function_in_type.h "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|11072669167287398027|2|1026", - "extent": "5:1-7:2|11072669167287398027|2|0", + "spell": "5:8-5:11|11072669167287398027|2|1026|-1", + "extent": "5:1-7:2|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -91,8 +91,8 @@ OUTPUT: static_function_in_type.cc "storage": 0, "comments": "static", "declarations": [], - "spell": "5:11-5:19|17262466801709381811|2|1026", - "extent": "5:1-6:2|17262466801709381811|2|0", + "spell": "5:11-5:19|17262466801709381811|2|1026|-1", + "extent": "5:1-6:2|17262466801709381811|2|0|-1", "bases": [], "derived": [], "vars": [13569879755236306838], @@ -113,14 +113,14 @@ OUTPUT: static_function_in_type.cc "funcs": [], "vars": [], "instances": [13569879755236306838], - "uses": ["5:20-5:27|11072669167287398027|2|4"] + "uses": ["5:20-5:27|11072669167287398027|2|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["3:11-3:13|0|1|1"], + "declarations": ["3:11-3:13|3:1-7:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -143,7 +143,7 @@ OUTPUT: static_function_in_type.cc "funcs": [17019747379608639279], "vars": [], "instances": [], - "uses": ["5:6-5:9|11072669167287398027|2|4"] + "uses": ["5:6-5:9|11072669167287398027|2|4|-1"] }], "usr2var": [{ "usr": 13569879755236306838, @@ -151,8 +151,8 @@ OUTPUT: static_function_in_type.cc "qual_name_offset": 13, "short_name": "m", "declarations": [], - "spell": "5:29-5:30|17019747379608639279|3|1026", - "extent": "5:20-5:30|17019747379608639279|3|0", + "spell": "5:29-5:30|17019747379608639279|3|1026|-1", + "extent": "5:20-5:30|17019747379608639279|3|0|-1", "type": 1972401196751872203, "uses": [], "kind": 253, diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 5b4ef8076..d9d069f79 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -17,8 +17,8 @@ "short_name": "FOO", "hover": "#define FOO", "declarations": [], - "spell": "2:9-2:12|0|1|2", - "extent": "2:9-2:12|0|1|0", + "spell": "2:9-2:12|0|1|2|-1", + "extent": "2:9-2:12|0|1|0|-1", "type": 0, "uses": [], "kind": 255, diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 7d5f44beb..322228113 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -19,9 +19,9 @@ void Foo::Bar(Template&) {} "short_name": "Bar", "kind": 6, "storage": 0, - "declarations": ["5:8-5:11|15041163540773201510|2|1025"], - "spell": "8:11-8:14|15041163540773201510|2|1026", - "extent": "8:1-8:36|15041163540773201510|2|0", + "declarations": ["5:8-5:11|5:3-5:30|15041163540773201510|2|1025|-1"], + "spell": "8:11-8:14|15041163540773201510|2|1026|-1", + "extent": "8:1-8:36|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -42,7 +42,7 @@ void Foo::Bar(Template&) {} "funcs": [], "vars": [], "instances": [], - "uses": ["5:12-5:20|15041163540773201510|2|4", "8:15-8:23|0|1|4"] + "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", @@ -50,8 +50,8 @@ void Foo::Bar(Template&) {} "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "4:8-4:11|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:8-4:11|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -59,7 +59,7 @@ void Foo::Bar(Template&) {} "funcs": [8412238651648388423], "vars": [], "instances": [], - "uses": ["8:6-8:9|0|1|4"] + "uses": ["8:6-8:9|0|1|4|-1"] }, { "usr": 17107291254533526269, "detailed_name": "class Template {}", @@ -67,8 +67,8 @@ void Foo::Bar(Template&) {} "short_name": "Template", "kind": 5, "declarations": [], - "spell": "2:7-2:15|0|1|2", - "extent": "2:1-2:18|0|1|0", + "spell": "2:7-2:15|0|1|2|-1", + "extent": "2:1-2:18|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 36a978218..6548d39bf 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -42,8 +42,8 @@ namespace ns { "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "2:8-2:15|11072669167287398027|2|1026", - "extent": "2:3-2:18|11072669167287398027|2|0", + "spell": "2:8-2:15|11072669167287398027|2|1026|-1", + "extent": "2:3-2:18|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -51,14 +51,14 @@ namespace ns { "funcs": [], "vars": [], "instances": [4731849186641714451, 4731849186641714451], - "uses": ["6:22-6:29|12688716854043726585|2|4", "6:44-6:51|12688716854043726585|2|4", "10:18-10:25|11072669167287398027|2|4"] + "uses": ["6:22-6:29|12688716854043726585|2|4|-1", "6:44-6:51|12688716854043726585|2|4|-1", "10:18-10:25|11072669167287398027|2|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["1:11-1:13|0|1|1"], + "declarations": ["1:11-1:13|1:1-15:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -80,8 +80,8 @@ namespace ns { "short_name": "Holder", "kind": 23, "declarations": [], - "spell": "5:10-5:16|11072669167287398027|2|1026", - "extent": "5:3-7:4|11072669167287398027|2|0", + "spell": "5:10-5:16|11072669167287398027|2|1026|-1", + "extent": "5:3-7:4|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -89,7 +89,7 @@ namespace ns { "funcs": [], "vars": [], "instances": [], - "uses": ["10:26-10:32|11072669167287398027|2|4", "13:13-13:19|11072669167287398027|2|4", "14:14-14:20|11072669167287398027|2|4"] + "uses": ["10:26-10:32|11072669167287398027|2|4|-1", "13:13-13:19|11072669167287398027|2|4|-1", "14:14-14:20|11072669167287398027|2|4|-1"] }], "usr2var": [{ "usr": 4731849186641714451, @@ -97,11 +97,11 @@ namespace ns { "qual_name_offset": 29, "short_name": "static_var", "hover": "static constexpr ns::VarType ns::Holder::static_var = (VarType)0x0", - "declarations": ["6:30-6:40|12688716854043726585|2|1025"], - "spell": "10:37-10:47|12688716854043726585|2|1026", - "extent": "9:3-10:47|12688716854043726585|2|0", + "declarations": ["6:30-6:40|6:5-6:55|12688716854043726585|2|1025|-1"], + "spell": "10:37-10:47|12688716854043726585|2|1026|-1", + "extent": "9:3-10:47|12688716854043726585|2|0|-1", "type": 1532099849728741556, - "uses": ["13:26-13:36|11072669167287398027|2|12", "14:27-14:37|11072669167287398027|2|12"], + "uses": ["13:26-13:36|11072669167287398027|2|12|-1", "14:27-14:37|11072669167287398027|2|12|-1"], "kind": 13, "storage": 2 }, { @@ -111,8 +111,8 @@ namespace ns { "short_name": "Foo2", "hover": "int ns::Foo2 = Holder::static_var", "declarations": [], - "spell": "14:7-14:11|11072669167287398027|2|1026", - "extent": "14:3-14:37|11072669167287398027|2|0", + "spell": "14:7-14:11|11072669167287398027|2|1026|-1", + "extent": "14:3-14:37|11072669167287398027|2|0|-1", "type": 53, "uses": [], "kind": 13, @@ -124,8 +124,8 @@ namespace ns { "short_name": "Foo", "hover": "int ns::Foo = Holder::static_var", "declarations": [], - "spell": "13:7-13:10|11072669167287398027|2|1026", - "extent": "13:3-13:36|11072669167287398027|2|0", + "spell": "13:7-13:10|11072669167287398027|2|1026|-1", + "extent": "13:3-13:36|11072669167287398027|2|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index e4b593918..312441e28 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -33,8 +33,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2", - "extent": "8:1-8:11|0|1|0", + "spell": "8:6-8:9|0|1|2|-1", + "extent": "8:1-8:11|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -47,7 +47,7 @@ void foo() { "short_name": "bar", "kind": 6, "storage": 0, - "declarations": ["4:8-4:11|8402783583255987702|2|1025"], + "declarations": ["4:8-4:11|4:3-4:13|8402783583255987702|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -61,8 +61,8 @@ void foo() { "short_name": "C", "kind": 23, "declarations": [], - "spell": "2:8-2:9|0|1|2", - "extent": "2:1-5:2|0|1|0", + "spell": "2:8-2:9|0|1|2|-1", + "extent": "2:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -81,8 +81,8 @@ void foo() { "short_name": "T", "kind": 26, "declarations": [], - "spell": "1:17-1:18|8402783583255987702|2|2", - "extent": "1:11-1:18|8402783583255987702|2|0", + "spell": "1:17-1:18|8402783583255987702|2|2|-1", + "extent": "1:11-1:18|8402783583255987702|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -98,8 +98,8 @@ void foo() { "qual_name_offset": 2, "short_name": "x", "declarations": [], - "spell": "3:5-3:6|8402783583255987702|2|1026", - "extent": "3:3-3:6|8402783583255987702|2|0", + "spell": "3:5-3:6|8402783583255987702|2|1026|-1", + "extent": "3:3-3:6|8402783583255987702|2|0|-1", "type": 14750650276757822712, "uses": [], "kind": 8, diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index d0fb3cb45..a9005f186 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -24,12 +24,12 @@ namespace ns { "kind": 254, "storage": 0, "declarations": [], - "spell": "5:16-5:19|14042997404480181958|2|1026", - "extent": "5:5-7:6|14042997404480181958|2|0", + "spell": "5:16-5:19|14042997404480181958|2|1026|-1", + "extent": "5:5-7:6|14042997404480181958|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["10:21-10:24|11072669167287398027|2|36", "11:22-11:25|11072669167287398027|2|36"], + "uses": ["10:21-10:24|11072669167287398027|2|36|-1", "11:22-11:25|11072669167287398027|2|36|-1"], "callees": [] }], "usr2type": [{ @@ -53,7 +53,7 @@ namespace ns { "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["1:11-1:13|0|1|1"], + "declarations": ["1:11-1:13|1:1-12:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -75,8 +75,8 @@ namespace ns { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "3:10-3:13|11072669167287398027|2|1026", - "extent": "3:3-8:4|11072669167287398027|2|0", + "spell": "3:10-3:13|11072669167287398027|2|1026|-1", + "extent": "3:3-8:4|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -84,7 +84,7 @@ namespace ns { "funcs": [8221803074608342407], "vars": [], "instances": [], - "uses": ["10:11-10:14|11072669167287398027|2|4", "11:11-11:14|11072669167287398027|2|4"] + "uses": ["10:11-10:14|11072669167287398027|2|4|-1", "11:11-11:14|11072669167287398027|2|4|-1"] }], "usr2var": [{ "usr": 3182917058194750998, @@ -93,8 +93,8 @@ namespace ns { "short_name": "b", "hover": "int ns::b = Foo::foo()", "declarations": [], - "spell": "11:7-11:8|11072669167287398027|2|1026", - "extent": "11:3-11:35|11072669167287398027|2|0", + "spell": "11:7-11:8|11072669167287398027|2|1026|-1", + "extent": "11:3-11:35|11072669167287398027|2|0|-1", "type": 53, "uses": [], "kind": 13, @@ -106,8 +106,8 @@ namespace ns { "short_name": "a", "hover": "int ns::a = Foo::foo()", "declarations": [], - "spell": "10:7-10:8|11072669167287398027|2|1026", - "extent": "10:3-10:33|11072669167287398027|2|0", + "spell": "10:7-10:8|11072669167287398027|2|1026|-1", + "extent": "10:3-10:33|11072669167287398027|2|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index 0476c03ad..c7ce4fae8 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -19,8 +19,8 @@ namespace ns { "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|2", - "extent": "2:3-3:15|11072669167287398027|2|0", + "spell": "3:9-3:12|11072669167287398027|2|2|-1", + "extent": "2:3-3:15|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -36,8 +36,8 @@ namespace ns { "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|2", - "extent": "2:3-3:15|11072669167287398027|2|0", + "spell": "3:9-3:12|11072669167287398027|2|2|-1", + "extent": "2:3-3:15|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -52,7 +52,7 @@ namespace ns { "qual_name_offset": 10, "short_name": "ns", "kind": 3, - "declarations": ["1:11-1:13|0|1|1"], + "declarations": ["1:11-1:13|1:1-7:2|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -74,8 +74,8 @@ namespace ns { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|1026", - "extent": "3:3-3:15|11072669167287398027|2|0", + "spell": "3:9-3:12|11072669167287398027|2|1026|-1", + "extent": "3:3-3:15|11072669167287398027|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -83,7 +83,7 @@ namespace ns { "funcs": [], "vars": [], "instances": [], - "uses": ["5:3-5:6|11072669167287398027|2|4", "6:3-6:6|11072669167287398027|2|4"] + "uses": ["5:3-5:6|11072669167287398027|2|4|-1", "6:3-6:6|11072669167287398027|2|4|-1"] }], "usr2var": [{ "usr": 3182917058194750998, @@ -91,8 +91,8 @@ namespace ns { "qual_name_offset": 10, "short_name": "b", "declarations": [], - "spell": "6:13-6:14|11072669167287398027|2|1026", - "extent": "6:3-6:14|11072669167287398027|2|0", + "spell": "6:13-6:14|11072669167287398027|2|1026|-1", + "extent": "6:3-6:14|11072669167287398027|2|0|-1", "type": 3948666349864691553, "uses": [], "kind": 13, @@ -103,8 +103,8 @@ namespace ns { "qual_name_offset": 9, "short_name": "a", "declarations": [], - "spell": "5:12-5:13|11072669167287398027|2|1026", - "extent": "5:3-5:13|11072669167287398027|2|0", + "spell": "5:12-5:13|11072669167287398027|2|1026|-1", + "extent": "5:3-5:13|11072669167287398027|2|0|-1", "type": 8224244241460152567, "uses": [], "kind": 13, diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 7b8960c13..d597a78cf 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -54,7 +54,7 @@ void foo(float Value); "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["43:6-43:9|0|1|1"], + "declarations": ["43:6-43:9|42:1-43:50|0|1|1|-1"], "bases": [], "derived": [], "vars": [], @@ -67,7 +67,7 @@ void foo(float Value); "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["27:8-27:13|1663022413889915338|2|1025"], + "declarations": ["27:8-27:13|27:3-27:15|1663022413889915338|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -81,8 +81,8 @@ void foo(float Value); "kind": 12, "storage": 0, "declarations": [], - "spell": "39:6-39:9|0|1|2", - "extent": "39:1-39:21|0|1|0", + "spell": "39:6-39:9|0|1|2|-1", + "extent": "39:1-39:21|0|1|0|-1", "bases": [], "derived": [], "vars": [17826688417349629938], @@ -95,7 +95,7 @@ void foo(float Value); "short_name": "clear", "kind": 6, "storage": 0, - "declarations": ["13:8-13:13|7440942986741176606|2|1025"], + "declarations": ["13:8-13:13|13:3-13:15|7440942986741176606|2|1025|-1"], "bases": [], "derived": [], "vars": [], @@ -124,8 +124,8 @@ void foo(float Value); "short_name": "function", "kind": 5, "declarations": [], - "spell": "5:7-5:15|0|1|2", - "extent": "4:1-5:30|0|1|0", + "spell": "5:7-5:15|0|1|2|-1", + "extent": "4:1-5:30|0|1|0|-1", "alias_of": 0, "bases": [15019211479263750068], "derived": [], @@ -133,7 +133,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["7:1-7:9|0|1|4"] + "uses": ["7:1-7:9|0|1|4|-1"] }, { "usr": 1663022413889915338, "detailed_name": "template<> class vector> {}", @@ -141,8 +141,8 @@ void foo(float Value); "short_name": "vector", "kind": 5, "declarations": [], - "spell": "26:7-26:13|0|1|2", - "extent": "25:1-28:2|0|1|0", + "spell": "26:7-26:13|0|1|2|-1", + "extent": "25:1-28:2|0|1|0|-1", "alias_of": 0, "bases": [7440942986741176606], "derived": [], @@ -150,7 +150,7 @@ void foo(float Value); "funcs": [6113470698424012876], "vars": [], "instances": [15931696253641284761], - "uses": ["26:7-26:13|0|1|4", "33:1-33:7|0|1|4"] + "uses": ["26:7-26:13|0|1|4|-1", "33:1-33:7|0|1|4|-1"] }, { "usr": 3231449734830406187, "detailed_name": "function", @@ -158,8 +158,8 @@ void foo(float Value); "short_name": "function", "kind": 26, "declarations": [], - "spell": "5:7-5:15|0|1|2", - "extent": "4:1-5:30|0|1|0", + "spell": "5:7-5:15|0|1|2|-1", + "extent": "4:1-5:30|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -175,8 +175,8 @@ void foo(float Value); "short_name": "Z1", "kind": 23, "declarations": [], - "spell": "19:8-19:10|0|1|2", - "extent": "19:1-19:13|0|1|0", + "spell": "19:8-19:10|0|1|2|-1", + "extent": "19:1-19:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -184,7 +184,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["21:23-21:25|0|1|4", "32:8-32:10|0|1|4"] + "uses": ["21:23-21:25|0|1|4|-1", "32:8-32:10|0|1|4|-1"] }, { "usr": 7440942986741176606, "detailed_name": "class vector {}", @@ -192,8 +192,8 @@ void foo(float Value); "short_name": "vector", "kind": 5, "declarations": [], - "spell": "12:7-12:13|0|1|2", - "extent": "12:1-14:2|0|1|0", + "spell": "12:7-12:13|0|1|2|-1", + "extent": "12:1-14:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [16155717907537731864, 1663022413889915338], @@ -201,7 +201,7 @@ void foo(float Value); "funcs": [18107614608385228556], "vars": [], "instances": [], - "uses": ["21:16-21:22|0|1|4", "30:1-30:7|0|1|4", "32:1-32:7|0|1|4"] + "uses": ["21:16-21:22|0|1|4|-1", "30:1-30:7|0|1|4|-1", "32:1-32:7|0|1|4|-1"] }, { "usr": 9201299975592934124, "detailed_name": "enum Enum {}", @@ -209,8 +209,8 @@ void foo(float Value); "short_name": "Enum", "kind": 10, "declarations": [], - "spell": "35:6-35:10|0|1|2", - "extent": "35:1-37:2|0|1|0", + "spell": "35:6-35:10|0|1|2|-1", + "extent": "35:1-37:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -226,8 +226,8 @@ void foo(float Value); "short_name": "Z2", "kind": 23, "declarations": [], - "spell": "23:8-23:10|0|1|2", - "extent": "23:1-23:13|0|1|0", + "spell": "23:8-23:10|0|1|2|-1", + "extent": "23:1-23:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -235,7 +235,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["26:14-26:16|0|1|4", "33:8-33:10|0|1|4"] + "uses": ["26:14-26:16|0|1|4|-1", "33:8-33:10|0|1|4|-1"] }, { "usr": 11153492883079050853, "detailed_name": "vector", @@ -243,8 +243,8 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "17:7-17:13|0|1|2", - "extent": "16:1-17:20|0|1|0", + "spell": "17:7-17:13|0|1|2|-1", + "extent": "16:1-17:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -260,8 +260,8 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "12:7-12:13|0|1|2", - "extent": "11:1-14:2|0|1|0", + "spell": "12:7-12:13|0|1|2|-1", + "extent": "11:1-14:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -277,8 +277,8 @@ void foo(float Value); "short_name": "T", "kind": 26, "declarations": [], - "spell": "38:20-38:21|17498190318698490707|3|2", - "extent": "38:11-38:21|17498190318698490707|3|0", + "spell": "38:20-38:21|17498190318698490707|3|2|-1", + "extent": "38:11-38:21|17498190318698490707|3|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -293,7 +293,7 @@ void foo(float Value); "qual_name_offset": 6, "short_name": "function", "kind": 5, - "declarations": ["2:7-2:15|0|1|1"], + "declarations": ["2:7-2:15|2:1-2:15|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [218068462278884837], @@ -309,8 +309,8 @@ void foo(float Value); "short_name": "vector", "kind": 26, "declarations": [], - "spell": "21:16-21:22|0|1|2", - "extent": "21:1-21:26|0|1|0", + "spell": "21:16-21:22|0|1|2|-1", + "extent": "21:1-21:26|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -325,7 +325,7 @@ void foo(float Value); "qual_name_offset": 6, "short_name": "allocator", "kind": 5, - "declarations": ["9:28-9:37|0|1|1"], + "declarations": ["9:28-9:37|9:22-9:37|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -341,8 +341,8 @@ void foo(float Value); "short_name": "vector", "kind": 5, "declarations": [], - "spell": "17:7-17:13|0|1|2", - "extent": "16:1-17:20|0|1|0", + "spell": "17:7-17:13|0|1|2|-1", + "extent": "16:1-17:20|0|1|0|-1", "alias_of": 0, "bases": [7440942986741176606], "derived": [], @@ -350,7 +350,7 @@ void foo(float Value); "funcs": [], "vars": [], "instances": [], - "uses": ["31:1-31:7|0|1|4"] + "uses": ["31:1-31:7|0|1|4|-1"] }], "usr2var": [{ "usr": 86949563628772958, @@ -358,8 +358,8 @@ void foo(float Value); "qual_name_offset": 14, "short_name": "vip", "declarations": [], - "spell": "31:14-31:17|0|1|2", - "extent": "31:1-31:17|0|1|0", + "spell": "31:14-31:17|0|1|2|-1", + "extent": "31:1-31:17|0|1|0|-1", "type": 11153492883079050853, "uses": [], "kind": 13, @@ -370,8 +370,8 @@ void foo(float Value); "qual_name_offset": 21, "short_name": "f", "declarations": [], - "spell": "7:21-7:22|0|1|2", - "extent": "7:1-7:22|0|1|0", + "spell": "7:21-7:22|0|1|2|-1", + "extent": "7:1-7:22|0|1|0|-1", "type": 3231449734830406187, "uses": [], "kind": 13, @@ -382,8 +382,8 @@ void foo(float Value); "qual_name_offset": 11, "short_name": "vz1", "declarations": [], - "spell": "32:12-32:15|0|1|2", - "extent": "32:1-32:15|0|1|0", + "spell": "32:12-32:15|0|1|2|-1", + "extent": "32:1-32:15|0|1|0|-1", "type": 15440970074034693939, "uses": [], "kind": 13, @@ -395,8 +395,8 @@ void foo(float Value); "short_name": "Enum1", "hover": "Enum1 = 1", "declarations": [], - "spell": "36:10-36:15|9201299975592934124|2|1026", - "extent": "36:10-36:15|9201299975592934124|2|0", + "spell": "36:10-36:15|9201299975592934124|2|1026|-1", + "extent": "36:10-36:15|9201299975592934124|2|0|-1", "type": 0, "uses": [], "kind": 22, @@ -407,8 +407,8 @@ void foo(float Value); "qual_name_offset": 13, "short_name": "vc", "declarations": [], - "spell": "30:14-30:16|0|1|2", - "extent": "30:1-30:16|0|1|0", + "spell": "30:14-30:16|0|1|2|-1", + "extent": "30:1-30:16|0|1|0|-1", "type": 13322943937025195708, "uses": [], "kind": 13, @@ -420,10 +420,10 @@ void foo(float Value); "short_name": "kOnst", "hover": "static const int kOnst = 7", "declarations": [], - "spell": "41:18-41:23|0|1|2", - "extent": "41:1-41:27|0|1|0", + "spell": "41:18-41:23|0|1|2|-1", + "extent": "41:1-41:27|0|1|0|-1", "type": 53, - "uses": ["43:27-43:32|0|1|12"], + "uses": ["43:27-43:32|0|1|12|-1"], "kind": 13, "storage": 2 }, { @@ -433,10 +433,10 @@ void foo(float Value); "short_name": "Enum0", "hover": "Enum0 = 0", "declarations": [], - "spell": "36:3-36:8|9201299975592934124|2|1026", - "extent": "36:3-36:8|9201299975592934124|2|0", + "spell": "36:3-36:8|9201299975592934124|2|1026|-1", + "extent": "36:3-36:8|9201299975592934124|2|0|-1", "type": 0, - "uses": ["43:20-43:25|0|1|4"], + "uses": ["43:20-43:25|0|1|4|-1"], "kind": 22, "storage": 0 }, { @@ -445,8 +445,8 @@ void foo(float Value); "qual_name_offset": 11, "short_name": "vz2", "declarations": [], - "spell": "33:12-33:15|0|1|2", - "extent": "33:1-33:15|0|1|0", + "spell": "33:12-33:15|0|1|2|-1", + "extent": "33:1-33:15|0|1|0|-1", "type": 1663022413889915338, "uses": [], "kind": 13, @@ -457,8 +457,8 @@ void foo(float Value); "qual_name_offset": 2, "short_name": "Value", "declarations": [], - "spell": "39:12-39:17|17498190318698490707|3|1026", - "extent": "39:10-39:17|17498190318698490707|3|0", + "spell": "39:12-39:17|17498190318698490707|3|1026|-1", + "extent": "39:10-39:17|17498190318698490707|3|0|-1", "type": 14111105212951082474, "uses": [], "kind": 253, diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 07c0d4757..17dfb7836 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -30,8 +30,8 @@ void Template::Foo() {} "kind": 6, "storage": 0, "declarations": [], - "spell": "10:22-10:25|17649312483543982122|2|1026", - "extent": "9:1-10:30|17649312483543982122|2|0", + "spell": "10:22-10:25|17649312483543982122|2|1026|-1", + "extent": "9:1-10:30|17649312483543982122|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -44,9 +44,9 @@ void Template::Foo() {} "short_name": "Foo", "kind": 6, "storage": 0, - "declarations": ["3:8-3:11|17107291254533526269|2|1025"], - "spell": "7:19-7:22|17107291254533526269|2|1026", - "extent": "6:1-7:24|17107291254533526269|2|0", + "declarations": ["3:8-3:11|3:3-3:13|17107291254533526269|2|1025|-1"], + "spell": "7:19-7:22|17107291254533526269|2|1026|-1", + "extent": "6:1-7:24|17107291254533526269|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -60,8 +60,8 @@ void Template::Foo() {} "short_name": "Template", "kind": 5, "declarations": [], - "spell": "2:7-2:15|0|1|2", - "extent": "2:1-4:2|0|1|0", + "spell": "2:7-2:15|0|1|2|-1", + "extent": "2:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -69,7 +69,7 @@ void Template::Foo() {} "funcs": [11994188353303124840], "vars": [], "instances": [], - "uses": ["7:6-7:14|0|1|4", "10:6-10:14|0|1|4"] + "uses": ["7:6-7:14|0|1|4|-1", "10:6-10:14|0|1|4|-1"] }, { "usr": 17649312483543982122, "detailed_name": "", diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 93d129987..2297d9966 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -21,12 +21,12 @@ int b = Foo::foo(); "kind": 254, "storage": 0, "declarations": [], - "spell": "3:14-3:17|10528472276654770367|2|1026", - "extent": "3:3-5:4|10528472276654770367|2|0", + "spell": "3:14-3:17|10528472276654770367|2|1026|-1", + "extent": "3:3-5:4|10528472276654770367|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["8:19-8:22|0|1|36", "9:20-9:23|0|1|36"], + "uses": ["8:19-8:22|0|1|36|-1", "9:20-9:23|0|1|36|-1"], "callees": [] }], "usr2type": [{ @@ -51,8 +51,8 @@ int b = Foo::foo(); "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "2:8-2:11|0|1|2", - "extent": "2:1-6:2|0|1|0", + "spell": "2:8-2:11|0|1|2|-1", + "extent": "2:1-6:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -60,7 +60,7 @@ int b = Foo::foo(); "funcs": [8340731781048851399], "vars": [], "instances": [], - "uses": ["8:9-8:12|0|1|4", "9:9-9:12|0|1|4"] + "uses": ["8:9-8:12|0|1|4|-1", "9:9-9:12|0|1|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -69,8 +69,8 @@ int b = Foo::foo(); "short_name": "b", "hover": "int b = Foo::foo()", "declarations": [], - "spell": "9:5-9:6|0|1|2", - "extent": "9:1-9:25|0|1|0", + "spell": "9:5-9:6|0|1|2|-1", + "extent": "9:1-9:25|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -82,8 +82,8 @@ int b = Foo::foo(); "short_name": "a", "hover": "int a = Foo::foo()", "declarations": [], - "spell": "8:5-8:6|0|1|2", - "extent": "8:1-8:24|0|1|0", + "spell": "8:5-8:6|0|1|2|-1", + "extent": "8:1-8:24|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index a38322c34..3fcb3672f 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -22,12 +22,12 @@ int b = Foo::foo(); "kind": 254, "storage": 0, "declarations": [], - "spell": "4:14-4:17|10528472276654770367|2|1026", - "extent": "4:3-6:4|10528472276654770367|2|0", + "spell": "4:14-4:17|10528472276654770367|2|1026|-1", + "extent": "4:3-6:4|10528472276654770367|2|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["9:19-9:22|0|1|36", "10:20-10:23|0|1|36"], + "uses": ["9:19-9:22|0|1|36|-1", "10:20-10:23|0|1|36|-1"], "callees": [] }], "usr2type": [{ @@ -52,8 +52,8 @@ int b = Foo::foo(); "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "2:8-2:11|0|1|2", - "extent": "2:1-7:2|0|1|0", + "spell": "2:8-2:11|0|1|2|-1", + "extent": "2:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -61,7 +61,7 @@ int b = Foo::foo(); "funcs": [9034026360701857235], "vars": [], "instances": [], - "uses": ["9:9-9:12|0|1|4", "10:9-10:12|0|1|4"] + "uses": ["9:9-9:12|0|1|4|-1", "10:9-10:12|0|1|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -70,8 +70,8 @@ int b = Foo::foo(); "short_name": "b", "hover": "int b = Foo::foo()", "declarations": [], - "spell": "10:5-10:6|0|1|2", - "extent": "10:1-10:33|0|1|0", + "spell": "10:5-10:6|0|1|2|-1", + "extent": "10:1-10:33|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -83,8 +83,8 @@ int b = Foo::foo(); "short_name": "a", "hover": "int a = Foo::foo()", "declarations": [], - "spell": "9:5-9:6|0|1|2", - "extent": "9:1-9:31|0|1|0", + "spell": "9:5-9:6|0|1|2|-1", + "extent": "9:1-9:31|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 7115ebc92..e1b1b8290 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -40,8 +40,8 @@ VarDecl b "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|0|1|2", - "extent": "1:1-1:10|0|1|0", + "spell": "1:6-1:7|0|1|2|-1", + "extent": "1:1-1:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -49,7 +49,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [], - "uses": ["9:5-9:6|0|1|4"] + "uses": ["9:5-9:6|0|1|4|-1"] }, { "usr": 7074603899792463171, "detailed_name": "Inner", @@ -57,8 +57,8 @@ VarDecl b "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:10-6:15|0|1|2", - "extent": "6:3-6:18|0|1|0", + "spell": "6:10-6:15|0|1|2|-1", + "extent": "6:3-6:18|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -74,8 +74,8 @@ VarDecl b "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:8-5:11|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -83,7 +83,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [], - "uses": ["9:1-9:4|0|1|4", "10:1-10:4|0|1|4"] + "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] }, { "usr": 13892793056005362145, "detailed_name": "enum B {}", @@ -91,8 +91,8 @@ VarDecl b "short_name": "B", "kind": 10, "declarations": [], - "spell": "2:6-2:7|0|1|2", - "extent": "2:1-2:10|0|1|0", + "spell": "2:6-2:7|0|1|2|-1", + "extent": "2:1-2:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -100,7 +100,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [], - "uses": ["10:5-10:6|0|1|4"] + "uses": ["10:5-10:6|0|1|4|-1"] }, { "usr": 13938528237873543349, "detailed_name": "struct Foo::Inner {}", @@ -108,8 +108,8 @@ VarDecl b "short_name": "Inner", "kind": 23, "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|1026", - "extent": "6:3-6:18|10528472276654770367|2|0", + "spell": "6:10-6:15|10528472276654770367|2|1026|-1", + "extent": "6:3-6:18|10528472276654770367|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -117,7 +117,7 @@ VarDecl b "funcs": [], "vars": [], "instances": [], - "uses": ["9:9-9:14|0|1|4", "10:9-10:14|0|1|4"] + "uses": ["9:9-9:14|0|1|4|-1", "10:9-10:14|0|1|4|-1"] }, { "usr": 15961308565836244174, "detailed_name": "Inner", @@ -125,8 +125,8 @@ VarDecl b "short_name": "Inner", "kind": 26, "declarations": [], - "spell": "6:10-6:15|0|1|2", - "extent": "6:3-6:18|0|1|0", + "spell": "6:10-6:15|0|1|2|-1", + "extent": "6:3-6:18|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -142,8 +142,8 @@ VarDecl b "qual_name_offset": 14, "short_name": "b", "declarations": [], - "spell": "10:15-10:16|0|1|2", - "extent": "10:1-10:16|0|1|0", + "spell": "10:15-10:16|0|1|2|-1", + "extent": "10:1-10:16|0|1|0|-1", "type": 15961308565836244174, "uses": [], "kind": 13, @@ -154,8 +154,8 @@ VarDecl b "qual_name_offset": 14, "short_name": "a", "declarations": [], - "spell": "9:15-9:16|0|1|2", - "extent": "9:1-9:16|0|1|0", + "spell": "9:15-9:16|0|1|2|-1", + "extent": "9:1-9:16|0|1|0|-1", "type": 7074603899792463171, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index fd1726719..23d2ed6a4 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -34,8 +34,8 @@ int b = Foo::var; "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "2:8-2:11|0|1|2", - "extent": "2:1-4:2|0|1|0", + "spell": "2:8-2:11|0|1|2|-1", + "extent": "2:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ int b = Foo::var; "funcs": [], "vars": [], "instances": [], - "uses": ["6:9-6:12|0|1|4", "7:9-7:12|0|1|4"] + "uses": ["6:9-6:12|0|1|4|-1", "7:9-7:12|0|1|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -52,8 +52,8 @@ int b = Foo::var; "short_name": "b", "hover": "int b = Foo::var", "declarations": [], - "spell": "7:5-7:6|0|1|2", - "extent": "7:1-7:23|0|1|0", + "spell": "7:5-7:6|0|1|2|-1", + "extent": "7:1-7:23|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -64,9 +64,9 @@ int b = Foo::var; "qual_name_offset": 21, "short_name": "var", "hover": "static constexpr int Foo::var = 3", - "declarations": ["3:24-3:27|10528472276654770367|2|1025"], + "declarations": ["3:24-3:27|3:3-3:31|10528472276654770367|2|1025|-1"], "type": 53, - "uses": ["6:19-6:22|0|1|12", "7:20-7:23|0|1|12"], + "uses": ["6:19-6:22|0|1|12|-1", "7:20-7:23|0|1|12|-1"], "kind": 13, "storage": 2 }, { @@ -76,8 +76,8 @@ int b = Foo::var; "short_name": "a", "hover": "int a = Foo::var", "declarations": [], - "spell": "6:5-6:6|0|1|2", - "extent": "6:1-6:22|0|1|0", + "spell": "6:5-6:6|0|1|2|-1", + "extent": "6:1-6:22|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index 8fccd50a0..c93297116 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -22,12 +22,12 @@ int b = foo(); "kind": 12, "storage": 0, "declarations": [], - "spell": "2:12-2:15|0|1|2", - "extent": "2:1-4:2|0|1|0", + "spell": "2:12-2:15|0|1|2|-1", + "extent": "2:1-4:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["6:9-6:12|0|1|36", "7:9-7:12|0|1|36"], + "uses": ["6:9-6:12|0|1|36|-1", "7:9-7:12|0|1|36|-1"], "callees": [] }], "usr2type": [{ @@ -53,8 +53,8 @@ int b = foo(); "short_name": "b", "hover": "int b = foo()", "declarations": [], - "spell": "7:5-7:6|0|1|2", - "extent": "7:1-7:20|0|1|0", + "spell": "7:5-7:6|0|1|2|-1", + "extent": "7:1-7:20|0|1|0|-1", "type": 53, "uses": [], "kind": 13, @@ -66,8 +66,8 @@ int b = foo(); "short_name": "a", "hover": "int a = foo()", "declarations": [], - "spell": "6:5-6:6|0|1|2", - "extent": "6:1-6:19|0|1|0", + "spell": "6:5-6:6|0|1|2|-1", + "extent": "6:1-6:19|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index 0c83f7d8c..bb9745e83 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -17,8 +17,8 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "2:7-2:10|0|1|2", - "extent": "1:1-2:13|0|1|0", + "spell": "2:7-2:10|0|1|2|-1", + "extent": "1:1-2:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -34,8 +34,8 @@ Foo b; "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "2:7-2:10|0|1|2", - "extent": "2:1-2:13|0|1|0", + "spell": "2:7-2:10|0|1|2|-1", + "extent": "2:1-2:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ Foo b; "funcs": [], "vars": [], "instances": [], - "uses": ["4:1-4:4|0|1|4", "5:1-5:4|0|1|4"] + "uses": ["4:1-4:4|0|1|4|-1", "5:1-5:4|0|1|4|-1"] }, { "usr": 14134940367505932005, "detailed_name": "Foo", @@ -51,8 +51,8 @@ Foo b; "short_name": "Foo", "kind": 26, "declarations": [], - "spell": "2:7-2:10|0|1|2", - "extent": "1:1-2:13|0|1|0", + "spell": "2:7-2:10|0|1|2|-1", + "extent": "1:1-2:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -68,8 +68,8 @@ Foo b; "qual_name_offset": 10, "short_name": "b", "declarations": [], - "spell": "5:11-5:12|0|1|2", - "extent": "5:1-5:12|0|1|0", + "spell": "5:11-5:12|0|1|2|-1", + "extent": "5:1-5:12|0|1|0|-1", "type": 14134940367505932005, "uses": [], "kind": 13, @@ -80,8 +80,8 @@ Foo b; "qual_name_offset": 9, "short_name": "a", "declarations": [], - "spell": "4:10-4:11|0|1|2", - "extent": "4:1-4:11|0|1|0", + "spell": "4:10-4:11|0|1|2|-1", + "extent": "4:1-4:11|0|1|0|-1", "type": 5123806965838456033, "uses": [], "kind": 13, diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 844baece5..44489203a 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -43,8 +43,8 @@ UnexposedDecl var "short_name": "A", "kind": 10, "declarations": [], - "spell": "1:6-1:7|0|1|2", - "extent": "1:1-1:10|0|1|0", + "spell": "1:6-1:7|0|1|2|-1", + "extent": "1:1-1:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -52,7 +52,7 @@ UnexposedDecl var "funcs": [], "vars": [], "instances": [16721564935990383768], - "uses": ["7:1-7:2|0|1|4", "7:11-7:12|0|1|4"] + "uses": ["7:1-7:2|0|1|4|-1", "7:11-7:12|0|1|4|-1"] }, { "usr": 11919899838872947844, "detailed_name": "T", @@ -60,8 +60,8 @@ UnexposedDecl var "short_name": "T", "kind": 26, "declarations": [], - "spell": "4:19-4:20|0|1|2", - "extent": "4:10-4:20|0|1|0", + "spell": "4:19-4:20|0|1|2|-1", + "extent": "4:10-4:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -77,8 +77,8 @@ UnexposedDecl var "short_name": "B", "kind": 10, "declarations": [], - "spell": "2:6-2:7|0|1|2", - "extent": "2:1-2:10|0|1|0", + "spell": "2:6-2:7|0|1|2|-1", + "extent": "2:1-2:10|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -86,7 +86,7 @@ UnexposedDecl var "funcs": [], "vars": [], "instances": [12028309045033782423], - "uses": ["8:1-8:2|0|1|4", "8:11-8:12|0|1|4"] + "uses": ["8:1-8:2|0|1|4|-1", "8:11-8:12|0|1|4|-1"] }], "usr2var": [{ "usr": 8096973118640070624, @@ -95,10 +95,10 @@ UnexposedDecl var "short_name": "var", "hover": "T var = T()", "declarations": [], - "spell": "5:3-5:6|0|1|2", - "extent": "5:1-5:12|0|1|0", + "spell": "5:3-5:6|0|1|2|-1", + "extent": "5:1-5:12|0|1|0|-1", "type": 11919899838872947844, - "uses": ["7:7-7:10|0|1|12", "8:7-8:10|0|1|12"], + "uses": ["7:7-7:10|0|1|12|-1", "8:7-8:10|0|1|12|-1"], "kind": 13, "storage": 0 }, { @@ -108,8 +108,8 @@ UnexposedDecl var "short_name": "b", "hover": "B b = var", "declarations": [], - "spell": "8:3-8:4|0|1|2", - "extent": "8:1-8:13|0|1|0", + "spell": "8:3-8:4|0|1|2|-1", + "extent": "8:1-8:13|0|1|0|-1", "type": 13892793056005362145, "uses": [], "kind": 13, @@ -121,8 +121,8 @@ UnexposedDecl var "short_name": "a", "hover": "A a = var", "declarations": [], - "spell": "7:3-7:4|0|1|2", - "extent": "7:1-7:13|0|1|0", + "spell": "7:3-7:4|0|1|2|-1", + "extent": "7:1-7:13|0|1|0|-1", "type": 6697181287623958829, "uses": [], "kind": 13, diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 8a75ecf95..b3dbecc3b 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -31,8 +31,8 @@ union vector3 { "short_name": "", "kind": 23, "declarations": [], - "spell": "2:3-2:9|17937907487590875128|2|1026", - "extent": "2:3-2:28|17937907487590875128|2|0", + "spell": "2:3-2:9|17937907487590875128|2|1026|-1", + "extent": "2:3-2:28|17937907487590875128|2|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -57,8 +57,8 @@ union vector3 { "short_name": "vector3", "kind": 5, "declarations": [], - "spell": "1:7-1:14|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:7-1:14|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -86,8 +86,8 @@ union vector3 { "qual_name_offset": 6, "short_name": "v", "declarations": [], - "spell": "3:9-3:10|17937907487590875128|2|1026", - "extent": "3:3-3:13|17937907487590875128|2|0", + "spell": "3:9-3:10|17937907487590875128|2|1026|-1", + "extent": "3:3-3:13|17937907487590875128|2|0|-1", "type": 0, "uses": [], "kind": 8, @@ -98,8 +98,8 @@ union vector3 { "qual_name_offset": 6, "short_name": "x", "declarations": [], - "spell": "2:18-2:19|1428566502523368801|2|1026", - "extent": "2:12-2:19|1428566502523368801|2|0", + "spell": "2:18-2:19|1428566502523368801|2|1026|-1", + "extent": "2:12-2:19|1428566502523368801|2|0|-1", "type": 82, "uses": [], "kind": 8, @@ -110,8 +110,8 @@ union vector3 { "qual_name_offset": 6, "short_name": "y", "declarations": [], - "spell": "2:21-2:22|1428566502523368801|2|1026", - "extent": "2:12-2:22|1428566502523368801|2|0", + "spell": "2:21-2:22|1428566502523368801|2|1026|-1", + "extent": "2:12-2:22|1428566502523368801|2|0|-1", "type": 82, "uses": [], "kind": 8, @@ -122,8 +122,8 @@ union vector3 { "qual_name_offset": 6, "short_name": "z", "declarations": [], - "spell": "2:24-2:25|1428566502523368801|2|1026", - "extent": "2:12-2:25|1428566502523368801|2|0", + "spell": "2:24-2:25|1428566502523368801|2|1026|-1", + "extent": "2:12-2:25|1428566502523368801|2|0|-1", "type": 82, "uses": [], "kind": 8, diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index 38505c299..17d3fcbd0 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -13,7 +13,7 @@ static func g; "short_name": "g", "kind": 12, "storage": 0, - "declarations": ["2:13-2:14|0|1|1"], + "declarations": ["2:13-2:14|2:1-2:14|0|1|1|-1"], "bases": [], "derived": [], "vars": [], @@ -27,8 +27,8 @@ static func g; "short_name": "func", "kind": 252, "declarations": [], - "spell": "1:14-1:18|0|1|2", - "extent": "1:1-1:47|0|1|0", + "spell": "1:14-1:18|0|1|2|-1", + "extent": "1:1-1:47|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -36,7 +36,7 @@ static func g; "funcs": [], "vars": [], "instances": [], - "uses": ["2:8-2:12|0|1|4"] + "uses": ["2:8-2:12|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 83b94e90f..7861f8ff7 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -46,8 +46,8 @@ union Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -69,8 +69,8 @@ union Foo { "qual_name_offset": 5, "short_name": "b", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|1026", - "extent": "3:3-3:9|8501689086387244262|2|0", + "spell": "3:8-3:9|8501689086387244262|2|1026|-1", + "extent": "3:3-3:9|8501689086387244262|2|0|-1", "type": 37, "uses": [], "kind": 8, @@ -81,8 +81,8 @@ union Foo { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|1026", - "extent": "2:3-2:8|8501689086387244262|2|0", + "spell": "2:7-2:8|8501689086387244262|2|1026|-1", + "extent": "2:3-2:8|8501689086387244262|2|0|-1", "type": 53, "uses": [], "kind": 8, diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 253c4a345..248f5975d 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -24,8 +24,8 @@ void act(Foo*) { "kind": 12, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2", - "extent": "8:1-10:2|0|1|0", + "spell": "8:6-8:9|0|1|2|-1", + "extent": "8:1-10:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -69,8 +69,8 @@ void act(Foo*) { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -84,7 +84,7 @@ void act(Foo*) { "R": 0 }], "instances": [2933643612409209903], - "uses": ["6:1-6:4|0|1|4", "8:10-8:13|0|1|4"] + "uses": ["6:1-6:4|0|1|4|-1", "8:10-8:13|0|1|4|-1"] }], "usr2var": [{ "usr": 2933643612409209903, @@ -92,10 +92,10 @@ void act(Foo*) { "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "6:5-6:6|0|1|2", - "extent": "6:1-6:6|0|1|0", + "spell": "6:5-6:6|0|1|2|-1", + "extent": "6:1-6:6|0|1|0|-1", "type": 8501689086387244262, - "uses": ["9:3-9:4|13982179977217945200|3|4"], + "uses": ["9:3-9:4|13982179977217945200|3|4|-1"], "kind": 13, "storage": 0 }, { @@ -104,8 +104,8 @@ void act(Foo*) { "qual_name_offset": 5, "short_name": "b", "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|1026", - "extent": "3:3-3:13|8501689086387244262|2|0", + "spell": "3:8-3:9|8501689086387244262|2|1026|-1", + "extent": "3:3-3:13|8501689086387244262|2|0|-1", "type": 37, "uses": [], "kind": 8, @@ -116,10 +116,10 @@ void act(Foo*) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|1026", - "extent": "2:3-2:12|8501689086387244262|2|0", + "spell": "2:7-2:8|8501689086387244262|2|1026|-1", + "extent": "2:3-2:12|8501689086387244262|2|0|-1", "type": 53, - "uses": ["9:5-9:6|13982179977217945200|3|20"], + "uses": ["9:5-9:6|13982179977217945200|3|20|-1"], "kind": 8, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 69269d9e8..53c436697 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -21,12 +21,12 @@ Foo::Foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2", - "extent": "1:1-1:17|0|1|0", + "spell": "1:6-1:12|0|1|2|-1", + "extent": "1:1-1:17|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|3385168158331140247|3|16420"], + "uses": ["8:3-8:9|3385168158331140247|3|16420|-1"], "callees": [] }, { "usr": 3385168158331140247, @@ -35,9 +35,9 @@ Foo::Foo() { "short_name": "Foo", "kind": 9, "storage": 0, - "declarations": ["4:3-4:6|15041163540773201510|2|1025"], - "spell": "7:6-7:9|15041163540773201510|2|1026", - "extent": "7:1-9:2|15041163540773201510|2|0", + "declarations": ["4:3-4:6|4:3-4:8|15041163540773201510|2|1025|-1"], + "spell": "7:6-7:9|15041163540773201510|2|1026|-1", + "extent": "7:1-9:2|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -51,8 +51,8 @@ Foo::Foo() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "3:8-3:11|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:8-3:11|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -60,7 +60,7 @@ Foo::Foo() { "funcs": [3385168158331140247], "vars": [], "instances": [], - "uses": ["4:3-4:6|15041163540773201510|2|4", "7:1-7:4|0|1|4", "7:6-7:9|15041163540773201510|2|4"] + "uses": ["4:3-4:6|15041163540773201510|2|4|-1", "7:1-7:4|0|1|4|-1", "7:6-7:9|15041163540773201510|2|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 1312ef951..868db9e87 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -18,11 +18,11 @@ void caller() { "short_name": "called", "kind": 12, "storage": 0, - "declarations": ["3:6-3:12|0|1|1"], + "declarations": ["3:6-3:12|3:1-3:28|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["6:14-6:20|11404881820527069090|3|16420", "6:14-6:20|0|1|64|0"], + "uses": ["6:14-6:20|11404881820527069090|3|16420|-1", "6:14-6:20|0|1|64|0"], "callees": [] }, { "usr": 11404881820527069090, @@ -32,8 +32,8 @@ void caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:12|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:6-5:12|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -48,10 +48,10 @@ void caller() { "short_name": "MACRO_CALL", "hover": "#define MACRO_CALL(e) e", "declarations": [], - "spell": "1:9-1:19|0|1|2", - "extent": "1:9-1:24|0|1|0", + "spell": "1:9-1:19|0|1|2|-1", + "extent": "1:9-1:24|0|1|0|-1", "type": 0, - "uses": ["6:3-6:13|0|1|64"], + "uses": ["6:3-6:13|0|1|64|-1"], "kind": 255, "storage": 0 }] diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index becca51b9..0d223beca 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -23,11 +23,11 @@ void foo() { "short_name": "called", "kind": 12, "storage": 0, - "declarations": ["1:6-1:12|0|1|1"], + "declarations": ["1:6-1:12|1:1-1:14|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|10177235824697315808|3|16420"], + "uses": ["5:3-5:9|10177235824697315808|3|16420|-1"], "callees": [] }, { "usr": 2459767597003442547, @@ -50,8 +50,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2", - "extent": "8:1-10:2|0|1|0", + "spell": "8:6-8:9|0|1|2|-1", + "extent": "8:1-10:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -65,12 +65,12 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "4:6-4:12|0|1|2", - "extent": "4:1-6:2|0|1|0", + "spell": "4:6-4:12|0|1|2|-1", + "extent": "4:1-6:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["9:3-9:9|4259594751088586730|3|16420"], + "uses": ["9:3-9:9|4259594751088586730|3|16420|-1"], "callees": ["5:3-5:9|468307235068920063|3|16420"] }], "usr2type": [], diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index 522158bdf..63a13f2b9 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -21,12 +21,12 @@ Wrapper caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:5-5:11|0|1|2", - "extent": "5:1-5:27|0|1|0", + "spell": "5:5-5:11|0|1|2|-1", + "extent": "5:1-5:27|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|11404881820527069090|3|16420"], + "uses": ["8:10-8:16|11404881820527069090|3|16420|-1"], "callees": [] }, { "usr": 10544127002917214589, @@ -35,11 +35,11 @@ Wrapper caller() { "short_name": "Wrapper", "kind": 9, "storage": 0, - "declarations": ["2:3-2:10|13611487872560323389|2|1025"], + "declarations": ["2:3-2:10|2:3-2:17|13611487872560323389|2|1025|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["8:10-8:16|11404881820527069090|3|16676"], + "uses": ["8:10-8:16|11404881820527069090|3|16676|-1"], "callees": [] }, { "usr": 11404881820527069090, @@ -49,8 +49,8 @@ Wrapper caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "7:9-7:15|0|1|2", - "extent": "7:1-9:2|0|1|0", + "spell": "7:9-7:15|0|1|2|-1", + "extent": "7:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -64,8 +64,8 @@ Wrapper caller() { "short_name": "Wrapper", "kind": 23, "declarations": [], - "spell": "1:8-1:15|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:15|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -73,7 +73,7 @@ Wrapper caller() { "funcs": [10544127002917214589], "vars": [], "instances": [], - "uses": ["2:3-2:10|13611487872560323389|2|4", "7:1-7:8|0|1|4"] + "uses": ["2:3-2:10|13611487872560323389|2|4|-1", "7:1-7:8|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 294b6f5e2..9d4efdb62 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -20,12 +20,12 @@ void user() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2", - "extent": "3:1-3:15|0|1|0", + "spell": "3:6-3:10|0|1|2|-1", + "extent": "3:1-3:15|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|132", "7:12-7:16|9376923949268137283|3|132"], + "uses": ["6:18-6:22|9376923949268137283|3|132|-1", "7:12-7:16|9376923949268137283|3|132|-1"], "callees": [] }, { "usr": 9376923949268137283, @@ -35,8 +35,8 @@ void user() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2", - "extent": "5:1-8:2|0|1|0", + "spell": "5:6-5:10|0|1|2|-1", + "extent": "5:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [16088407831770615719], @@ -50,12 +50,12 @@ void user() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:13|0|1|2", - "extent": "1:1-1:28|0|1|0", + "spell": "1:6-1:13|0|1|2|-1", + "extent": "1:1-1:28|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["7:3-7:10|9376923949268137283|3|16420"], + "uses": ["7:3-7:10|9376923949268137283|3|16420|-1"], "callees": [] }], "usr2type": [], @@ -66,8 +66,8 @@ void user() { "short_name": "x", "hover": "void (*x)() = &used", "declarations": [], - "spell": "6:10-6:11|9376923949268137283|3|2", - "extent": "6:3-6:22|9376923949268137283|3|0", + "spell": "6:10-6:11|9376923949268137283|3|2|-1", + "extent": "6:3-6:22|9376923949268137283|3|0|-1", "type": 0, "uses": [], "kind": 13, diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 3dfdda35d..e8242960e 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -20,8 +20,8 @@ void user() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:6-5:10|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "bases": [], "derived": [], "vars": [4636142131003982569], @@ -34,11 +34,11 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1025"], + "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|132"], + "uses": ["6:18-6:22|9376923949268137283|3|132|-1"], "callees": [] }], "usr2type": [{ @@ -48,8 +48,8 @@ void user() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -57,7 +57,7 @@ void user() { "funcs": [18417145003926999463], "vars": [], "instances": [], - "uses": ["6:13-6:16|9376923949268137283|3|4"] + "uses": ["6:13-6:16|9376923949268137283|3|4|-1"] }], "usr2var": [{ "usr": 4636142131003982569, @@ -66,8 +66,8 @@ void user() { "short_name": "x", "hover": "void (Foo::*)() x = &Foo::Used", "declarations": [], - "spell": "6:8-6:9|9376923949268137283|3|2", - "extent": "6:3-6:22|9376923949268137283|3|0", + "spell": "6:8-6:9|9376923949268137283|3|2|-1", + "extent": "6:3-6:22|9376923949268137283|3|0|-1", "type": 0, "uses": [], "kind": 13, diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index b6d82740a..0ec91f0a7 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -16,12 +16,12 @@ void caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2", - "extent": "1:1-1:17|0|1|0", + "spell": "1:6-1:12|0|1|2|-1", + "extent": "1:1-1:17|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["3:3-3:9|11404881820527069090|3|16420"], + "uses": ["3:3-3:9|11404881820527069090|3|16420|-1"], "callees": [] }, { "usr": 11404881820527069090, @@ -31,8 +31,8 @@ void caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:12|0|1|2", - "extent": "2:1-4:2|0|1|0", + "spell": "2:6-2:12|0|1|2|-1", + "extent": "2:1-4:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index e16be451e..726f13fd2 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -20,8 +20,8 @@ void user() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2", - "extent": "5:1-8:2|0|1|0", + "spell": "5:6-5:10|0|1|2|-1", + "extent": "5:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [14045150712868309451], @@ -34,11 +34,11 @@ void user() { "short_name": "Used", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1025"], + "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:10|9376923949268137283|3|16420"], + "uses": ["7:6-7:10|9376923949268137283|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -48,8 +48,8 @@ void user() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -57,7 +57,7 @@ void user() { "funcs": [18417145003926999463], "vars": [], "instances": [14045150712868309451], - "uses": ["6:3-6:6|9376923949268137283|3|4"] + "uses": ["6:3-6:6|9376923949268137283|3|4|-1"] }], "usr2var": [{ "usr": 14045150712868309451, @@ -66,10 +66,10 @@ void user() { "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], - "spell": "6:8-6:9|9376923949268137283|3|2", - "extent": "6:3-6:19|9376923949268137283|3|0", + "spell": "6:8-6:9|9376923949268137283|3|2|-1", + "extent": "6:3-6:19|9376923949268137283|3|0|-1", "type": 15041163540773201510, - "uses": ["7:3-7:4|9376923949268137283|3|12"], + "uses": ["7:3-7:4|9376923949268137283|3|12|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 413923852..6872016b4 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -19,12 +19,12 @@ class Foo { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:12-1:18|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:12-1:18|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["6:11-6:17|15041163540773201510|2|36"], + "uses": ["6:11-6:17|15041163540773201510|2|36|-1"], "callees": [] }], "usr2type": [{ @@ -49,8 +49,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "5:7-5:10|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:7-5:10|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -70,8 +70,8 @@ class Foo { "short_name": "x", "hover": "int Foo::x = helper()", "declarations": [], - "spell": "6:7-6:8|15041163540773201510|2|1026", - "extent": "6:3-6:19|15041163540773201510|2|0", + "spell": "6:7-6:8|15041163540773201510|2|1026|-1", + "extent": "6:3-6:19|15041163540773201510|2|0|-1", "type": 53, "uses": [], "kind": 8, diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 775595fd8..1e7cef98e 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -15,11 +15,11 @@ void usage() { "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["1:6-1:9|0|1|1"], + "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["4:3-4:6|6767773193109753523|3|16420"], + "uses": ["4:3-4:6|6767773193109753523|3|16420|-1"], "callees": [] }, { "usr": 6767773193109753523, @@ -29,8 +29,8 @@ void usage() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:11|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:11|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index d27dadecb..9fdfb1edd 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -19,8 +19,8 @@ void usage() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:11|0|1|2", - "extent": "5:1-8:2|0|1|0", + "spell": "5:6-5:11|0|1|2|-1", + "extent": "5:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [16229832321010999607], @@ -33,11 +33,11 @@ void usage() { "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["2:8-2:11|15041163540773201510|2|1025"], + "declarations": ["2:8-2:11|2:3-2:13|15041163540773201510|2|1025|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["7:6-7:9|6767773193109753523|3|16420"], + "uses": ["7:6-7:9|6767773193109753523|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -47,8 +47,8 @@ void usage() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -56,7 +56,7 @@ void usage() { "funcs": [17922201480358737771], "vars": [], "instances": [16229832321010999607], - "uses": ["6:3-6:6|6767773193109753523|3|4"] + "uses": ["6:3-6:6|6767773193109753523|3|4|-1"] }], "usr2var": [{ "usr": 16229832321010999607, @@ -65,10 +65,10 @@ void usage() { "short_name": "f", "hover": "Foo *f = nullptr", "declarations": [], - "spell": "6:8-6:9|6767773193109753523|3|2", - "extent": "6:3-6:19|6767773193109753523|3|0", + "spell": "6:8-6:9|6767773193109753523|3|2|-1", + "extent": "6:3-6:19|6767773193109753523|3|0|-1", "type": 15041163540773201510, - "uses": ["7:3-7:4|6767773193109753523|3|12"], + "uses": ["7:3-7:4|6767773193109753523|3|12|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 422d59523..72e6e6701 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -19,8 +19,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2", - "extent": "4:1-7:2|0|1|0", + "spell": "4:6-4:9|0|1|2|-1", + "extent": "4:1-7:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -33,11 +33,11 @@ void foo() { "short_name": "accept", "kind": 12, "storage": 0, - "declarations": ["2:6-2:12|0|1|1"], + "declarations": ["2:6-2:12|2:1-2:15|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|4259594751088586730|3|16420", "6:3-6:9|4259594751088586730|3|16420"], + "uses": ["5:3-5:9|4259594751088586730|3|16420|-1", "6:3-6:9|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 74d2c0257..5c4dc8241 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -23,8 +23,8 @@ unique_ptr* return_type() { "kind": 12, "storage": 0, "declarations": [], - "spell": "9:16-9:27|0|1|2", - "extent": "9:1-12:2|0|1|0", + "spell": "9:16-9:27|0|1|2|-1", + "extent": "9:1-12:2|0|1|0|-1", "bases": [], "derived": [], "vars": [3364438781074774169], @@ -38,8 +38,8 @@ unique_ptr* return_type() { "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "2:1-2:20|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "2:1-2:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ unique_ptr* return_type() { "funcs": [], "vars": [], "instances": [], - "uses": ["6:8-6:18|0|1|4", "7:8-7:18|0|1|4", "9:1-9:11|0|1|4", "10:3-10:13|16359708726068806331|3|4"] + "uses": ["6:8-6:18|0|1|4|-1", "7:8-7:18|0|1|4|-1", "9:1-9:11|0|1|4|-1", "10:3-10:13|16359708726068806331|3|4|-1"] }, { "usr": 4186953406371619898, "detailed_name": "unique_ptr", @@ -55,8 +55,8 @@ unique_ptr* return_type() { "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "1:1-2:20|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "1:1-2:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -72,8 +72,8 @@ unique_ptr* return_type() { "short_name": "S", "kind": 23, "declarations": [], - "spell": "4:8-4:9|0|1|2", - "extent": "4:1-4:12|0|1|0", + "spell": "4:8-4:9|0|1|2|-1", + "extent": "4:1-4:12|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -81,7 +81,7 @@ unique_ptr* return_type() { "funcs": [], "vars": [], "instances": [], - "uses": ["7:19-7:20|0|1|4", "9:12-9:13|0|1|4", "10:14-10:15|16359708726068806331|3|4"] + "uses": ["7:19-7:20|0|1|4|-1", "9:12-9:13|0|1|4|-1", "10:14-10:15|16359708726068806331|3|4|-1"] }, { "usr": 16848604152578034754, "detailed_name": "unique_ptr", @@ -89,8 +89,8 @@ unique_ptr* return_type() { "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "1:1-2:20|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "1:1-2:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -106,8 +106,8 @@ unique_ptr* return_type() { "qual_name_offset": 15, "short_name": "local", "declarations": [], - "spell": "10:18-10:23|16359708726068806331|3|2", - "extent": "10:3-10:23|16359708726068806331|3|0", + "spell": "10:18-10:23|16359708726068806331|3|2|-1", + "extent": "10:3-10:23|16359708726068806331|3|0|-1", "type": 4186953406371619898, "uses": [], "kind": 13, @@ -118,8 +118,8 @@ unique_ptr* return_type() { "qual_name_offset": 24, "short_name": "f0", "declarations": [], - "spell": "6:25-6:27|0|1|2", - "extent": "6:1-6:27|0|1|0", + "spell": "6:25-6:27|0|1|2|-1", + "extent": "6:1-6:27|0|1|0|-1", "type": 16848604152578034754, "uses": [], "kind": 13, @@ -130,8 +130,8 @@ unique_ptr* return_type() { "qual_name_offset": 21, "short_name": "f1", "declarations": [], - "spell": "7:22-7:24|0|1|2", - "extent": "7:1-7:24|0|1|0", + "spell": "7:22-7:24|0|1|2|-1", + "extent": "7:1-7:24|0|1|0|-1", "type": 4186953406371619898, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 7b5ebc54c..0b4e20e06 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -91,8 +91,8 @@ unique_ptr* Foo::foo() { return nullptr; } "kind": 12, "storage": 0, "declarations": [], - "spell": "33:37-33:51|0|1|2", - "extent": "33:1-33:92|0|1|0", + "spell": "33:37-33:51|0|1|2|-1", + "extent": "33:1-33:92|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -106,8 +106,8 @@ unique_ptr* Foo::foo() { return nullptr; } "kind": 12, "storage": 0, "declarations": [], - "spell": "40:6-40:20|0|1|2", - "extent": "40:1-40:28|0|1|0", + "spell": "40:6-40:20|0|1|2|-1", + "extent": "40:1-40:28|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -120,9 +120,9 @@ unique_ptr* Foo::foo() { return nullptr; } "short_name": "foo", "kind": 6, "storage": 0, - "declarations": ["65:23-65:26|15041163540773201510|2|1025"], - "spell": "79:26-79:29|15041163540773201510|2|1026", - "extent": "79:1-79:51|15041163540773201510|2|0", + "declarations": ["65:23-65:26|65:3-65:28|15041163540773201510|2|1025|-1"], + "spell": "79:26-79:29|15041163540773201510|2|1026|-1", + "extent": "79:1-79:51|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -136,8 +136,8 @@ unique_ptr* Foo::foo() { return nullptr; } "kind": 12, "storage": 0, "declarations": [], - "spell": "53:6-53:11|0|1|2", - "extent": "53:1-55:2|0|1|0", + "spell": "53:6-53:11|0|1|2|-1", + "extent": "53:1-55:2|0|1|0|-1", "bases": [], "derived": [], "vars": [500112618220246], @@ -150,7 +150,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 7, "short_name": "S1", "kind": 23, - "declarations": ["4:8-4:10|0|1|1"], + "declarations": ["4:8-4:10|4:1-4:10|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -158,7 +158,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:30-15:32|0|1|4", "33:23-33:25|0|1|4", "33:63-33:65|0|1|4", "54:25-54:27|18320186404467436976|3|4", "65:14-65:16|15041163540773201510|2|4", "79:12-79:14|0|1|4"] + "uses": ["15:30-15:32|0|1|4|-1", "33:23-33:25|0|1|4|-1", "33:63-33:65|0|1|4|-1", "54:25-54:27|18320186404467436976|3|4|-1", "65:14-65:16|15041163540773201510|2|4|-1", "79:12-79:14|0|1|4|-1"] }, { "usr": 7147635971744144194, "detailed_name": "template<> class unique_ptr", @@ -173,14 +173,14 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:19-15:29|0|1|4", "33:12-33:22|0|1|4", "33:52-33:62|0|1|4", "54:14-54:24|18320186404467436976|3|4", "65:3-65:13|15041163540773201510|2|4", "79:1-79:11|0|1|4"] + "uses": ["15:19-15:29|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", "qual_name_offset": 7, "short_name": "S2", "kind": 23, - "declarations": ["5:8-5:10|0|1|1"], + "declarations": ["5:8-5:10|5:1-5:10|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -188,14 +188,14 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["15:34-15:36|0|1|4", "15:39-15:41|0|1|4", "33:27-33:29|0|1|4", "33:32-33:34|0|1|4", "33:67-33:69|0|1|4", "54:29-54:31|18320186404467436976|3|4", "54:34-54:36|18320186404467436976|3|4", "65:18-65:20|15041163540773201510|2|4", "79:16-79:18|0|1|4"] + "uses": ["15:34-15:36|0|1|4|-1", "15:39-15:41|0|1|4|-1", "33:27-33:29|0|1|4|-1", "33:32-33:34|0|1|4|-1", "33:67-33:69|0|1|4|-1", "54:29-54:31|18320186404467436976|3|4|-1", "54:34-54:36|18320186404467436976|3|4|-1", "65:18-65:20|15041163540773201510|2|4|-1", "79:16-79:18|0|1|4|-1"] }, { "usr": 14209198335088845323, "detailed_name": "class unique_ptr", "qual_name_offset": 6, "short_name": "unique_ptr", "kind": 5, - "declarations": ["2:7-2:17|0|1|1"], + "declarations": ["2:7-2:17|2:1-2:17|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -211,8 +211,8 @@ unique_ptr* Foo::foo() { return nullptr; } "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "64:7-64:10|0|1|2", - "extent": "64:1-66:2|0|1|0", + "spell": "64:7-64:10|0|1|2|-1", + "extent": "64:1-66:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -220,7 +220,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [17922201480358737771], "vars": [], "instances": [], - "uses": ["79:21-79:24|0|1|4"] + "uses": ["79:21-79:24|0|1|4|-1"] }, { "usr": 18153735331422331128, "detailed_name": "unique_ptr", @@ -228,8 +228,8 @@ unique_ptr* Foo::foo() { return nullptr; } "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "1:1-2:17|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "1:1-2:17|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -237,7 +237,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [2933643612409209903, 500112618220246], - "uses": ["15:8-15:18|0|1|4", "33:1-33:11|0|1|4", "54:3-54:13|18320186404467436976|3|4"] + "uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"] }], "usr2var": [{ "usr": 500112618220246, @@ -245,8 +245,8 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 36, "short_name": "local", "declarations": [], - "spell": "54:39-54:44|18320186404467436976|3|2", - "extent": "54:3-54:44|18320186404467436976|3|0", + "spell": "54:39-54:44|18320186404467436976|3|2|-1", + "extent": "54:3-54:44|18320186404467436976|3|0|-1", "type": 18153735331422331128, "uses": [], "kind": 13, @@ -256,7 +256,7 @@ unique_ptr* Foo::foo() { return nullptr; } "detailed_name": "extern unique_ptr, S2> f", "qual_name_offset": 42, "short_name": "f", - "declarations": ["15:43-15:44|0|1|1"], + "declarations": ["15:43-15:44|15:1-15:44|0|1|1|-1"], "type": 18153735331422331128, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 1b904ef73..1893c26e4 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -18,8 +18,8 @@ static unique_ptr foo; "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "2:1-2:20|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "2:1-2:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -27,7 +27,7 @@ static unique_ptr foo; "funcs": [], "vars": [], "instances": [], - "uses": ["6:8-6:18|0|1|4"] + "uses": ["6:8-6:18|0|1|4|-1"] }, { "usr": 4186953406371619898, "detailed_name": "unique_ptr", @@ -35,8 +35,8 @@ static unique_ptr foo; "short_name": "unique_ptr", "kind": 26, "declarations": [], - "spell": "2:7-2:17|0|1|2", - "extent": "1:1-2:20|0|1|0", + "spell": "2:7-2:17|0|1|2|-1", + "extent": "1:1-2:20|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -51,7 +51,7 @@ static unique_ptr foo; "qual_name_offset": 7, "short_name": "S", "kind": 23, - "declarations": ["4:8-4:9|0|1|1"], + "declarations": ["4:8-4:9|4:1-4:9|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -59,7 +59,7 @@ static unique_ptr foo; "funcs": [], "vars": [], "instances": [], - "uses": ["6:19-6:20|0|1|4"] + "uses": ["6:19-6:20|0|1|4|-1"] }], "usr2var": [{ "usr": 3398408600781120939, @@ -67,8 +67,8 @@ static unique_ptr foo; "qual_name_offset": 21, "short_name": "foo", "declarations": [], - "spell": "6:22-6:25|0|1|2", - "extent": "6:1-6:25|0|1|0", + "spell": "6:22-6:25|0|1|2|-1", + "extent": "6:1-6:25|0|1|0|-1", "type": 4186953406371619898, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index 2fd672160..4d09cd857 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -14,8 +14,8 @@ extern T t; "short_name": "T", "kind": 23, "declarations": [], - "spell": "1:8-1:9|0|1|2", - "extent": "1:1-1:12|0|1|0", + "spell": "1:8-1:9|0|1|2|-1", + "extent": "1:1-1:12|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -23,14 +23,14 @@ extern T t; "funcs": [], "vars": [], "instances": [1346710425945444872], - "uses": ["3:8-3:9|0|1|4"] + "uses": ["3:8-3:9|0|1|4|-1"] }], "usr2var": [{ "usr": 1346710425945444872, "detailed_name": "extern T t", "qual_name_offset": 9, "short_name": "t", - "declarations": ["3:10-3:11|0|1|1"], + "declarations": ["3:10-3:11|3:1-3:11|0|1|1|-1"], "type": 5673439900521455039, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 114d6a860..09cae9e57 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -19,8 +19,8 @@ struct Foo { "short_name": "ImplementedType", "kind": 23, "declarations": [], - "spell": "2:8-2:23|0|1|2", - "extent": "2:1-2:26|0|1|0", + "spell": "2:8-2:23|0|1|2|-1", + "extent": "2:1-2:26|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -28,14 +28,14 @@ struct Foo { "funcs": [], "vars": [], "instances": [14727441168849658842], - "uses": ["6:3-6:18|15041163540773201510|2|4"] + "uses": ["6:3-6:18|15041163540773201510|2|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, - "declarations": ["1:8-1:19|0|1|1"], + "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ struct Foo { "funcs": [], "vars": [], "instances": [14314859014962085433], - "uses": ["5:3-5:14|15041163540773201510|2|4"] + "uses": ["5:3-5:14|15041163540773201510|2|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", @@ -51,8 +51,8 @@ struct Foo { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "4:8-4:11|0|1|2", - "extent": "4:1-7:2|0|1|0", + "spell": "4:8-4:11|0|1|2|-1", + "extent": "4:1-7:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -74,8 +74,8 @@ struct Foo { "qual_name_offset": 13, "short_name": "a", "declarations": [], - "spell": "5:16-5:17|15041163540773201510|2|1026", - "extent": "5:3-5:17|15041163540773201510|2|0", + "spell": "5:16-5:17|15041163540773201510|2|1026|-1", + "extent": "5:3-5:17|15041163540773201510|2|0|-1", "type": 13749354388332789217, "uses": [], "kind": 8, @@ -86,8 +86,8 @@ struct Foo { "qual_name_offset": 16, "short_name": "b", "declarations": [], - "spell": "6:19-6:20|15041163540773201510|2|1026", - "extent": "6:3-6:20|15041163540773201510|2|0", + "spell": "6:19-6:20|15041163540773201510|2|1026|-1", + "extent": "6:3-6:20|15041163540773201510|2|0|-1", "type": 8508299082070213750, "uses": [], "kind": 8, diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 0b037bc5b..39fd917dd 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -19,8 +19,8 @@ void Foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2", - "extent": "4:1-7:2|0|1|0", + "spell": "4:6-4:9|0|1|2|-1", + "extent": "4:1-7:2|0|1|0|-1", "bases": [], "derived": [], "vars": [16374832544037266261, 2580122838476012357], @@ -34,8 +34,8 @@ void Foo() { "short_name": "ImplementedType", "kind": 23, "declarations": [], - "spell": "2:8-2:23|0|1|2", - "extent": "2:1-2:26|0|1|0", + "spell": "2:8-2:23|0|1|2|-1", + "extent": "2:1-2:26|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -43,14 +43,14 @@ void Foo() { "funcs": [], "vars": [], "instances": [2580122838476012357], - "uses": ["6:3-6:18|4654328188330986029|3|4"] + "uses": ["6:3-6:18|4654328188330986029|3|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, - "declarations": ["1:8-1:19|0|1|1"], + "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -58,7 +58,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [16374832544037266261], - "uses": ["5:3-5:14|4654328188330986029|3|4"] + "uses": ["5:3-5:14|4654328188330986029|3|4|-1"] }], "usr2var": [{ "usr": 2580122838476012357, @@ -66,8 +66,8 @@ void Foo() { "qual_name_offset": 16, "short_name": "b", "declarations": [], - "spell": "6:19-6:20|4654328188330986029|3|2", - "extent": "6:3-6:20|4654328188330986029|3|0", + "spell": "6:19-6:20|4654328188330986029|3|2|-1", + "extent": "6:3-6:20|4654328188330986029|3|0|-1", "type": 8508299082070213750, "uses": [], "kind": 13, @@ -78,8 +78,8 @@ void Foo() { "qual_name_offset": 13, "short_name": "a", "declarations": [], - "spell": "5:16-5:17|4654328188330986029|3|2", - "extent": "5:3-5:17|4654328188330986029|3|0", + "spell": "5:16-5:17|4654328188330986029|3|2|-1", + "extent": "5:3-5:17|4654328188330986029|3|0|-1", "type": 13749354388332789217, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 4495b5ede..1570ef020 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -16,8 +16,8 @@ void foo(ForwardType* f, ImplementedType a) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2", - "extent": "4:1-4:47|0|1|0", + "spell": "4:6-4:9|0|1|2|-1", + "extent": "4:1-4:47|0|1|0|-1", "bases": [], "derived": [], "vars": [13058491096576226774, 11055777568039014776], @@ -31,8 +31,8 @@ void foo(ForwardType* f, ImplementedType a) {} "short_name": "ImplementedType", "kind": 23, "declarations": [], - "spell": "2:8-2:23|0|1|2", - "extent": "2:1-2:26|0|1|0", + "spell": "2:8-2:23|0|1|2|-1", + "extent": "2:1-2:26|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -40,14 +40,14 @@ void foo(ForwardType* f, ImplementedType a) {} "funcs": [], "vars": [], "instances": [11055777568039014776], - "uses": ["4:26-4:41|0|1|4"] + "uses": ["4:26-4:41|0|1|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, - "declarations": ["1:8-1:19|0|1|1"], + "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -55,7 +55,7 @@ void foo(ForwardType* f, ImplementedType a) {} "funcs": [], "vars": [], "instances": [13058491096576226774], - "uses": ["4:10-4:21|0|1|4"] + "uses": ["4:10-4:21|0|1|4|-1"] }], "usr2var": [{ "usr": 11055777568039014776, @@ -63,8 +63,8 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 16, "short_name": "a", "declarations": [], - "spell": "4:42-4:43|1699390678058422036|3|1026", - "extent": "4:26-4:43|1699390678058422036|3|0", + "spell": "4:42-4:43|1699390678058422036|3|1026|-1", + "extent": "4:26-4:43|1699390678058422036|3|0|-1", "type": 8508299082070213750, "uses": [], "kind": 253, @@ -75,8 +75,8 @@ void foo(ForwardType* f, ImplementedType a) {} "qual_name_offset": 13, "short_name": "f", "declarations": [], - "spell": "4:23-4:24|1699390678058422036|3|1026", - "extent": "4:10-4:24|1699390678058422036|3|0", + "spell": "4:23-4:24|1699390678058422036|3|1026|-1", + "extent": "4:10-4:24|1699390678058422036|3|0|-1", "type": 13749354388332789217, "uses": [], "kind": 253, diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index cee275579..3f205c9da 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -20,9 +20,9 @@ void foo(Foo* f, Foo*) {} "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["3:6-3:9|0|1|1"], - "spell": "4:6-4:9|0|1|2", - "extent": "4:1-4:26|0|1|0", + "declarations": ["3:6-3:9|3:1-3:23|0|1|1|-1"], + "spell": "4:6-4:9|0|1|2|-1", + "extent": "4:1-4:26|0|1|0|-1", "bases": [], "derived": [], "vars": [13823260660189154978], @@ -35,7 +35,7 @@ void foo(Foo* f, Foo*) {} "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["1:8-1:11|0|1|1"], + "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ void foo(Foo* f, Foo*) {} "funcs": [], "vars": [], "instances": [13823260660189154978], - "uses": ["3:10-3:13|0|1|4", "3:18-3:21|0|1|4", "4:10-4:13|0|1|4", "4:18-4:21|0|1|4"] + "uses": ["3:10-3:13|0|1|4|-1", "3:18-3:21|0|1|4|-1", "4:10-4:13|0|1|4|-1", "4:18-4:21|0|1|4|-1"] }], "usr2var": [{ "usr": 13823260660189154978, @@ -51,8 +51,8 @@ void foo(Foo* f, Foo*) {} "qual_name_offset": 5, "short_name": "f", "declarations": [], - "spell": "4:15-4:16|8908726657907936744|3|1026", - "extent": "4:10-4:16|8908726657907936744|3|0", + "spell": "4:15-4:16|8908726657907936744|3|1026|-1", + "extent": "4:10-4:16|8908726657907936744|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 253, diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index f0cda5364..f50fab00c 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -13,8 +13,8 @@ void foo(ForwardType*) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:9|0|1|2", - "extent": "2:1-2:26|0|1|0", + "spell": "2:6-2:9|0|1|2|-1", + "extent": "2:1-2:26|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -27,7 +27,7 @@ void foo(ForwardType*) {} "qual_name_offset": 7, "short_name": "ForwardType", "kind": 23, - "declarations": ["1:8-1:19|0|1|1"], + "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -35,7 +35,7 @@ void foo(ForwardType*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["2:10-2:21|0|1|4"] + "uses": ["2:10-2:21|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 41dfc3250..ec1f4d9c4 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -19,8 +19,8 @@ void foo(Type& a0, const Type& a1) { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-8:2|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], @@ -34,8 +34,8 @@ void foo(Type& a0, const Type& a1) { "short_name": "Type", "kind": 23, "declarations": [], - "spell": "1:8-1:12|0|1|2", - "extent": "1:1-1:15|0|1|0", + "spell": "1:8-1:12|0|1|2|-1", + "extent": "1:1-1:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ void foo(Type& a0, const Type& a1) { "funcs": [], "vars": [], "instances": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], - "uses": ["3:10-3:14|0|1|4", "3:26-3:30|0|1|4", "4:3-4:7|16858540520096802573|3|4", "5:3-5:7|16858540520096802573|3|4", "6:9-6:13|16858540520096802573|3|4", "7:9-7:13|16858540520096802573|3|4"] + "uses": ["3:10-3:14|0|1|4|-1", "3:26-3:30|0|1|4|-1", "4:3-4:7|16858540520096802573|3|4|-1", "5:3-5:7|16858540520096802573|3|4|-1", "6:9-6:13|16858540520096802573|3|4|-1", "7:9-7:13|16858540520096802573|3|4|-1"] }], "usr2var": [{ "usr": 5004072032239834773, @@ -51,8 +51,8 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 12, "short_name": "a4", "declarations": [], - "spell": "6:15-6:17|16858540520096802573|3|2", - "extent": "6:3-6:17|16858540520096802573|3|0", + "spell": "6:15-6:17|16858540520096802573|3|2|-1", + "extent": "6:3-6:17|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, @@ -63,8 +63,8 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 6, "short_name": "a3", "declarations": [], - "spell": "5:9-5:11|16858540520096802573|3|2", - "extent": "5:3-5:11|16858540520096802573|3|0", + "spell": "5:9-5:11|16858540520096802573|3|2|-1", + "extent": "5:3-5:11|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, @@ -75,8 +75,8 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 6, "short_name": "a0", "declarations": [], - "spell": "3:16-3:18|16858540520096802573|3|1026", - "extent": "3:10-3:18|16858540520096802573|3|0", + "spell": "3:16-3:18|16858540520096802573|3|1026|-1", + "extent": "3:10-3:18|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 253, @@ -88,8 +88,8 @@ void foo(Type& a0, const Type& a1) { "short_name": "a5", "hover": "const Type *const a5 = nullptr", "declarations": [], - "spell": "7:21-7:23|16858540520096802573|3|2", - "extent": "7:3-7:33|16858540520096802573|3|0", + "spell": "7:21-7:23|16858540520096802573|3|2|-1", + "extent": "7:3-7:33|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, @@ -100,8 +100,8 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 5, "short_name": "a2", "declarations": [], - "spell": "4:8-4:10|16858540520096802573|3|2", - "extent": "4:3-4:10|16858540520096802573|3|0", + "spell": "4:8-4:10|16858540520096802573|3|2|-1", + "extent": "4:3-4:10|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, @@ -112,8 +112,8 @@ void foo(Type& a0, const Type& a1) { "qual_name_offset": 12, "short_name": "a1", "declarations": [], - "spell": "3:32-3:34|16858540520096802573|3|1026", - "extent": "3:20-3:34|16858540520096802573|3|0", + "spell": "3:32-3:34|16858540520096802573|3|1026|-1", + "extent": "3:20-3:34|16858540520096802573|3|0|-1", "type": 13487927231218873822, "uses": [], "kind": 253, diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index 102c156af..ccff19e21 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -13,8 +13,8 @@ static Type t; "short_name": "Type", "kind": 23, "declarations": [], - "spell": "1:8-1:12|0|1|2", - "extent": "1:1-1:15|0|1|0", + "spell": "1:8-1:12|0|1|2|-1", + "extent": "1:1-1:15|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -22,7 +22,7 @@ static Type t; "funcs": [], "vars": [], "instances": [6601831367240627080], - "uses": ["2:8-2:12|0|1|4"] + "uses": ["2:8-2:12|0|1|4|-1"] }], "usr2var": [{ "usr": 6601831367240627080, @@ -30,8 +30,8 @@ static Type t; "qual_name_offset": 12, "short_name": "t", "declarations": [], - "spell": "2:13-2:14|0|1|2", - "extent": "2:1-2:14|0|1|0", + "spell": "2:13-2:14|0|1|2|-1", + "extent": "2:1-2:14|0|1|0|-1", "type": 13487927231218873822, "uses": [], "kind": 13, diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 04e848602..7a07f9738 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -29,9 +29,9 @@ static Type* bar() { return nullptr; } "short_name": "Empty", "kind": 6, "storage": 0, - "declarations": ["9:8-9:13|15041163540773201510|2|1025"], - "spell": "13:11-13:16|15041163540773201510|2|1026", - "extent": "13:1-13:21|15041163540773201510|2|0", + "declarations": ["9:8-9:13|9:3-9:15|15041163540773201510|2|1025|-1"], + "spell": "13:11-13:16|15041163540773201510|2|1026|-1", + "extent": "13:1-13:21|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -44,9 +44,9 @@ static Type* bar() { return nullptr; } "short_name": "foo", "kind": 12, "storage": 0, - "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], - "spell": "5:7-5:10|0|1|2", - "extent": "5:1-5:32|0|1|0", + "declarations": ["3:7-3:10|3:1-3:12|0|1|1|-1", "4:7-4:10|4:1-4:12|0|1|1|-1"], + "spell": "5:7-5:10|0|1|2|-1", + "extent": "5:1-5:32|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -59,7 +59,7 @@ static Type* bar() { return nullptr; } "short_name": "external", "kind": 12, "storage": 0, - "declarations": ["15:20-15:28|0|1|1"], + "declarations": ["15:20-15:28|15:1-15:30|0|1|1|-1"], "bases": [], "derived": [], "vars": [], @@ -72,9 +72,9 @@ static Type* bar() { return nullptr; } "short_name": "Get", "kind": 6, "storage": 0, - "declarations": ["8:9-8:12|15041163540773201510|2|1025"], - "spell": "12:12-12:15|15041163540773201510|2|1026", - "extent": "12:1-12:40|15041163540773201510|2|0", + "declarations": ["8:9-8:12|8:3-8:17|15041163540773201510|2|1025|-1"], + "spell": "12:12-12:15|15041163540773201510|2|1026|-1", + "extent": "12:1-12:40|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [], @@ -87,9 +87,9 @@ static Type* bar() { return nullptr; } "short_name": "bar", "kind": 12, "storage": 0, - "declarations": ["17:14-17:17|0|1|1"], - "spell": "18:14-18:17|0|1|2", - "extent": "18:1-18:39|0|1|0", + "declarations": ["17:14-17:17|17:1-17:19|0|1|1|-1"], + "spell": "18:14-18:17|0|1|2|-1", + "extent": "18:1-18:39|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -102,7 +102,7 @@ static Type* bar() { return nullptr; } "qual_name_offset": 7, "short_name": "Type", "kind": 23, - "declarations": ["1:8-1:12|0|1|1"], + "declarations": ["1:8-1:12|1:1-1:12|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -110,7 +110,7 @@ static Type* bar() { return nullptr; } "funcs": [], "vars": [], "instances": [], - "uses": ["3:1-3:5|0|1|4", "4:1-4:5|0|1|4", "5:1-5:5|0|1|4", "8:3-8:7|15041163540773201510|2|4", "12:1-12:5|0|1|4", "15:14-15:18|0|1|4", "17:8-17:12|0|1|4", "18:8-18:12|0|1|4"] + "uses": ["3:1-3:5|0|1|4|-1", "4:1-4:5|0|1|4|-1", "5:1-5:5|0|1|4|-1", "8:3-8:7|15041163540773201510|2|4|-1", "12:1-12:5|0|1|4|-1", "15:14-15:18|0|1|4|-1", "17:8-17:12|0|1|4|-1", "18:8-18:12|0|1|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", @@ -118,8 +118,8 @@ static Type* bar() { return nullptr; } "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "7:7-7:10|0|1|2", - "extent": "7:1-10:2|0|1|0", + "spell": "7:7-7:10|0|1|2|-1", + "extent": "7:1-10:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -127,7 +127,7 @@ static Type* bar() { return nullptr; } "funcs": [13402221340333431092, 4240751906910175539], "vars": [], "instances": [], - "uses": ["12:7-12:10|0|1|4", "13:6-13:9|0|1|4"] + "uses": ["12:7-12:10|0|1|4|-1", "13:6-13:9|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index ded74f43e..65ca72f32 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -22,8 +22,8 @@ void accept3(Foo3*) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "8:6-8:13|0|1|2", - "extent": "8:1-8:23|0|1|0", + "spell": "8:6-8:13|0|1|2|-1", + "extent": "8:1-8:23|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -37,8 +37,8 @@ void accept3(Foo3*) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "7:6-7:12|0|1|2", - "extent": "7:1-7:21|0|1|0", + "spell": "7:6-7:12|0|1|2|-1", + "extent": "7:1-7:21|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -52,8 +52,8 @@ void accept3(Foo3*) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "9:6-9:13|0|1|2", - "extent": "9:1-9:23|0|1|0", + "spell": "9:6-9:13|0|1|2|-1", + "extent": "9:1-9:23|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -67,8 +67,8 @@ void accept3(Foo3*) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "10:6-10:13|0|1|2", - "extent": "10:1-10:23|0|1|0", + "spell": "10:6-10:13|0|1|2|-1", + "extent": "10:1-10:23|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -82,8 +82,8 @@ void accept3(Foo3*) {} "short_name": "Foo1", "kind": 252, "declarations": [], - "spell": "2:7-2:11|0|1|2", - "extent": "2:1-2:18|0|1|0", + "spell": "2:7-2:11|0|1|2|-1", + "extent": "2:1-2:18|0|1|0|-1", "alias_of": 15041163540773201510, "bases": [], "derived": [], @@ -91,7 +91,7 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["4:14-4:18|0|1|4", "8:14-8:18|0|1|4"] + "uses": ["4:14-4:18|0|1|4|-1", "8:14-8:18|0|1|4|-1"] }, { "usr": 2638219001294786365, "detailed_name": "using Foo4 = int", @@ -99,8 +99,8 @@ void accept3(Foo3*) {} "short_name": "Foo4", "kind": 252, "declarations": [], - "spell": "5:7-5:11|0|1|2", - "extent": "5:1-5:17|0|1|0", + "spell": "5:7-5:11|0|1|2|-1", + "extent": "5:1-5:17|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -115,7 +115,7 @@ void accept3(Foo3*) {} "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["1:8-1:11|0|1|1"], + "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -123,7 +123,7 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["2:14-2:17|0|1|4", "3:9-3:12|0|1|4", "7:13-7:16|0|1|4"] + "uses": ["2:14-2:17|0|1|4|-1", "3:9-3:12|0|1|4|-1", "7:13-7:16|0|1|4|-1"] }, { "usr": 15466821155413653804, "detailed_name": "typedef Foo Foo2", @@ -131,8 +131,8 @@ void accept3(Foo3*) {} "short_name": "Foo2", "kind": 252, "declarations": [], - "spell": "3:13-3:17|0|1|2", - "extent": "3:1-3:17|0|1|0", + "spell": "3:13-3:17|0|1|2|-1", + "extent": "3:1-3:17|0|1|0|-1", "alias_of": 15041163540773201510, "bases": [], "derived": [], @@ -140,7 +140,7 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["9:14-9:18|0|1|4"] + "uses": ["9:14-9:18|0|1|4|-1"] }, { "usr": 17897026942631673064, "detailed_name": "using Foo3 = Foo1", @@ -148,8 +148,8 @@ void accept3(Foo3*) {} "short_name": "Foo3", "kind": 252, "declarations": [], - "spell": "4:7-4:11|0|1|2", - "extent": "4:1-4:18|0|1|0", + "spell": "4:7-4:11|0|1|2|-1", + "extent": "4:1-4:18|0|1|0|-1", "alias_of": 1544499294580512394, "bases": [], "derived": [], @@ -157,7 +157,7 @@ void accept3(Foo3*) {} "funcs": [], "vars": [], "instances": [], - "uses": ["10:14-10:18|0|1|4"] + "uses": ["10:14-10:18|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index c93284777..e70435575 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -17,8 +17,8 @@ typedef Foo Foo2; "short_name": "Foo1", "kind": 252, "declarations": [], - "spell": "4:7-4:11|0|1|2", - "extent": "4:1-4:22|0|1|0", + "spell": "4:7-4:11|0|1|2|-1", + "extent": "4:1-4:22|0|1|0|-1", "alias_of": 5123806965838456033, "bases": [], "derived": [], @@ -26,7 +26,7 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["5:13-5:17|0|1|4"] + "uses": ["5:13-5:17|0|1|4|-1"] }, { "usr": 5123806965838456033, "detailed_name": "template<> struct Foo", @@ -41,14 +41,14 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["4:14-4:17|0|1|4"] + "uses": ["4:14-4:17|0|1|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["2:8-2:11|0|1|1"], + "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -71,7 +71,7 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["5:9-5:12|0|1|4"] + "uses": ["5:9-5:12|0|1|4|-1"] }, { "usr": 15933698173231330933, "detailed_name": "typedef Foo Foo2", @@ -79,8 +79,8 @@ typedef Foo Foo2; "short_name": "Foo2", "kind": 252, "declarations": [], - "spell": "5:19-5:23|0|1|2", - "extent": "5:1-5:23|0|1|0", + "spell": "5:19-5:23|0|1|2|-1", + "extent": "5:1-5:23|0|1|0|-1", "alias_of": 14491685842684954828, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index fead6f19a..5baaf0f81 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -21,9 +21,9 @@ extern Foo foo; "short_name": "make", "kind": 6, "storage": 0, - "declarations": ["2:8-2:12|15041163540773201510|2|1025"], - "spell": "5:11-5:15|15041163540773201510|2|1026", - "extent": "5:1-8:2|15041163540773201510|2|0", + "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], + "spell": "5:11-5:15|15041163540773201510|2|1026|-1", + "extent": "5:1-8:2|15041163540773201510|2|0|-1", "bases": [], "derived": [], "vars": [16380484338511689669], @@ -37,8 +37,8 @@ extern Foo foo; "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -46,14 +46,14 @@ extern Foo foo; "funcs": [9488177941273031343], "vars": [], "instances": [16380484338511689669, 14455976355866885943], - "uses": ["2:3-2:6|15041163540773201510|2|4", "5:1-5:4|0|1|4", "5:6-5:9|0|1|4", "6:3-6:6|9488177941273031343|3|4", "10:8-10:11|0|1|4"] + "uses": ["2:3-2:6|15041163540773201510|2|4|-1", "5:1-5:4|0|1|4|-1", "5:6-5:9|0|1|4|-1", "6:3-6:6|9488177941273031343|3|4|-1", "10:8-10:11|0|1|4|-1"] }], "usr2var": [{ "usr": 14455976355866885943, "detailed_name": "extern Foo foo", "qual_name_offset": 11, "short_name": "foo", - "declarations": ["10:12-10:15|0|1|1"], + "declarations": ["10:12-10:15|10:1-10:15|0|1|1|-1"], "type": 15041163540773201510, "uses": [], "kind": 13, @@ -64,8 +64,8 @@ extern Foo foo; "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "6:7-6:8|9488177941273031343|3|2", - "extent": "6:3-6:8|9488177941273031343|3|0", + "spell": "6:7-6:8|9488177941273031343|3|2|-1", + "extent": "6:3-6:8|9488177941273031343|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 036671a40..39ef7456b 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -27,8 +27,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "12:6-12:9|0|1|2", - "extent": "12:1-15:2|0|1|0", + "spell": "12:6-12:9|0|1|2|-1", + "extent": "12:1-15:2|0|1|0|-1", "bases": [], "derived": [], "vars": [8039186520399841081], @@ -41,11 +41,11 @@ void foo() { "short_name": "gen", "kind": 12, "storage": 0, - "declarations": ["3:5-3:8|0|1|1"], + "declarations": ["3:5-3:8|3:1-3:10|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["14:14-14:17|4259594751088586730|3|16420"], + "uses": ["14:14-14:17|4259594751088586730|3|16420|-1"], "callees": [] }, { "usr": 18319417758892371313, @@ -54,11 +54,11 @@ void foo() { "short_name": "called", "kind": 12, "storage": 0, - "declarations": ["1:6-1:12|0|1|1"], + "declarations": ["1:6-1:12|1:1-1:19|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|16420"], + "uses": ["14:3-14:9|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -83,8 +83,8 @@ void foo() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "5:8-5:11|0|1|2", - "extent": "5:1-8:2|0|1|0", + "spell": "5:8-5:11|0|1|2|-1", + "extent": "5:1-8:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -95,7 +95,7 @@ void foo() { "R": 0 }], "instances": [], - "uses": ["10:5-10:8|0|1|4", "14:22-14:25|4259594751088586730|3|4", "14:40-14:43|4259594751088586730|3|4"] + "uses": ["10:5-10:8|0|1|4|-1", "14:22-14:25|4259594751088586730|3|4|-1", "14:40-14:43|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 8039186520399841081, @@ -104,10 +104,10 @@ void foo() { "short_name": "a", "hover": "int a = 5", "declarations": [], - "spell": "13:7-13:8|4259594751088586730|3|2", - "extent": "13:3-13:12|4259594751088586730|3|0", + "spell": "13:7-13:8|4259594751088586730|3|2|-1", + "extent": "13:3-13:12|4259594751088586730|3|0|-1", "type": 53, - "uses": ["14:10-14:11|4259594751088586730|3|12"], + "uses": ["14:10-14:11|4259594751088586730|3|12|-1"], "kind": 13, "storage": 0 }, { @@ -116,10 +116,10 @@ void foo() { "qual_name_offset": 4, "short_name": "field_var", "declarations": [], - "spell": "7:7-7:16|15041163540773201510|2|1026", - "extent": "7:3-7:16|15041163540773201510|2|0", + "spell": "7:7-7:16|15041163540773201510|2|1026|-1", + "extent": "7:3-7:16|15041163540773201510|2|0|-1", "type": 53, - "uses": ["14:28-14:37|4259594751088586730|3|12"], + "uses": ["14:28-14:37|4259594751088586730|3|12|-1"], "kind": 8, "storage": 0 }, { @@ -127,11 +127,11 @@ void foo() { "detailed_name": "static int Foo::static_var", "qual_name_offset": 11, "short_name": "static_var", - "declarations": ["6:14-6:24|15041163540773201510|2|1025"], - "spell": "10:10-10:20|15041163540773201510|2|1026", - "extent": "10:1-10:24|15041163540773201510|2|0", + "declarations": ["6:14-6:24|6:3-6:24|15041163540773201510|2|1025|-1"], + "spell": "10:10-10:20|15041163540773201510|2|1026|-1", + "extent": "10:1-10:24|15041163540773201510|2|0|-1", "type": 53, - "uses": ["14:45-14:55|4259594751088586730|3|12"], + "uses": ["14:45-14:55|4259594751088586730|3|12|-1"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index 9bb67ba9c..db2c738ed 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -19,8 +19,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "5:6-5:9|0|1|2", - "extent": "5:1-7:2|0|1|0", + "spell": "5:6-5:9|0|1|2|-1", + "extent": "5:1-7:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -34,12 +34,12 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:5-3:8|0|1|2", - "extent": "3:1-3:24|0|1|0", + "spell": "3:5-3:8|0|1|2|-1", + "extent": "3:1-3:24|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["6:10-6:13|4259594751088586730|3|16420", "6:18-6:21|4259594751088586730|3|16420"], + "uses": ["6:10-6:13|4259594751088586730|3|16420|-1", "6:18-6:21|4259594751088586730|3|16420|-1"], "callees": [] }, { "usr": 18319417758892371313, @@ -48,11 +48,11 @@ void foo() { "short_name": "called", "kind": 12, "storage": 0, - "declarations": ["1:6-1:12|0|1|1"], + "declarations": ["1:6-1:12|1:1-1:19|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["6:3-6:9|4259594751088586730|3|16420"], + "uses": ["6:3-6:9|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [], diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 5ac9d0fad..e28d09549 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -20,12 +20,12 @@ void caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2", - "extent": "1:1-1:17|0|1|0", + "spell": "1:6-1:12|0|1|2|-1", + "extent": "1:1-1:17|0|1|0|-1", "bases": [], "derived": [], "vars": [], - "uses": ["4:13-4:19|11404881820527069090|3|132", "7:3-7:9|11404881820527069090|3|16420"], + "uses": ["4:13-4:19|11404881820527069090|3|132|-1", "7:3-7:9|11404881820527069090|3|16420|-1"], "callees": [] }, { "usr": 11404881820527069090, @@ -35,8 +35,8 @@ void caller() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:12|0|1|2", - "extent": "3:1-8:2|0|1|0", + "spell": "3:6-3:12|0|1|2|-1", + "extent": "3:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [9121974011454213596], @@ -51,10 +51,10 @@ void caller() { "short_name": "x", "hover": "auto x = &called", "declarations": [], - "spell": "4:8-4:9|11404881820527069090|3|2", - "extent": "4:3-4:19|11404881820527069090|3|0", + "spell": "4:8-4:9|11404881820527069090|3|2|-1", + "extent": "4:3-4:19|11404881820527069090|3|0|-1", "type": 0, - "uses": ["5:3-5:4|11404881820527069090|3|16428"], + "uses": ["5:3-5:4|11404881820527069090|3|16428|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 93667b6d7..1a25fe9ff 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -30,8 +30,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "10:6-10:9|0|1|2", - "extent": "10:1-18:2|0|1|0", + "spell": "10:6-10:9|0|1|2|-1", + "extent": "10:1-18:2|0|1|0|-1", "bases": [], "derived": [], "vars": [14669930844300034456], @@ -44,11 +44,11 @@ void foo() { "short_name": "accept", "kind": 12, "storage": 0, - "declarations": ["8:6-8:12|0|1|1"], + "declarations": ["8:6-8:12|8:1-8:18|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["16:3-16:9|4259594751088586730|3|16420"], + "uses": ["16:3-16:9|4259594751088586730|3|16420|-1"], "callees": [] }, { "usr": 17175780305784503374, @@ -57,11 +57,11 @@ void foo() { "short_name": "accept", "kind": 12, "storage": 0, - "declarations": ["7:6-7:12|0|1|1"], + "declarations": ["7:6-7:12|7:1-7:17|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|16420", "15:3-15:9|4259594751088586730|3|16420", "17:3-17:9|4259594751088586730|3|16420"], + "uses": ["14:3-14:9|4259594751088586730|3|16420|-1", "15:3-15:9|4259594751088586730|3|16420|-1", "17:3-17:9|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -86,8 +86,8 @@ void foo() { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-5:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -101,7 +101,7 @@ void foo() { "R": 32 }], "instances": [14669930844300034456], - "uses": ["11:3-11:6|4259594751088586730|3|4"] + "uses": ["11:3-11:6|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 3873837747174060388, @@ -109,10 +109,10 @@ void foo() { "qual_name_offset": 4, "short_name": "y", "declarations": [], - "spell": "4:7-4:8|15041163540773201510|2|1026", - "extent": "4:3-4:8|15041163540773201510|2|0", + "spell": "4:7-4:8|15041163540773201510|2|1026|-1", + "extent": "4:3-4:8|15041163540773201510|2|0|-1", "type": 53, - "uses": ["17:12-17:13|4259594751088586730|3|12"], + "uses": ["17:12-17:13|4259594751088586730|3|12|-1"], "kind": 8, "storage": 0 }, { @@ -121,10 +121,10 @@ void foo() { "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "3:7-3:8|15041163540773201510|2|1026", - "extent": "3:3-3:8|15041163540773201510|2|0", + "spell": "3:7-3:8|15041163540773201510|2|1026|-1", + "extent": "3:3-3:8|15041163540773201510|2|0|-1", "type": 53, - "uses": ["12:5-12:6|4259594751088586730|3|20", "13:5-13:6|4259594751088586730|3|4", "14:12-14:13|4259594751088586730|3|12", "15:12-15:13|4259594751088586730|3|12", "16:13-16:14|4259594751088586730|3|132"], + "uses": ["12:5-12:6|4259594751088586730|3|20|-1", "13:5-13:6|4259594751088586730|3|4|-1", "14:12-14:13|4259594751088586730|3|12|-1", "15:12-15:13|4259594751088586730|3|12|-1", "16:13-16:14|4259594751088586730|3|132|-1"], "kind": 8, "storage": 0 }, { @@ -133,10 +133,10 @@ void foo() { "qual_name_offset": 4, "short_name": "f", "declarations": [], - "spell": "11:7-11:8|4259594751088586730|3|2", - "extent": "11:3-11:8|4259594751088586730|3|0", + "spell": "11:7-11:8|4259594751088586730|3|2|-1", + "extent": "11:3-11:8|4259594751088586730|3|0|-1", "type": 15041163540773201510, - "uses": ["12:3-12:4|4259594751088586730|3|4", "13:3-13:4|4259594751088586730|3|4", "14:10-14:11|4259594751088586730|3|4", "15:10-15:11|4259594751088586730|3|4", "16:11-16:12|4259594751088586730|3|4", "17:10-17:11|4259594751088586730|3|4"], + "uses": ["12:3-12:4|4259594751088586730|3|4|-1", "13:3-13:4|4259594751088586730|3|4|-1", "14:10-14:11|4259594751088586730|3|4|-1", "15:10-15:11|4259594751088586730|3|4|-1", "16:11-16:12|4259594751088586730|3|4|-1", "17:10-17:11|4259594751088586730|3|4|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 6f2eee7d4..8c21456f1 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -21,8 +21,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "7:6-7:9|0|1|2", - "extent": "7:1-9:2|0|1|0", + "spell": "7:6-7:9|0|1|2|-1", + "extent": "7:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -35,11 +35,11 @@ void foo() { "short_name": "accept", "kind": 12, "storage": 0, - "declarations": ["5:6-5:12|0|1|1"], + "declarations": ["5:6-5:12|5:1-5:17|0|1|1|-1"], "bases": [], "derived": [], "vars": [], - "uses": ["8:3-8:9|4259594751088586730|3|16420"], + "uses": ["8:3-8:9|4259594751088586730|3|16420|-1"], "callees": [] }], "usr2type": [{ @@ -64,8 +64,8 @@ void foo() { "short_name": "Foo", "kind": 23, "declarations": [], - "spell": "1:8-1:11|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:8-1:11|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -73,16 +73,16 @@ void foo() { "funcs": [], "vars": [], "instances": [], - "uses": ["8:10-8:13|4259594751088586730|3|4"] + "uses": ["8:10-8:13|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 8599782646965457351, "detailed_name": "static int Foo::x", "qual_name_offset": 11, "short_name": "x", - "declarations": ["2:14-2:15|15041163540773201510|2|1025"], + "declarations": ["2:14-2:15|2:3-2:15|15041163540773201510|2|1025|-1"], "type": 53, - "uses": ["8:15-8:16|4259594751088586730|3|12"], + "uses": ["8:15-8:16|4259594751088586730|3|12|-1"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 09991182c..dd3fe7081 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -20,8 +20,8 @@ const VarType Holder::static_var; "short_name": "VarType", "kind": 10, "declarations": [], - "spell": "1:6-1:13|0|1|2", - "extent": "1:1-1:16|0|1|0", + "spell": "1:6-1:13|0|1|2|-1", + "extent": "1:1-1:16|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -29,7 +29,7 @@ const VarType Holder::static_var; "funcs": [], "vars": [], "instances": [7057400933868440116, 7057400933868440116], - "uses": ["4:20-4:27|10028537921178202800|2|4", "4:42-4:49|10028537921178202800|2|4", "7:7-7:14|0|1|4"] + "uses": ["4:20-4:27|10028537921178202800|2|4|-1", "4:42-4:49|10028537921178202800|2|4|-1", "7:7-7:14|0|1|4|-1"] }, { "usr": 10028537921178202800, "detailed_name": "struct Holder {}", @@ -37,8 +37,8 @@ const VarType Holder::static_var; "short_name": "Holder", "kind": 23, "declarations": [], - "spell": "3:8-3:14|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:8-3:14|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -46,7 +46,7 @@ const VarType Holder::static_var; "funcs": [], "vars": [], "instances": [], - "uses": ["7:15-7:21|0|1|4"] + "uses": ["7:15-7:21|0|1|4|-1"] }], "usr2var": [{ "usr": 7057400933868440116, @@ -54,9 +54,9 @@ const VarType Holder::static_var; "qual_name_offset": 25, "short_name": "static_var", "hover": "static constexpr VarType Holder::static_var = (VarType)0x0", - "declarations": ["4:28-4:38|10028537921178202800|2|1025"], - "spell": "7:23-7:33|10028537921178202800|2|1026", - "extent": "7:1-7:33|10028537921178202800|2|0", + "declarations": ["4:28-4:38|4:3-4:53|10028537921178202800|2|1025|-1"], + "spell": "7:23-7:33|10028537921178202800|2|1026|-1", + "extent": "7:1-7:33|10028537921178202800|2|0|-1", "type": 5792006888140599735, "uses": [], "kind": 13, diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 09442598c..0d3469e62 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -16,8 +16,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -45,9 +45,9 @@ void foo() { "detailed_name": "extern int a", "qual_name_offset": 11, "short_name": "a", - "declarations": ["1:12-1:13|0|1|1"], + "declarations": ["1:12-1:13|1:1-1:13|0|1|1|-1"], "type": 53, - "uses": ["4:3-4:4|4259594751088586730|3|20"], + "uses": ["4:3-4:4|4259594751088586730|3|20|-1"], "kind": 13, "storage": 1 }] diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 9bfd50aa2..2a5e0867a 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -14,8 +14,8 @@ void foo(int a) { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "bases": [], "derived": [], "vars": [10063793875496522529], @@ -44,10 +44,10 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026", - "extent": "1:10-1:15|11998306017310352355|3|0", + "spell": "1:14-1:15|11998306017310352355|3|1026|-1", + "extent": "1:10-1:15|11998306017310352355|3|0|-1", "type": 53, - "uses": ["2:3-2:4|11998306017310352355|3|4"], + "uses": ["2:3-2:4|11998306017310352355|3|4|-1"], "kind": 253, "storage": 0 }] diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index f6eb9d022..b4ed38423 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -15,8 +15,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-4:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-4:2|0|1|0|-1", "bases": [], "derived": [], "vars": [14014650769929566957], @@ -45,10 +45,10 @@ void foo() { "qual_name_offset": 4, "short_name": "x", "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2", - "extent": "2:3-2:8|4259594751088586730|3|0", + "spell": "2:7-2:8|4259594751088586730|3|2|-1", + "extent": "2:3-2:8|4259594751088586730|3|0|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20"], + "uses": ["3:3-3:4|4259594751088586730|3|20|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index d0f9a35fc..2aaf27be2 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -20,8 +20,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-9:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [13311055950748663970, 14036425367303419504], @@ -50,10 +50,10 @@ void foo() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2", - "extent": "2:3-2:8|4259594751088586730|3|0", + "spell": "2:7-2:8|4259594751088586730|3|2|-1", + "extent": "2:3-2:8|4259594751088586730|3|0|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20", "8:3-8:4|4259594751088586730|3|20"], + "uses": ["3:3-3:4|4259594751088586730|3|20|-1", "8:3-8:4|4259594751088586730|3|20|-1"], "kind": 13, "storage": 0 }, { @@ -62,10 +62,10 @@ void foo() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:9-5:10|4259594751088586730|3|2", - "extent": "5:5-5:10|4259594751088586730|3|0", + "spell": "5:9-5:10|4259594751088586730|3|2|-1", + "extent": "5:5-5:10|4259594751088586730|3|0|-1", "type": 53, - "uses": ["6:5-6:6|4259594751088586730|3|20"], + "uses": ["6:5-6:6|4259594751088586730|3|20|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 8a99171d5..801f3a750 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -20,8 +20,8 @@ void foo(int a) { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-8:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-8:2|0|1|0|-1", "bases": [], "derived": [], "vars": [11608231465452906059, 6997229590862003559], @@ -50,10 +50,10 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "4:9-4:10|11998306017310352355|3|2", - "extent": "4:5-4:10|11998306017310352355|3|0", + "spell": "4:9-4:10|11998306017310352355|3|2|-1", + "extent": "4:5-4:10|11998306017310352355|3|0|-1", "type": 53, - "uses": ["5:5-5:6|11998306017310352355|3|20"], + "uses": ["5:5-5:6|11998306017310352355|3|20|-1"], "kind": 13, "storage": 0 }, { @@ -62,10 +62,10 @@ void foo(int a) { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026", - "extent": "1:10-1:15|11998306017310352355|3|0", + "spell": "1:14-1:15|11998306017310352355|3|1026|-1", + "extent": "1:10-1:15|11998306017310352355|3|0|-1", "type": 53, - "uses": ["2:3-2:4|11998306017310352355|3|20", "7:3-7:4|11998306017310352355|3|20"], + "uses": ["2:3-2:4|11998306017310352355|3|20|-1", "7:3-7:4|11998306017310352355|3|20|-1"], "kind": 253, "storage": 0 }] diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 9c8258305..396f3ded3 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -17,8 +17,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [], @@ -47,10 +47,10 @@ void foo() { "qual_name_offset": 11, "short_name": "a", "declarations": [], - "spell": "1:12-1:13|0|1|2", - "extent": "1:1-1:13|0|1|0", + "spell": "1:12-1:13|0|1|2|-1", + "extent": "1:1-1:13|0|1|0|-1", "type": 53, - "uses": ["4:3-4:4|4259594751088586730|3|20"], + "uses": ["4:3-4:4|4259594751088586730|3|20|-1"], "kind": 13, "storage": 2 }] diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 4b3925a73..7bb7bc970 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -14,8 +14,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -26,7 +26,7 @@ class Foo { "R": 0 }], "instances": [13799811842374292251], - "uses": ["2:3-2:6|15041163540773201510|2|4"] + "uses": ["2:3-2:6|15041163540773201510|2|4|-1"] }], "usr2var": [{ "usr": 13799811842374292251, @@ -34,8 +34,8 @@ class Foo { "qual_name_offset": 5, "short_name": "member", "declarations": [], - "spell": "2:8-2:14|15041163540773201510|2|1026", - "extent": "2:3-2:14|15041163540773201510|2|0", + "spell": "2:8-2:14|15041163540773201510|2|1026|-1", + "extent": "2:3-2:14|15041163540773201510|2|0|-1", "type": 15041163540773201510, "uses": [], "kind": 8, diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 1dcb0699e..86e090415 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -16,8 +16,8 @@ Foo* Foo::member = nullptr; "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -25,16 +25,16 @@ Foo* Foo::member = nullptr; "funcs": [], "vars": [], "instances": [5844987037615239736, 5844987037615239736], - "uses": ["2:10-2:13|15041163540773201510|2|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] + "uses": ["2:10-2:13|15041163540773201510|2|4|-1", "4:1-4:4|0|1|4|-1", "4:6-4:9|0|1|4|-1"] }], "usr2var": [{ "usr": 5844987037615239736, "detailed_name": "static Foo *Foo::member", "qual_name_offset": 12, "short_name": "member", - "declarations": ["2:15-2:21|15041163540773201510|2|1025"], - "spell": "4:11-4:17|15041163540773201510|2|1026", - "extent": "4:1-4:27|15041163540773201510|2|0", + "declarations": ["2:15-2:21|2:3-2:21|15041163540773201510|2|1025|-1"], + "spell": "4:11-4:17|15041163540773201510|2|1026|-1", + "extent": "4:1-4:27|15041163540773201510|2|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index b0f84d67d..d01c6220a 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -29,8 +29,8 @@ class Foo { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -45,7 +45,7 @@ class Foo { "detailed_name": "static int Foo::member", "qual_name_offset": 11, "short_name": "member", - "declarations": ["2:14-2:20|15041163540773201510|2|1025"], + "declarations": ["2:14-2:20|2:3-2:20|15041163540773201510|2|1025|-1"], "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 3823df908..f76c0460f 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -17,8 +17,8 @@ void f() { "kind": 12, "storage": 0, "declarations": [], - "spell": "2:6-2:7|0|1|2", - "extent": "2:1-5:2|0|1|0", + "spell": "2:6-2:7|0|1|2|-1", + "extent": "2:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [10601729374837386290, 18422884837902130475], @@ -32,8 +32,8 @@ void f() { "short_name": "Foo", "kind": 5, "declarations": [], - "spell": "1:7-1:10|0|1|2", - "extent": "1:1-1:13|0|1|0", + "spell": "1:7-1:10|0|1|2|-1", + "extent": "1:1-1:13|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -41,7 +41,7 @@ void f() { "funcs": [], "vars": [], "instances": [10601729374837386290, 18422884837902130475], - "uses": ["3:16-3:19|880549676430489861|3|4", "4:17-4:20|880549676430489861|3|4"] + "uses": ["3:16-3:19|880549676430489861|3|4|-1", "4:17-4:20|880549676430489861|3|4|-1"] }], "usr2var": [{ "usr": 10601729374837386290, @@ -50,8 +50,8 @@ void f() { "short_name": "x", "hover": "auto x = new Foo()", "declarations": [], - "spell": "3:8-3:9|880549676430489861|3|2", - "extent": "3:3-3:21|880549676430489861|3|0", + "spell": "3:8-3:9|880549676430489861|3|2|-1", + "extent": "3:3-3:21|880549676430489861|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, @@ -63,8 +63,8 @@ void f() { "short_name": "y", "hover": "Foo *y = new Foo()", "declarations": [], - "spell": "4:9-4:10|880549676430489861|3|2", - "extent": "4:3-4:22|880549676430489861|3|0", + "spell": "4:9-4:10|880549676430489861|3|2|-1", + "extent": "4:3-4:22|880549676430489861|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index b6197c40b..66b965733 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -17,8 +17,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [13198746475679542317], @@ -31,7 +31,7 @@ void foo() { "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["1:8-1:11|0|1|1"], + "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -39,7 +39,7 @@ void foo() { "funcs": [], "vars": [], "instances": [13198746475679542317], - "uses": ["4:3-4:6|4259594751088586730|3|4"] + "uses": ["4:3-4:6|4259594751088586730|3|4|-1"] }], "usr2var": [{ "usr": 13198746475679542317, @@ -47,8 +47,8 @@ void foo() { "qual_name_offset": 5, "short_name": "a", "declarations": [], - "spell": "4:8-4:9|4259594751088586730|3|2", - "extent": "4:3-4:9|4259594751088586730|3|0", + "spell": "4:8-4:9|4259594751088586730|3|2|-1", + "extent": "4:3-4:9|4259594751088586730|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index 96a844ad0..a9c8683f2 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -15,8 +15,8 @@ void foo(Foo* p0, Foo* p1) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-3:30|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-3:30|0|1|0|-1", "bases": [], "derived": [], "vars": [8730439006497971620, 2525014371090380500], @@ -29,7 +29,7 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 7, "short_name": "Foo", "kind": 23, - "declarations": ["1:8-1:11|0|1|1"], + "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -37,7 +37,7 @@ void foo(Foo* p0, Foo* p1) {} "funcs": [], "vars": [], "instances": [8730439006497971620, 2525014371090380500], - "uses": ["3:10-3:13|0|1|4", "3:19-3:22|0|1|4"] + "uses": ["3:10-3:13|0|1|4|-1", "3:19-3:22|0|1|4|-1"] }], "usr2var": [{ "usr": 2525014371090380500, @@ -45,8 +45,8 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p1", "declarations": [], - "spell": "3:24-3:26|8908726657907936744|3|1026", - "extent": "3:19-3:26|8908726657907936744|3|0", + "spell": "3:24-3:26|8908726657907936744|3|1026|-1", + "extent": "3:19-3:26|8908726657907936744|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 253, @@ -57,8 +57,8 @@ void foo(Foo* p0, Foo* p1) {} "qual_name_offset": 5, "short_name": "p0", "declarations": [], - "spell": "3:15-3:17|8908726657907936744|3|1026", - "extent": "3:10-3:17|8908726657907936744|3|0", + "spell": "3:15-3:17|8908726657907936744|3|1026|-1", + "extent": "3:10-3:17|8908726657907936744|3|0|-1", "type": 15041163540773201510, "uses": [], "kind": 253, diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index 6ecfe2fa4..48b4f60ba 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -12,8 +12,8 @@ void foo(int, int) {} "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-1:22|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-1:22|0|1|0|-1", "bases": [], "derived": [], "vars": [], diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 27c7b00be..d6ffa4ef5 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -20,8 +20,8 @@ void foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-9:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-9:2|0|1|0|-1", "bases": [], "derived": [], "vars": [1894874819807168345, 4508045017817092115], @@ -50,10 +50,10 @@ void foo() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2", - "extent": "2:3-2:8|4259594751088586730|3|0", + "spell": "2:7-2:8|4259594751088586730|3|2|-1", + "extent": "2:3-2:8|4259594751088586730|3|0|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20", "8:3-8:4|4259594751088586730|3|20"], + "uses": ["3:3-3:4|4259594751088586730|3|20|-1", "8:3-8:4|4259594751088586730|3|20|-1"], "kind": 13, "storage": 0 }, { @@ -62,10 +62,10 @@ void foo() { "qual_name_offset": 4, "short_name": "a", "declarations": [], - "spell": "5:9-5:10|4259594751088586730|3|2", - "extent": "5:5-5:10|4259594751088586730|3|0", + "spell": "5:9-5:10|4259594751088586730|3|2|-1", + "extent": "5:5-5:10|4259594751088586730|3|0|-1", "type": 53, - "uses": ["6:5-6:6|4259594751088586730|3|20"], + "uses": ["6:5-6:6|4259594751088586730|3|20|-1"], "kind": 13, "storage": 0 }] diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index f2d522113..9ef35ec9f 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -14,8 +14,8 @@ void foo(int p) { "kind": 12, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2", - "extent": "1:1-3:2|0|1|0", + "spell": "1:6-1:9|0|1|2|-1", + "extent": "1:1-3:2|0|1|0|-1", "bases": [], "derived": [], "vars": [5875271969926422921, 11404600766177939811], @@ -44,8 +44,8 @@ void foo(int p) { "qual_name_offset": 4, "short_name": "p", "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026", - "extent": "1:10-1:15|11998306017310352355|3|0", + "spell": "1:14-1:15|11998306017310352355|3|1026|-1", + "extent": "1:10-1:15|11998306017310352355|3|0|-1", "type": 53, "uses": [], "kind": 253, @@ -57,8 +57,8 @@ void foo(int p) { "short_name": "p", "hover": "int p = 0", "declarations": [], - "spell": "2:9-2:10|11998306017310352355|3|2", - "extent": "2:5-2:14|11998306017310352355|3|0", + "spell": "2:9-2:10|11998306017310352355|3|2|-1", + "extent": "2:5-2:14|11998306017310352355|3|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index c76dd406a..0f563a73c 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -28,8 +28,8 @@ static int global = 0; "short_name": "global", "hover": "static int global = 0", "declarations": [], - "spell": "1:12-1:18|0|1|2", - "extent": "1:1-1:22|0|1|0", + "spell": "1:12-1:18|0|1|2|-1", + "extent": "1:1-1:22|0|1|0|-1", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index 8ca10b9ec..0ecf84a27 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -26,7 +26,7 @@ extern int global; "detailed_name": "extern int global", "qual_name_offset": 11, "short_name": "global", - "declarations": ["1:12-1:18|0|1|1"], + "declarations": ["1:12-1:18|1:1-1:18|0|1|1|-1"], "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index 7a6ebcf6b..b924afd5b 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -19,8 +19,8 @@ void Foo() { "kind": 12, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2", - "extent": "3:1-5:2|0|1|0", + "spell": "3:6-3:9|0|1|2|-1", + "extent": "3:1-5:2|0|1|0|-1", "bases": [], "derived": [], "vars": [6975456769752895964], @@ -34,8 +34,8 @@ void Foo() { "short_name": "S", "kind": 23, "declarations": [], - "spell": "1:8-1:9|0|1|2", - "extent": "1:1-1:12|0|1|0", + "spell": "1:8-1:9|0|1|2|-1", + "extent": "1:1-1:12|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -43,7 +43,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [], - "uses": ["2:11-2:12|0|1|4"] + "uses": ["2:11-2:12|0|1|4|-1"] }, { "usr": 7434820806199665424, "detailed_name": "using F = S", @@ -51,8 +51,8 @@ void Foo() { "short_name": "F", "kind": 252, "declarations": [], - "spell": "2:7-2:8|0|1|2", - "extent": "2:1-2:12|0|1|0", + "spell": "2:7-2:8|0|1|2|-1", + "extent": "2:1-2:12|0|1|0|-1", "alias_of": 4750332761459066907, "bases": [], "derived": [], @@ -60,7 +60,7 @@ void Foo() { "funcs": [], "vars": [], "instances": [6975456769752895964], - "uses": ["4:3-4:4|4654328188330986029|3|4"] + "uses": ["4:3-4:4|4654328188330986029|3|4|-1"] }], "usr2var": [{ "usr": 6975456769752895964, @@ -68,8 +68,8 @@ void Foo() { "qual_name_offset": 2, "short_name": "a", "declarations": [], - "spell": "4:5-4:6|4654328188330986029|3|2", - "extent": "4:3-4:6|4654328188330986029|3|0", + "spell": "4:5-4:6|4654328188330986029|3|2|-1", + "extent": "4:3-4:6|4654328188330986029|3|0|-1", "type": 7434820806199665424, "uses": [], "kind": 13, diff --git a/src/indexer.cc b/src/indexer.cc index ce53ad164..ad3580ccb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -686,12 +686,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceRange R = OrigD->getSourceRange(); entity->def.extent = GetUse(db, lid, - R.getBegin().isFileID() - ? FromTokenRange(SM, Lang, OrigD->getSourceRange()) - : loc, + R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, LexDC, Role::None); } else if (is_decl) { - entity->declarations.push_back(GetUse(db, lid, loc, LexDC, role)); + DeclRef &dr = entity->declarations.emplace_back(); + static_cast(dr) = GetUse(db, lid, loc, LexDC, role); + SourceRange R = OrigD->getSourceRange(); + dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc; } else { entity->uses.push_back(GetUse(db, lid, loc, LexDC, role)); return; @@ -1085,8 +1086,11 @@ class IndexPPCallbacks : public PPCallbacks { IndexVar &var = db->ToVar(usr); auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); var.def.kind = lsSymbolKind::Macro; - if (var.def.spell) - var.declarations.push_back(*var.def.spell); + if (var.def.spell) { + DeclRef &d = var.declarations.emplace_back(); + static_cast(d) = *var.def.spell; + d.extent = var.def.spell->range; + } var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}}; const MacroInfo *MI = MD->getMacroInfo(); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); @@ -1148,8 +1152,8 @@ class IndexFrontendAction : public ASTFrontendAction { }; } // namespace -const int IndexFile::kMajorVersion = 17; -const int IndexFile::kMinorVersion = 1; +const int IndexFile::kMajorVersion = 18; +const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) @@ -1348,8 +1352,7 @@ void Reflect(Reader &vis, Use &v) { v.usr = strtoull(s + 1, &s, 10); v.kind = static_cast(strtol(s + 1, &s, 10)); v.role = static_cast(strtol(s + 1, &s, 10)); - if (*s == '|') - v.file_id = static_cast(strtol(s + 1, &s, 10)); + v.file_id = static_cast(strtol(s + 1, &s, 10)); } else { Reflect(vis, static_cast(v)); Reflect(vis, v.file_id); @@ -1358,13 +1361,9 @@ void Reflect(Reader &vis, Use &v) { void Reflect(Writer &vis, Use &v) { if (vis.Format() == SerializeFormat::Json) { char buf[99]; - if (v.file_id == -1) - snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", - v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role)); - else - snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d|%d", - v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role), - v.file_id); + snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d|%d", + v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role), + v.file_id); std::string s(buf); Reflect(vis, s); } else { @@ -1372,3 +1371,34 @@ void Reflect(Writer &vis, Use &v) { Reflect(vis, v.file_id); } } + +void Reflect(Reader &vis, DeclRef &v) { + if (vis.Format() == SerializeFormat::Json) { + std::string t = vis.GetString(); + char *s = const_cast(t.c_str()); + v.range = Range::FromString(s); + s = strchr(s, '|') + 1; + v.extent = Range::FromString(s); + s = strchr(s, '|') + 1; + v.usr = strtoull(s, &s, 10); + v.kind = static_cast(strtol(s + 1, &s, 10)); + v.role = static_cast(strtol(s + 1, &s, 10)); + v.file_id = static_cast(strtol(s + 1, &s, 10)); + } else { + Reflect(vis, static_cast(v)); + Reflect(vis, v.extent); + } +} +void Reflect(Writer &vis, DeclRef &v) { + if (vis.Format() == SerializeFormat::Json) { + char buf[99]; + snprintf(buf, sizeof buf, "%s|%s|%" PRIu64 "|%d|%d|%d", + v.range.ToString().c_str(), v.extent.ToString().c_str(), v.usr, + int(v.kind), int(v.role), v.file_id); + std::string s(buf); + Reflect(vis, s); + } else { + Reflect(vis, static_cast(v)); + Reflect(vis, v.extent); + } +} diff --git a/src/indexer.h b/src/indexer.h index 355b5a984..4051e5412 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -82,10 +82,17 @@ struct Use : Reference { }; MAKE_HASHABLE(Use, t.range, t.file_id) +struct DeclRef : Use { + Range extent; +}; +MAKE_HASHABLE(DeclRef, t.range, t.file_id) + void Reflect(Reader &visitor, Reference &value); void Reflect(Writer &visitor, Reference &value); void Reflect(Reader &visitor, Use &value); void Reflect(Writer &visitor, Use &value); +void Reflect(Reader &visitor, DeclRef &value); +void Reflect(Writer &visitor, DeclRef &value); template struct NameMixin { std::string_view Name(bool qualified) const { @@ -134,7 +141,7 @@ struct IndexFunc : NameMixin { using Def = FuncDef; Usr usr; Def def; - std::vector declarations; + std::vector declarations; std::vector uses; std::vector derived; }; @@ -174,7 +181,7 @@ struct IndexType { using Def = TypeDef; Usr usr; Def def; - std::vector declarations; + std::vector declarations; std::vector uses; std::vector derived; std::vector instances; @@ -216,7 +223,7 @@ struct IndexVar { using Def = VarDef; Usr usr; Def def; - std::vector declarations; + std::vector declarations; std::vector uses; }; diff --git a/src/query.cc b/src/query.cc index 88a7e809f..be657184e 100644 --- a/src/query.cc +++ b/src/query.cc @@ -38,13 +38,8 @@ void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) { use.usr = use.file_id; } -void AddRange(std::vector &into, const std::vector &from) { - into.reserve(into.size() + from.size()); - for (Use use : from) - into.push_back(use); -} - -void AddRange(std::vector &into, const std::vector &from) { +template +void AddRange(std::vector &into, const std::vector &from) { into.insert(into.end(), from.begin(), from.end()); } @@ -243,6 +238,12 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { files[use.file_id] .outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta; }; + auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, + SymbolKind kind, DeclRef &dr, int delta) { + Ref(lid2fid, usr, kind, dr, delta, 1); + files[dr.file_id] + .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta; + }; auto UpdateUses = [&](Usr usr, SymbolKind kind, llvm::DenseMap &entity_usr, @@ -298,10 +299,10 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); for (auto &[usr, del_add]: u->funcs_declarations) { - for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Func, use, -1, 3); - for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Func, use, 1, 3); + for (DeclRef &dr : del_add.first) + RefDecl(prev_lid2file_id, usr, SymbolKind::Func, dr, -1); + for (DeclRef &dr : del_add.second) + RefDecl(lid2file_id, usr, SymbolKind::Func, dr, 1); } REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); @@ -322,10 +323,10 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); Update(lid2file_id, u->file_id, std::move(u->types_def_update)); for (auto &[usr, del_add]: u->types_declarations) { - for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Type, use, -1, 3); - for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Type, use, 1, 3); + for (DeclRef &dr : del_add.first) + RefDecl(prev_lid2file_id, usr, SymbolKind::Type, dr, -1); + for (DeclRef &dr : del_add.second) + RefDecl(lid2file_id, usr, SymbolKind::Type, dr, 1); } REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); @@ -347,10 +348,10 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); for (auto &[usr, del_add]: u->vars_declarations) { - for (Use &use : del_add.first) - Ref(prev_lid2file_id, usr, SymbolKind::Var, use, -1, 3); - for (Use &use : del_add.second) - Ref(lid2file_id, usr, SymbolKind::Var, use, 1, 3); + for (DeclRef &dr : del_add.first) + RefDecl(prev_lid2file_id, usr, SymbolKind::Var, dr, -1); + for (DeclRef &dr : del_add.second) + RefDecl(lid2file_id, usr, SymbolKind::Var, dr, 1); } REMOVE_ADD(var, declarations); for (auto &[usr, p] : u->vars_uses) diff --git a/src/query.h b/src/query.h index 5f0a5d240..7cf17018d 100644 --- a/src/query.h +++ b/src/query.h @@ -73,6 +73,9 @@ template struct QueryEntity { } }; +using DeclRefUpdate = + std::unordered_map, std::vector>>; using UseUpdate = std::unordered_map, std::vector>>; using UsrUpdate = @@ -81,7 +84,7 @@ using UsrUpdate = struct QueryFunc : QueryEntity { Usr usr; llvm::SmallVector def; - std::vector declarations; + std::vector declarations; std::vector uses; std::vector derived; }; @@ -89,7 +92,7 @@ struct QueryFunc : QueryEntity { struct QueryType : QueryEntity { Usr usr; llvm::SmallVector def; - std::vector declarations; + std::vector declarations; std::vector uses; std::vector derived; std::vector instances; @@ -98,7 +101,7 @@ struct QueryType : QueryEntity { struct QueryVar : QueryEntity { Usr usr; llvm::SmallVector def; - std::vector declarations; + std::vector declarations; std::vector uses; }; @@ -123,7 +126,7 @@ struct IndexUpdate { int funcs_hint; std::vector> funcs_removed; std::vector> funcs_def_update; - UseUpdate funcs_declarations; + DeclRefUpdate funcs_declarations; UseUpdate funcs_uses; UsrUpdate funcs_derived; @@ -131,7 +134,7 @@ struct IndexUpdate { int types_hint; std::vector> types_removed; std::vector> types_def_update; - UseUpdate types_declarations; + DeclRefUpdate types_declarations; UseUpdate types_uses; UsrUpdate types_derived; UsrUpdate types_instances; @@ -140,7 +143,7 @@ struct IndexUpdate { int vars_hint; std::vector> vars_removed; std::vector> vars_def_update; - UseUpdate vars_declarations; + DeclRefUpdate vars_declarations; UseUpdate vars_uses; }; diff --git a/src/query_utils.cc b/src/query_utils.cc index c4fdc5d70..af885525e 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -105,16 +105,24 @@ std::vector GetVarDeclarations(DB *db, const std::vector &usrs, } std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym) { + std::vector ret; switch (sym.kind) { case SymbolKind::Func: - return db->GetFunc(sym).declarations; + for (auto &d : db->GetFunc(sym).declarations) + ret.push_back(d); + break; case SymbolKind::Type: - return db->GetType(sym).declarations; + for (auto &d : db->GetType(sym).declarations) + ret.push_back(d); + break; case SymbolKind::Var: - return db->GetVar(sym).declarations; + for (auto &d : db->GetVar(sym).declarations) + ret.push_back(d); + break; default: - return {}; + break; } + return ret; } std::vector GetUsesForAllBases(DB *db, QueryFunc &root) { From 82d31a201250d8e7ac75acb9b90e5cabd61889cd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 7 Sep 2018 23:40:22 -0700 Subject: [PATCH 197/378] Implement index.onChange: true; enable spell checking for diagnostics --- src/clang_complete.cc | 1 + src/config.h | 4 +- src/indexer.cc | 19 +++++-- src/indexer.h | 4 +- src/messages/textDocument_didChange.cc | 4 +- src/messages/textDocument_didOpen.cc | 6 +-- src/messages/textDocument_didSave.cc | 24 ++------- .../workspace_didChangeWatchedFiles.cc | 12 +++-- src/pipeline.cc | 52 ++++++++++++------- src/pipeline.hh | 15 ++++-- src/project.cc | 8 +-- 11 files changed, 83 insertions(+), 66 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 4d6613af7..a5456c53d 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -623,6 +623,7 @@ void DiagnosticMain(ClangCompleteManager *manager) { BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; + CI->getLangOpts()->SpellChecking = true; StoreDiags DC; WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); diff --git a/src/config.h b/src/config.h index 3e22a0e94..79e7ee75c 100644 --- a/src/config.h +++ b/src/config.h @@ -201,7 +201,7 @@ struct Config { // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. - bool onDidChange = false; + bool onChange = false; // Whether to reparse a file if write times of its dependencies have // changed. The file will always be reparsed if its own write time changes. @@ -245,7 +245,7 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, onOpen, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, - multiVersionBlacklist, multiVersionWhitelist, onDidChange, + multiVersionBlacklist, multiVersionWhitelist, onChange, reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); diff --git a/src/indexer.cc b/src/indexer.cc index ad3580ccb..177d4be5e 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1131,9 +1131,10 @@ class IndexPPCallbacks : public PPCallbacks { void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { llvm::sys::fs::UniqueID UniqueID; auto range = FromCharRange(SM, param.Ctx->getLangOpts(), Range, &UniqueID); - const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin())); - if (IndexFile *db = param.ConsumeFile(*FE)) - db->skipped_ranges.push_back(range); + if (const FileEntry *FE = + SM.getFileEntryForID(SM.getFileID(Range.getBegin()))) + if (IndexFile *db = param.ConsumeFile(*FE)) + db->skipped_ranges.push_back(range); } }; @@ -1202,7 +1203,7 @@ void Init() { std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector &file_contents) { + const std::vector> &remapped) { if (!g_config->index.enabled) return {}; @@ -1226,6 +1227,14 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, // HSOpts.UseBuiltinIncludes) // HSOpts.ResourceDir = g_config->clang.resourceDir; } + std::vector> Bufs; + for (auto &[filename, content] : remapped) { + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); + CI->getPreprocessorOpts().addRemappedFile( + filename == file ? CI->getFrontendOpts().Inputs[0].getFile() + : StringRef(filename), + Bufs.back().get()); + } DiagnosticConsumer DC; auto Clang = std::make_unique(PCH); @@ -1272,6 +1281,8 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, LOG_S(ERROR) << "failed to index " << file; return {}; } + for (auto &Buf : Bufs) + Buf.release(); auto result = param.file_consumer->TakeLocalState(); for (std::unique_ptr &entry : result) { diff --git a/src/indexer.h b/src/indexer.h index 4051e5412..dc4fe774d 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -288,5 +288,5 @@ void Init(); std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector &file_contents); -} + const std::vector>& remapped); +} // namespace ccls::idx diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index a0690a2c6..1704282d7 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -38,9 +38,9 @@ struct Handler_TextDocumentDidChange void Run(In_TextDocumentDidChange *request) override { std::string path = request->params.textDocument.uri.GetPath(); working_files->OnChange(request->params); - if (g_config->index.onDidChange) { + if (g_config->index.onChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); - pipeline::Index(entry.filename, entry.args, true); + pipeline::Index(entry.filename, entry.args, IndexMode::OnChange); } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 8120f4be5..b88d3b947 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -35,8 +35,7 @@ struct In_TextDocumentDidOpen : public NotificationInMessage { // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project // entry (e.g. loaded from compile_commands.json or .ccls). std::vector args; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen::Params, textDocument, args); MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen, params); @@ -72,7 +71,8 @@ struct Handler_TextDocumentDidOpen if (SourceFileLanguage(path) != LanguageId::Unknown) { Project::Entry entry = project->FindCompilationEntryForFile(path); pipeline::Index(entry.filename, - params.args.size() ? params.args : entry.args, true); + params.args.size() ? params.args : entry.args, + IndexMode::Normal); clang_complete->FlushSession(entry.filename); } diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 17bb53ff2..023d1bb39 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -32,8 +32,7 @@ struct In_TextDocumentDidSave : public NotificationInMessage { // Optional the content when saved. Depends on the includeText value // when the save notifcation was requested. // std::string text; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_TextDocumentDidSave::Params, textDocument); MAKE_REFLECT_STRUCT(In_TextDocumentDidSave, params); @@ -47,25 +46,8 @@ struct Handler_TextDocumentDidSave const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); - // Send out an index request, and copy the current buffer state so we - // can update the cached index contents when the index is done. - // - // We also do not index if there is already an index request or if - // the client requested indexing on didChange instead. - // - // TODO: Cancel outgoing index request. Might be tricky to make - // efficient since we have to cancel. - // - we could have an |atomic active_cancellations| variable - // that all of the indexers check before accepting an index. if - // zero we don't slow down fast-path. if non-zero we acquire - // mutex and check to see if we should skip the current request. - // if so, ignore that index response. - // TODO: send as priority request - if (!g_config->index.onDidChange) { - Project::Entry entry = project->FindCompilationEntryForFile(path); - pipeline::Index(entry.filename, entry.args, true); - } - + Project::Entry entry = project->FindCompilationEntryForFile(path); + pipeline::Index(entry.filename, entry.args, IndexMode::Normal); clang_complete->NotifySave(path); } }; diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index c25078b90..b2c3eef59 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -62,18 +62,20 @@ struct Handler_WorkspaceDidChangeWatchedFiles continue; entry = project->entries[it->second]; } - bool is_interactive = - working_files->GetFileByFilename(entry.filename) != nullptr; + IndexMode mode = + working_files->GetFileByFilename(entry.filename) != nullptr + ? IndexMode::Normal + : IndexMode::NonInteractive; switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - pipeline::Index(path, entry.args, is_interactive); - if (is_interactive) + pipeline::Index(path, entry.args, mode); + if (mode == IndexMode::Normal) clang_complete->NotifySave(path); break; } case lsFileChangeType::Deleted: - pipeline::Index(path, entry.args, is_interactive); + pipeline::Index(path, entry.args, mode); break; } } diff --git a/src/pipeline.cc b/src/pipeline.cc index 89eca5662..c9f5c3709 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -78,7 +78,7 @@ namespace { struct Index_Request { std::string path; std::vector args; - bool is_interactive; + IndexMode mode; lsRequestId id; }; @@ -158,6 +158,7 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, if (!opt_request) return false; auto &request = *opt_request; + bool loud = request.mode != IndexMode::OnChange; // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { @@ -168,7 +169,7 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, } if (std::string reason; !matcher.IsMatch(request.path, &reason)) { - LOG_S(INFO) << "skip " << request.path << " for " << reason; + LOG_IF_S(INFO, loud) << "skip " << request.path << " for " << reason; return false; } @@ -191,6 +192,8 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, if (!write_time) return true; int reparse = vfs->Stamp(path_to_index, *write_time); + if (g_config->index.onChange) + reparse = 2; if (!vfs->Mark(path_to_index, g_thread_id, 1) && !reparse) return true; @@ -226,21 +229,29 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack(std::move(update), request.is_interactive); + on_indexed->PushBack(std::move(update), + request.mode != IndexMode::NonInteractive); } for (const auto &dep : dependencies) if (vfs->Mark(dep.first().str(), 0, 2) && (prev = RawCacheLoad(dep.first().str()))) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack(std::move(update), request.is_interactive); + on_indexed->PushBack(std::move(update), + request.mode != IndexMode::NonInteractive); } return true; } - LOG_S(INFO) << "parse " << path_to_index; + LOG_IF_S(INFO, loud) << "parse " << path_to_index; + std::vector> remapped; + if (g_config->index.onChange) { + std::string content = working_files->GetContent(request.path); + if (content.size()) + remapped.emplace_back(request.path, content); + } auto indexes = - idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); + idx::Index(vfs, entry.directory, path_to_index, entry.args, remapped); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -259,16 +270,15 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; if (std::string reason; !matcher.IsMatch(path, &reason)) { - LOG_S(INFO) << "skip emitting and storing index of " << path << " for " - << reason; + LOG_IF_S(INFO, loud) << "skip emitting and storing index of " << path << " for " + << reason; continue; } - LOG_S(INFO) << "emit index for " << path; + LOG_IF_S(INFO, loud) << "emit index for " << path; prev = RawCacheLoad(path); // Write current index to disk if requested. - LOG_S(INFO) << "store index for " << path; { std::string cache_path = GetCachePath(path); WriteToFile(cache_path, curr->file_contents); @@ -285,9 +295,11 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, // Build delta update. IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); - LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; + LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev + << ")"; - on_indexed->PushBack(std::move(update), request.is_interactive); + on_indexed->PushBack(std::move(update), + request.mode != IndexMode::NonInteractive); } return true; @@ -340,12 +352,14 @@ void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { auto &def_u = *update->files_def_update; - LOG_S(INFO) << "apply index for " << def_u.first.path; - if (WorkingFile *working_file = + if (WorkingFile *wfile = working_files->GetFileByFilename(def_u.first.path)) { - working_file->SetIndexContent(def_u.second); - EmitSkippedRanges(working_file, def_u.first.skipped_ranges); - EmitSemanticHighlighting(db, semantic_cache, working_file, + // FIXME With index.onChange: true, use buffer_content only for + // request.path + wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content + : def_u.second); + EmitSkippedRanges(wfile, def_u.first.skipped_ranges); + EmitSemanticHighlighting(db, semantic_cache, wfile, &db->files[update->file_id]); } } @@ -492,8 +506,8 @@ void MainLoop() { } void Index(const std::string &path, const std::vector &args, - bool interactive, lsRequestId id) { - index_request->PushBack({path, args, interactive, id}, interactive); + IndexMode mode, lsRequestId id) { + index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } std::optional LoadCachedFileContents(const std::string &path) { diff --git a/src/pipeline.hh b/src/pipeline.hh index d3c7dcf4f..3ad966361 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -26,8 +26,14 @@ class DiagnosticsPublisher { std::vector diagnostics); }; -namespace ccls::pipeline { +namespace ccls { +enum class IndexMode { + NonInteractive, + OnChange, + Normal, +}; +namespace pipeline { void Init(); void LaunchStdin(); void LaunchStdout(); @@ -37,11 +43,10 @@ void Indexer_Main(DiagnosticsPublisher* diag_pub, WorkingFiles* working_files); void MainLoop(); -void Index(const std::string& path, - const std::vector& args, - bool is_interactive, - lsRequestId id = {}); +void Index(const std::string &path, const std::vector &args, + IndexMode mode, lsRequestId id = {}); std::optional LoadCachedFileContents(const std::string& path); void WriteStdout(MethodType method, lsBaseOutMessage& response); } +} diff --git a/src/project.cc b/src/project.cc index c25e97c9b..173ec597d 100644 --- a/src/project.cc +++ b/src/project.cc @@ -460,10 +460,12 @@ void Project::ForAllFilteredFiles( void Project::Index(WorkingFiles *wfiles, lsRequestId id) { ForAllFilteredFiles([&](int i, const Project::Entry &entry) { - bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - pipeline::Index(entry.filename, entry.args, is_interactive, id); + bool interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; + pipeline::Index(entry.filename, entry.args, + interactive ? IndexMode::Normal : IndexMode::NonInteractive, + id); }); // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - pipeline::Index("", {}, false); + pipeline::Index("", {}, IndexMode::NonInteractive); } From 58191fd33536cca23c25e1008f04e96b516e5f77 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 8 Sep 2018 10:37:48 -0700 Subject: [PATCH 198/378] Support empty cacheDirectory and fix cache load --- src/clang_complete.cc | 7 ++- src/clang_tu.cc | 1 + src/config.h | 14 +++--- src/file_consumer.h | 1 + src/indexer.cc | 14 ++---- src/indexer.h | 3 +- src/messages/ccls_freshenIndex.cc | 3 +- src/messages/initialize.cc | 19 ++++---- src/messages/textDocument_didChange.cc | 12 ++--- src/messages/textDocument_didOpen.cc | 2 +- src/pipeline.cc | 62 +++++++++++++++++++++----- src/pipeline.hh | 9 ++-- src/serializer.cc | 2 +- src/utils.cc | 15 ++----- src/utils.h | 1 - 15 files changed, 97 insertions(+), 68 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index a5456c53d..9f9b671f7 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -573,7 +573,6 @@ void CompletionMain(ClangCompleteManager *completion_manager) { BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; - CI->getDiagnosticOpts().IgnoreWarnings = true; clang::CodeCompleteOptions CCOpts; CCOpts.IncludeBriefComments = true; #if LLVM_VERSION_MAJOR >= 7 @@ -612,8 +611,6 @@ void DiagnosticMain(ClangCompleteManager *manager) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = manager->diagnostic_request_.Dequeue(); - if (!g_config->diagnostics.onChange) - continue; std::string path = request.document.uri.GetPath(); std::shared_ptr session = manager->TryGetSession( @@ -623,7 +620,8 @@ void DiagnosticMain(ClangCompleteManager *manager) { BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; - CI->getLangOpts()->SpellChecking = true; + CI->getDiagnosticOpts().IgnoreWarnings = false; + CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; StoreDiags DC; WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); @@ -680,6 +678,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; + CI.getDiagnosticOpts().IgnoreWarnings = false; CI.getFrontendOpts().SkipFunctionBodies = true; CI.getLangOpts()->CommentOpts.ParseAllComments = true; #if LLVM_VERSION_MAJOR >= 7 diff --git a/src/clang_tu.cc b/src/clang_tu.cc index be2f16793..d4646705b 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -75,6 +75,7 @@ BuildCompilerInvocation(const std::vector &args, std::unique_ptr CI = createInvocationFromCommandLine(cargs, Diags, VFS); if (CI) { + CI->getDiagnosticOpts().IgnoreWarnings = true; CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->SpellChecking = false; } diff --git a/src/config.h b/src/config.h index 79e7ee75c..ae234f727 100644 --- a/src/config.h +++ b/src/config.h @@ -21,14 +21,7 @@ limitations under the License. /* The language client plugin needs to send initialization options in the -`initialize` request to the ccls language server. The only required option is -`cacheDirectory`, which is where index files will be stored. - - { - "initializationOptions": { - "cacheDirectory": "/tmp/ccls" - } - } +`initialize` request to the ccls language server. If necessary, the command line option --init can be used to override initialization options specified by the client. For example, in shell syntax: @@ -47,6 +40,7 @@ struct Config { std::string compilationDatabaseDirectory; // Cache directory for indexed files, either absolute or relative to the // project root. + // If empty, cache will be stored in memory. std::string cacheDirectory = ".ccls-cache"; // Cache serialization format. // @@ -54,12 +48,14 @@ struct Config { // printed with jq. // // "binary" uses a compact binary serialization format. - // It is not schema-aware and you need to re-index whenever a struct + // It is not schema-aware and you need to re-index whenever an internal struct // member has changed. SerializeFormat cacheFormat = SerializeFormat::Binary; struct Clang { // Arguments that should be excluded, e.g. ["-fopenmp", "-Wall"] + // + // e.g. If your project is built by GCC and has an option thag clang does not understand. std::vector excludeArgs; // Additional arguments to pass to clang. diff --git a/src/file_consumer.h b/src/file_consumer.h index b02920845..d2c758946 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -45,6 +45,7 @@ struct VFS { int64_t timestamp; int owner; int stage; + bool loaded = false; }; mutable std::unordered_map state; mutable std::mutex mutex; diff --git a/src/indexer.cc b/src/indexer.cc index 177d4be5e..567dcf50c 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -51,7 +51,7 @@ struct IndexParam { std::unordered_map SeenUniqueID; std::unordered_map UID2multi; std::unordered_map file_contents; - std::unordered_map file2write_time; + std::unordered_map file2mtime; struct DeclInfo { Usr usr; std::string short_name; @@ -71,13 +71,7 @@ struct IndexParam { if (inserted) { std::string file_name = FileName(File); it->second = file_name; - - // Set modification time. - std::optional write_time = LastWriteTime(file_name); - LOG_IF_S(ERROR, !write_time) - << "failed to fetch write time for " << file_name; - if (write_time) - file2write_time[file_name] = *write_time; + file2mtime[file_name] = File.getModificationTime(); } } @@ -1307,13 +1301,13 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, Uniquify(it.second.uses); // Update file contents and modification time. - entry->last_write_time = param.file2write_time[entry->path]; + entry->mtime = param.file2mtime[entry->path]; // Update dependencies for the file. Do not include the file in its own // dependency set. for (auto &[_, path] : param.SeenUniqueID) if (path != entry->path && path != entry->import_file) - entry->dependencies[path] = param.file2write_time[path]; + entry->dependencies[path] = param.file2mtime[path]; } return result; diff --git a/src/indexer.h b/src/indexer.h index dc4fe774d..797b0096a 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -247,7 +247,8 @@ struct IndexFile { llvm::sys::fs::UniqueID UniqueID; std::string path; std::vector args; - int64_t last_write_time = 0; + // This is unfortunately time_t as used by clang::FileEntry + int64_t mtime = 0; LanguageId language = LanguageId::C; // uid2lid_and_path is used to generate lid2path, but not serialized. diff --git a/src/messages/ccls_freshenIndex.cc b/src/messages/ccls_freshenIndex.cc index edf23b4d4..a49e0243a 100644 --- a/src/messages/ccls_freshenIndex.cc +++ b/src/messages/ccls_freshenIndex.cc @@ -69,7 +69,8 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { q.pop(); need_index.insert(file->def->path); - std::optional write_time = LastWriteTime(file->def->path); + std::optional write_time = + pipeline::LastWriteTime(file->def->path); if (!write_time) continue; { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cfbca19ea..fdbfa349d 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -438,10 +438,7 @@ struct Handler_Initialize : BaseMessageHandler { Reflect(json_writer, *g_config); LOG_S(INFO) << "initializationOptions: " << output.GetString(); - if (g_config->cacheDirectory.empty()) { - LOG_S(ERROR) << "cacheDirectory cannot be empty."; - exit(1); - } else { + if (g_config->cacheDirectory.size()) { g_config->cacheDirectory = NormalizePath(g_config->cacheDirectory); EnsureEndsInSlash(g_config->cacheDirectory); } @@ -470,12 +467,14 @@ struct Handler_Initialize : BaseMessageHandler { // Set project root. EnsureEndsInSlash(project_path); g_config->projectRoot = project_path; - // Create two cache directories for files inside and outside of the - // project. - sys::fs::create_directories(g_config->cacheDirectory + - EscapeFileName(g_config->projectRoot)); - sys::fs::create_directories(g_config->cacheDirectory + '@' + - EscapeFileName(g_config->projectRoot)); + if (g_config->cacheDirectory.size()) { + // Create two cache directories for files inside and outside of the + // project. + sys::fs::create_directories(g_config->cacheDirectory + + EscapeFileName(g_config->projectRoot)); + sys::fs::create_directories(g_config->cacheDirectory + '@' + + EscapeFileName(g_config->projectRoot)); + } diag_pub->Init(); idx::Init(); diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index 1704282d7..f010ae04d 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -36,15 +36,17 @@ struct Handler_TextDocumentDidChange MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDidChange *request) override { - std::string path = request->params.textDocument.uri.GetPath(); - working_files->OnChange(request->params); + const auto ¶ms = request->params; + std::string path = params.textDocument.uri.GetPath(); + working_files->OnChange(params); if (g_config->index.onChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); pipeline::Index(entry.filename, entry.args, IndexMode::OnChange); } - clang_complete->NotifyEdit(path); - clang_complete->DiagnosticsUpdate( - request->params.textDocument.AsTextDocumentIdentifier()); + clang_complete->NotifyView(path); + if (g_config->diagnostics.onChange) + clang_complete->DiagnosticsUpdate( + params.textDocument.AsTextDocumentIdentifier()); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index b88d3b947..2dc25c01a 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -53,7 +53,7 @@ struct Handler_TextDocumentDidOpen WorkingFile *working_file = working_files->OnOpen(params.textDocument); if (std::optional cached_file_contents = - pipeline::LoadCachedFileContents(path)) + pipeline::LoadIndexedContent(path)) working_file->SetIndexContent(*cached_file_contents); QueryFile *file = nullptr; diff --git a/src/pipeline.cc b/src/pipeline.cc index c9f5c3709..c973f564c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -95,12 +95,18 @@ ThreadedQueue *index_request; ThreadedQueue *on_indexed; ThreadedQueue *for_stdout; +struct InMemoryIndexFile { + std::string content; + IndexFile index; +}; +std::unordered_map g_index; + bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, const std::vector &args, const std::optional &from) { { std::lock_guard lock(vfs->mutex); - if (prev->last_write_time < vfs->state[path].timestamp) { + if (prev->mtime < vfs->state[path].timestamp) { LOG_S(INFO) << "timestamp changed for " << path << (from ? " (via " + *from + ")" : std::string()); return true; @@ -140,6 +146,13 @@ std::string GetCachePath(const std::string &source_file) { } std::unique_ptr RawCacheLoad(const std::string &path) { + if (g_config->cacheDirectory.empty()) { + auto it = g_index.find(path); + if (it == g_index.end()) + return nullptr; + return std::make_unique(it->second.index); + } + std::string cache_path = GetCachePath(path); std::optional file_content = ReadContent(cache_path); std::optional serialized_indexed_content = @@ -267,7 +280,18 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, for (std::unique_ptr &curr : indexes) { std::string path = curr->path; - if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) + bool do_update = path == path_to_index, loaded; + { + std::lock_guard lock(vfs->mutex); + VFS::State &st = vfs->state[path]; + if (st.timestamp < curr->mtime) { + st.timestamp = curr->mtime; + do_update = true; + } + loaded = st.loaded; + st.loaded = true; + } + if (!do_update) continue; if (std::string reason; !matcher.IsMatch(path, &reason)) { LOG_IF_S(INFO, loud) << "skip emitting and storing index of " << path << " for " @@ -275,15 +299,22 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, continue; } - LOG_IF_S(INFO, loud) << "emit index for " << path; - prev = RawCacheLoad(path); + prev.reset(); + if (loaded) + prev = RawCacheLoad(path); - // Write current index to disk if requested. - { + // Store current index. + LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev + << ")"; + if (g_config->cacheDirectory.empty()) { + auto it = g_index.insert_or_assign( + path, InMemoryIndexFile{curr->file_contents, *curr}); + std::string().swap(it.first->second.index.file_contents); + } else { std::string cache_path = GetCachePath(path); WriteToFile(cache_path, curr->file_contents); WriteToFile(AppendSerializationFormat(cache_path), - Serialize(g_config->cacheFormat, *curr)); + Serialize(g_config->cacheFormat, *curr)); } vfs->Reset(path); @@ -295,8 +326,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, // Build delta update. IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); - LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev - << ")"; on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); @@ -510,7 +539,20 @@ void Index(const std::string &path, const std::vector &args, index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } -std::optional LoadCachedFileContents(const std::string &path) { +std::optional LastWriteTime(const std::string &path) { + sys::fs::file_status Status; + if (sys::fs::status(path, Status)) + return {}; + return sys::toTimeT(Status.getLastModificationTime()); +} + +std::optional LoadIndexedContent(const std::string &path) { + if (g_config->cacheDirectory.empty()) { + auto it = g_index.find(path); + if (it == g_index.end()) + return {}; + return it->second.content; + } return ReadContent(GetCachePath(path)); } diff --git a/src/pipeline.hh b/src/pipeline.hh index 3ad966361..3c49285c2 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -46,7 +46,8 @@ void MainLoop(); void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {}); -std::optional LoadCachedFileContents(const std::string& path); -void WriteStdout(MethodType method, lsBaseOutMessage& response); -} -} +std::optional LastWriteTime(const std::string &path); +std::optional LoadIndexedContent(const std::string& path); +void WriteStdout(MethodType method, lsBaseOutMessage &response); +} // namespace pipeline +} // namespace ccls diff --git a/src/serializer.cc b/src/serializer.cc index 487650b0a..41c10d9a5 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -309,7 +309,7 @@ bool ReflectMemberStart(Writer &visitor, IndexFile &value) { template void Reflect(TVisitor &visitor, IndexFile &value) { REFLECT_MEMBER_START(); if (!gTestOutputMode) { - REFLECT_MEMBER(last_write_time); + REFLECT_MEMBER(mtime); REFLECT_MEMBER(language); REFLECT_MEMBER(lid2path); REFLECT_MEMBER(import_file); diff --git a/src/utils.cc b/src/utils.cc index 36a7e0e4d..df5b98c8f 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -15,13 +15,13 @@ limitations under the License. #include "utils.h" -#include "filesystem.hh" -using namespace llvm; #include "log.hh" #include "platform.h" #include +#include "llvm/ADT/StringRef.h" + #include #include #include @@ -29,7 +29,6 @@ using namespace llvm; #include #include #include -using namespace std::placeholders; void TrimInPlace(std::string &s) { auto f = [](char c) { return !isspace(c); }; @@ -69,7 +68,8 @@ bool StartsWith(std::string_view s, std::string_view prefix) { } bool EndsWithAny(std::string_view s, const std::vector &ss) { - return std::any_of(ss.begin(), ss.end(), std::bind(EndsWith, s, _1)); + return std::any_of(ss.begin(), ss.end(), + std::bind(EndsWith, s, std::placeholders::_1)); } bool FindAnyPartial(const std::string &value, @@ -147,13 +147,6 @@ void WriteToFile(const std::string &filename, const std::string &content) { fclose(f); } -std::optional LastWriteTime(const std::string &filename) { - sys::fs::file_status Status; - if (sys::fs::status(filename, Status)) - return {}; - return Status.getLastModificationTime().time_since_epoch().count(); -} - // Find discontinous |search| in |content|. // Return |found| and the count of skipped chars before found. int ReverseSubseqMatch(std::string_view pat, std::string_view text, diff --git a/src/utils.h b/src/utils.h index 973243fd9..40352e1af 100644 --- a/src/utils.h +++ b/src/utils.h @@ -75,7 +75,6 @@ std::string EscapeFileName(std::string path); std::optional ReadContent(const std::string &filename); void WriteToFile(const std::string &filename, const std::string &content); -std::optional LastWriteTime(const std::string &filename); int ReverseSubseqMatch(std::string_view pat, std::string_view text, int case_sensitivity); From da982a6506fccef9c947f1825d8a05abbe7c9d97 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 8 Sep 2018 12:07:43 -0700 Subject: [PATCH 199/378] Reuse preamble (built by "comp-preload") in indexer --- src/clang_complete.cc | 86 ++++++++----------- src/{clang_complete.h => clang_complete.hh} | 20 ++--- src/config.h | 4 +- src/indexer.cc | 37 ++++++-- src/indexer.h | 10 ++- src/message_handler.h | 4 +- src/messages/initialize.cc | 4 +- src/messages/textDocument_codeLens.cc | 2 +- src/messages/textDocument_completion.cc | 6 +- src/messages/textDocument_didChange.cc | 2 +- src/messages/textDocument_didClose.cc | 2 +- src/messages/textDocument_didOpen.cc | 2 +- src/messages/textDocument_didSave.cc | 2 +- src/messages/textDocument_signatureHelp.cc | 4 +- .../workspace_didChangeConfiguration.cc | 2 +- .../workspace_didChangeWatchedFiles.cc | 2 +- src/pipeline.cc | 19 ++-- src/pipeline.hh | 8 +- src/test.cc | 7 +- 19 files changed, 121 insertions(+), 102 deletions(-) rename src/{clang_complete.h => clang_complete.hh} (91%) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 9f9b671f7..f6a848201 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "clang_utils.h" #include "filesystem.hh" @@ -525,7 +525,7 @@ bool Parse(CompilerInstance &Clang) { return true; } -void CompletionPreloadMain(ClangCompleteManager *completion_manager) { +void CompletionPreloadMain(CompletionManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. auto request = completion_manager->preload_requests_.Dequeue(); @@ -550,10 +550,10 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) { } } -void CompletionMain(ClangCompleteManager *completion_manager) { +void CompletionMain(CompletionManager *completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. - std::unique_ptr request = + std::unique_ptr request = completion_manager->completion_request_.Dequeue(); // Drop older requests if we're not buffering. @@ -606,10 +606,10 @@ void CompletionMain(ClangCompleteManager *completion_manager) { } } -void DiagnosticMain(ClangCompleteManager *manager) { +void DiagnosticMain(CompletionManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. - ClangCompleteManager::DiagnosticRequest request = + CompletionManager::DiagnosticRequest request = manager->diagnostic_request_.Dequeue(); std::string path = request.document.uri.GetPath(); @@ -699,10 +699,10 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { } // namespace ccls -ClangCompleteManager::ClangCompleteManager(Project *project, - WorkingFiles *working_files, - OnDiagnostic on_diagnostic, - OnDropped on_dropped) +CompletionManager::CompletionManager(Project *project, + WorkingFiles *working_files, + OnDiagnostic on_diagnostic, + OnDropped on_dropped) : project_(project), working_files_(working_files), on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), preloaded_sessions_(kMaxPreloadedSessions), @@ -725,7 +725,7 @@ ClangCompleteManager::ClangCompleteManager(Project *project, .detach(); } -void ClangCompleteManager::CodeComplete( +void CompletionManager::CodeComplete( const lsRequestId &id, const lsTextDocumentPositionParams &completion_location, const OnComplete &on_complete) { @@ -734,7 +734,7 @@ void ClangCompleteManager::CodeComplete( on_complete)); } -void ClangCompleteManager::DiagnosticsUpdate( +void CompletionManager::DiagnosticsUpdate( const lsTextDocumentIdentifier &document) { bool has = false; diagnostic_request_.Iterate([&](const DiagnosticRequest &request) { @@ -746,29 +746,13 @@ void ClangCompleteManager::DiagnosticsUpdate( true /*priority*/); } -void ClangCompleteManager::NotifyView(const std::string &filename) { - // - // On view, we reparse only if the file has not been parsed. The existence of - // a CompletionSession instance implies the file is already parsed or will be - // parsed soon. - // - +void CompletionManager::NotifyView(const std::string &path) { // Only reparse the file if we create a new CompletionSession. - if (EnsureCompletionOrCreatePreloadSession(filename)) - preload_requests_.PushBack(PreloadRequest(filename), true); -} - -void ClangCompleteManager::NotifyEdit(const std::string &filename) { - // - // We treat an edit like a view, because the completion logic will handle - // moving the CompletionSession instance from preloaded to completion - // storage. - // - - NotifyView(filename); + if (EnsureCompletionOrCreatePreloadSession(path)) + preload_requests_.PushBack(PreloadRequest(path), true); } -void ClangCompleteManager::NotifySave(const std::string &filename) { +void CompletionManager::NotifySave(const std::string &filename) { // // On save, always reparse. // @@ -777,7 +761,7 @@ void ClangCompleteManager::NotifySave(const std::string &filename) { preload_requests_.PushBack(PreloadRequest(filename), true); } -void ClangCompleteManager::NotifyClose(const std::string &filename) { +void CompletionManager::NotifyClose(const std::string &filename) { // // On close, we clear any existing CompletionSession instance. // @@ -797,63 +781,63 @@ void ClangCompleteManager::NotifyClose(const std::string &filename) { assert((preloaded_ptr && completion_ptr) == false); } -bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( - const std::string &filename) { +bool CompletionManager::EnsureCompletionOrCreatePreloadSession( + const std::string &path) { std::lock_guard lock(sessions_lock_); // Check for an existing CompletionSession. - if (preloaded_sessions_.TryGet(filename) || - completion_sessions_.TryGet(filename)) { + if (preloaded_sessions_.TryGet(path) || + completion_sessions_.TryGet(path)) { return false; } // No CompletionSession, create new one. auto session = std::make_shared( - project_->FindCompilationEntryForFile(filename), working_files_, PCH); + project_->FindCompilationEntryForFile(path), working_files_, PCH); preloaded_sessions_.Insert(session->file.filename, session); return true; } std::shared_ptr -ClangCompleteManager::TryGetSession(const std::string &filename, - bool mark_as_completion, - bool create_if_needed) { +CompletionManager::TryGetSession(const std::string &path, + bool mark_as_completion, + bool create_if_needed) { std::lock_guard lock(sessions_lock_); // Try to find a preloaded session. std::shared_ptr preloaded = - preloaded_sessions_.TryGet(filename); + preloaded_sessions_.TryGet(path); if (preloaded) { // If this request is for a completion, we should move it to // |completion_sessions|. if (mark_as_completion) { - preloaded_sessions_.TryTake(filename); - completion_sessions_.Insert(filename, preloaded); + preloaded_sessions_.TryTake(path); + completion_sessions_.Insert(path, preloaded); } return preloaded; } // Try to find a completion session. If none create one. std::shared_ptr session = - completion_sessions_.TryGet(filename); + completion_sessions_.TryGet(path); if (!session && create_if_needed) { session = std::make_shared( - project_->FindCompilationEntryForFile(filename), working_files_, PCH); - completion_sessions_.Insert(filename, session); + project_->FindCompilationEntryForFile(path), working_files_, PCH); + completion_sessions_.Insert(path, session); } return session; } -void ClangCompleteManager::FlushSession(const std::string &filename) { +void CompletionManager::FlushSession(const std::string &path) { std::lock_guard lock(sessions_lock_); - preloaded_sessions_.TryTake(filename); - completion_sessions_.TryTake(filename); + preloaded_sessions_.TryTake(path); + completion_sessions_.TryTake(path); } -void ClangCompleteManager::FlushAllSessions() { +void CompletionManager::FlushAllSessions() { LOG_S(INFO) << "flush all clang complete sessions"; std::lock_guard lock(sessions_lock_); diff --git a/src/clang_complete.h b/src/clang_complete.hh similarity index 91% rename from src/clang_complete.h rename to src/clang_complete.hh index 92716e418..94e9fc36d 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.hh @@ -76,7 +76,7 @@ struct CompletionSession }; } -struct ClangCompleteManager { +struct CompletionManager { using OnDiagnostic = std::function diagnostics)>; using OnComplete = std::function - TryGetSession(const std::string &filename, bool mark_as_completion, + TryGetSession(const std::string &path, bool mark_as_completion, bool create_if_needed); // Flushes all saved sessions with the supplied filename - void FlushSession(const std::string &filename); + void FlushSession(const std::string &path); // Flushes all saved sessions void FlushAllSessions(void); diff --git a/src/config.h b/src/config.h index ae234f727..565c671c1 100644 --- a/src/config.h +++ b/src/config.h @@ -154,6 +154,8 @@ struct Config { // If true, diagnostics will be reported for textDocument/didOpen. bool onOpen = true; + bool spellChecking = true; + std::vector whitelist; } diagnostics; @@ -238,7 +240,7 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, - onOpen, whitelist) + onOpen, spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, diff --git a/src/indexer.cc b/src/indexer.cc index 567dcf50c..55586691e 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -15,12 +15,13 @@ limitations under the License. #include "indexer.h" +#include "clang_complete.hh" #include "clang_tu.h" #include "log.hh" #include "match.h" #include "platform.h" #include "serializer.h" -using ccls::Intern; +using namespace ccls; #include #include @@ -1195,7 +1196,8 @@ void Init() { } std::vector> -Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, +Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, + const std::string &opt_wdir, const std::string &file, const std::vector &args, const std::vector> &remapped) { if (!g_config->index.enabled) @@ -1221,13 +1223,32 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, // HSOpts.UseBuiltinIncludes) // HSOpts.ResourceDir = g_config->clang.resourceDir; } + std::string buf = wfiles->GetContent(file); std::vector> Bufs; - for (auto &[filename, content] : remapped) { - Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); - CI->getPreprocessorOpts().addRemappedFile( - filename == file ? CI->getFrontendOpts().Inputs[0].getFile() - : StringRef(filename), - Bufs.back().get()); + if (buf.size()) { + // If there is a completion session, reuse its preamble if exists. + bool done_remap = false; + std::shared_ptr session = + completion->TryGetSession(file, false, false); + if (session) + if (auto preamble = session->GetPreamble()) { + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(buf)); + auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), Bufs.back().get(), 0); + if (preamble->Preamble.CanReuse(*CI, Bufs.back().get(), Bounds, + FS.get())) { + preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get()); + done_remap = true; + } + } + for (auto &[filename, content] : remapped) { + if (filename == file && done_remap) + continue; + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); + CI->getPreprocessorOpts().addRemappedFile( + filename == file ? CI->getFrontendOpts().Inputs[0].getFile() + : StringRef(filename), + Bufs.back().get()); + } } DiagnosticConsumer DC; diff --git a/src/indexer.h b/src/indexer.h index 797b0096a..ab20ba305 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -284,10 +284,14 @@ struct IndexFile { std::string ToString(); }; +struct CompletionManager; +struct WorkingFiles; + namespace ccls::idx { void Init(); std::vector> -Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, +Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, + const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector>& remapped); -} // namespace ccls::idx + const std::vector> &remapped); +} diff --git a/src/message_handler.h b/src/message_handler.h index 99da9d309..3d314222d 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -26,7 +26,7 @@ limitations under the License. #include #include -struct ClangCompleteManager; +struct CompletionManager; struct CodeCompleteCache; struct Config; class DiagnosticsPublisher; @@ -119,7 +119,7 @@ struct MessageHandler { ImportManager *import_manager = nullptr; SemanticHighlightSymbolCache *semantic_cache = nullptr; WorkingFiles *working_files = nullptr; - ClangCompleteManager *clang_complete = nullptr; + CompletionManager *clang_complete = nullptr; IncludeComplete *include_complete = nullptr; CodeCompleteCache *global_code_complete_cache = nullptr; CodeCompleteCache *non_global_code_complete_cache = nullptr; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index fdbfa349d..332f8c5b5 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "clang_complete.hh" #include "filesystem.hh" #include "include_complete.h" #include "log.hh" @@ -495,7 +496,8 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); - pipeline::Indexer_Main(diag_pub, vfs, project, working_files); + pipeline::Indexer_Main(clang_complete, diag_pub, vfs, project, + working_files); }) .detach(); } diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index 730441e74..ccf235fda 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "lsp_code_action.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 9582b5784..78383969a 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "fuzzy_match.h" #include "include_complete.h" #include "message_handler.h" @@ -380,7 +380,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { pipeline::WriteStdout(kMethodType, out); } else { - ClangCompleteManager::OnComplete callback = std::bind( + CompletionManager::OnComplete callback = std::bind( [this, request, params, is_global_completion, existing_completion, has_open_paren](const std::vector &results, bool is_cached_result) { @@ -420,7 +420,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { !global_code_complete_cache->cached_results_.empty(); }); if (is_cache_match) { - ClangCompleteManager::OnComplete freshen_global = + CompletionManager::OnComplete freshen_global = [this](std::vector results, bool is_cached_result) { assert(!is_cached_result); diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index f010ae04d..5b50714c8 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" #include "project.h" diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index 8187ee7dc..8e3f504fb 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" #include "working_files.h" diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 2dc25c01a..146c22c0c 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "include_complete.h" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 023d1bb39..0badb21c1 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" #include "project.h" diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 8799a5424..1a763e218 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" using namespace ccls; @@ -114,7 +114,7 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { if (search.empty()) return; - ClangCompleteManager::OnComplete callback = std::bind( + CompletionManager::OnComplete callback = std::bind( [this](InMessage *message, std::string search, int active_param, const std::vector &results, bool is_cached_result) { diff --git a/src/messages/workspace_didChangeConfiguration.cc b/src/messages/workspace_didChangeConfiguration.cc index eb5b2d887..9b9ba474b 100644 --- a/src/messages/workspace_didChangeConfiguration.cc +++ b/src/messages/workspace_didChangeConfiguration.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" #include "project.h" diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index b2c3eef59..5d8728597 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.h" +#include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" #include "project.h" diff --git a/src/pipeline.cc b/src/pipeline.cc index c973f564c..ffab9e296 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -15,7 +15,7 @@ limitations under the License. #include "pipeline.hh" -#include "clang_complete.h" +#include "clang_complete.hh" #include "config.h" #include "include_complete.h" #include "log.hh" @@ -165,7 +165,8 @@ std::unique_ptr RawCacheLoad(const std::string &path) { IndexFile::kMajorVersion); } -bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, +bool Indexer_Parse(CompletionManager *completion, + DiagnosticsPublisher *diag_pub, WorkingFiles *wfiles, Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) @@ -259,12 +260,12 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, std::vector> remapped; if (g_config->index.onChange) { - std::string content = working_files->GetContent(request.path); + std::string content = wfiles->GetContent(request.path); if (content.size()) remapped.emplace_back(request.path, content); } - auto indexes = - idx::Index(vfs, entry.directory, path_to_index, entry.args, remapped); + auto indexes = idx::Index(completion, wfiles, vfs, entry.directory, + path_to_index, entry.args, remapped); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -348,11 +349,13 @@ void Init() { for_stdout = new ThreadedQueue(stdout_waiter); } -void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, +void Indexer_Main(CompletionManager *completion, + DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, WorkingFiles *working_files) { GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); while (true) - if (!Indexer_Parse(diag_pub, working_files, project, vfs, matcher)) + if (!Indexer_Parse(completion, diag_pub, working_files, project, vfs, + matcher)) indexer_waiter->Wait(index_request); } @@ -464,7 +467,7 @@ void MainLoop() { VFS vfs; DiagnosticsPublisher diag_pub; - ClangCompleteManager clang_complete( + CompletionManager clang_complete( &project, &working_files, [&](std::string path, std::vector diagnostics) { diag_pub.Publish(&working_files, path, diagnostics); diff --git a/src/pipeline.hh b/src/pipeline.hh index 3c49285c2..da9bfc9e0 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -8,6 +8,7 @@ #include #include +struct CompletionManager; struct GroupMatch; struct VFS; struct Project; @@ -37,10 +38,9 @@ namespace pipeline { void Init(); void LaunchStdin(); void LaunchStdout(); -void Indexer_Main(DiagnosticsPublisher* diag_pub, - VFS* vfs, - Project* project, - WorkingFiles* working_files); +void Indexer_Main(CompletionManager *complete, + DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, + WorkingFiles *working_files); void MainLoop(); void Index(const std::string &path, const std::vector &args, diff --git a/src/test.cc b/src/test.cc index b93a21b99..19d52a9e6 100644 --- a/src/test.cc +++ b/src/test.cc @@ -15,6 +15,7 @@ limitations under the License. #include "test.h" +#include "clang_complete.hh" #include "filesystem.hh" #include "indexer.h" #include "platform.h" @@ -301,7 +302,11 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { // Run test. g_config = new Config; VFS vfs; - auto dbs = ccls::idx::Index(&vfs, "", path, flags, {}); + CompletionManager completion( + nullptr, nullptr, [&](std::string, std::vector) {}, + [](lsRequestId id) {}); + WorkingFiles wfiles; + auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, flags, {}); for (const auto &entry : all_expected_output) { const std::string &expected_path = entry.first; From 92ee7f3e0fbad1b23e125abda42abcfc9206cf7a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 8 Sep 2018 16:00:14 -0700 Subject: [PATCH 200/378] Add diagnostics.onSave --- src/config.h | 5 ++++- src/messages/initialize.cc | 3 +-- src/messages/textDocument_didSave.cc | 2 ++ src/pipeline.cc | 11 ++++------- src/pipeline.hh | 5 ++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/config.h b/src/config.h index 565c671c1..310d8dba7 100644 --- a/src/config.h +++ b/src/config.h @@ -154,6 +154,9 @@ struct Config { // If true, diagnostics will be reported for textDocument/didOpen. bool onOpen = true; + // If true, diagnostics will be reported for textDocument/didSave. + bool onSave = true; + bool spellChecking = true; std::vector whitelist; @@ -240,7 +243,7 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, - onOpen, spellChecking, whitelist) + onOpen, onSave, spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 332f8c5b5..c4516ef13 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -496,8 +496,7 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); - pipeline::Indexer_Main(clang_complete, diag_pub, vfs, project, - working_files); + pipeline::Indexer_Main(clang_complete, vfs, project, working_files); }) .detach(); } diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 0badb21c1..08520a92e 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -49,6 +49,8 @@ struct Handler_TextDocumentDidSave Project::Entry entry = project->FindCompilationEntryForFile(path); pipeline::Index(entry.filename, entry.args, IndexMode::Normal); clang_complete->NotifySave(path); + if (g_config->diagnostics.onSave) + clang_complete->DiagnosticsUpdate(params.textDocument); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); diff --git a/src/pipeline.cc b/src/pipeline.cc index ffab9e296..e6df6fd9b 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -165,8 +165,7 @@ std::unique_ptr RawCacheLoad(const std::string &path) { IndexFile::kMajorVersion); } -bool Indexer_Parse(CompletionManager *completion, - DiagnosticsPublisher *diag_pub, WorkingFiles *wfiles, +bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) @@ -349,13 +348,11 @@ void Init() { for_stdout = new ThreadedQueue(stdout_waiter); } -void Indexer_Main(CompletionManager *completion, - DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, - WorkingFiles *working_files) { +void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, + WorkingFiles *wfiles) { GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); while (true) - if (!Indexer_Parse(completion, diag_pub, working_files, project, vfs, - matcher)) + if (!Indexer_Parse(completion, wfiles, project, vfs, matcher)) indexer_waiter->Wait(index_request); } diff --git a/src/pipeline.hh b/src/pipeline.hh index da9bfc9e0..6e311d5ca 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -38,9 +38,8 @@ namespace pipeline { void Init(); void LaunchStdin(); void LaunchStdout(); -void Indexer_Main(CompletionManager *complete, - DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, - WorkingFiles *working_files); +void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, + WorkingFiles *wfiles); void MainLoop(); void Index(const std::string &path, const std::vector &args, From c202dd3775b1b563943c7e31726c9b2dcea2bead Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 8 Sep 2018 17:49:52 -0700 Subject: [PATCH 201/378] Make CXXConversion references wider; use getTypedefNameForAnonDecl; improve CXXDestructor CXXConversion spell --- index_tests/constructors/destructor.cc | 2 +- .../inheritance/multiple_base_functions.cc | 6 +-- src/indexer.cc | 42 +++++++++++++++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 3bb394d20..97207f379 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -56,7 +56,7 @@ void foo() { "kind": 6, "storage": 0, "declarations": [], - "spell": "4:3-4:4|15041163540773201510|2|1026|-1", + "spell": "4:3-4:7|15041163540773201510|2|1026|-1", "extent": "4:3-4:12|15041163540773201510|2|0|-1", "bases": [], "derived": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 117194751..76cd27eef 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -21,7 +21,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:12|15826803741381445676|2|1090|-1", + "spell": "5:11-5:17|15826803741381445676|2|1090|-1", "extent": "5:3-5:23|15826803741381445676|2|0|-1", "bases": [], "derived": [], @@ -36,7 +36,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "8:3-8:4|10963370434658308541|2|5186|-1", + "spell": "8:3-8:11|10963370434658308541|2|5186|-1", "extent": "8:3-8:26|10963370434658308541|2|0|-1", "bases": [], "derived": [], @@ -51,7 +51,7 @@ struct Derived : Base0, Base1 { "kind": 6, "storage": 0, "declarations": [], - "spell": "2:11-2:12|11628904180681204356|2|1090|-1", + "spell": "2:11-2:17|11628904180681204356|2|1090|-1", "extent": "2:3-2:23|11628904180681204356|2|0|-1", "bases": [], "derived": [], diff --git a/src/indexer.cc b/src/indexer.cc index 55586691e..3d9e2d67a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -675,6 +675,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexParam::DeclInfo *info; Usr usr = GetUsr(D, &info); + if (is_def) + switch (OrigD->getKind()) { + case Decl::CXXConversion: // *operator* int => *operator int* + case Decl::CXXDestructor: // *~*A => *~A* + if (Loc.isFileID()) { + SourceRange R = + cast(OrigD)->getNameInfo().getSourceRange(); + if (R.getEnd().isFileID()) + loc = FromTokenRange(SM, Lang, R); + } + break; + default: + break; + } + auto do_def_decl = [&](auto *entity) { if (is_def) { entity->def.spell = GetUse(db, lid, loc, SemDC, role); @@ -704,8 +719,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; case SymbolKind::Func: func = &db->ToFunc(usr); - // Span one more column to the left/right if D is CXXConstructor. - if (!is_def && !is_decl && D->getKind() == Decl::CXXConstructor) + // Mark as Role::Implicit to span one more column to the left/right. + if (!is_def && !is_decl && + (D->getKind() == Decl::CXXConstructor || + D->getKind() == Decl::CXXConversion)) role = Role(role | Role::Implicit); do_def_decl(func); if (Spell != Loc) @@ -728,7 +745,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { do_def_decl(type); if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); - if (type->def.detailed_name[0] == '\0') + if (type->def.detailed_name[0] == '\0' && info->short_name.size()) SetName(OrigD, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); @@ -885,6 +902,25 @@ class IndexDataConsumer : public index::IndexDataConsumer { // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; + if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) { + if (TypedefNameDecl *TD = RD->getTypedefNameForAnonDecl()) { + StringRef Name = TD->getName(); + StringRef Tag; + switch (RD->getTagKind()) { + case TTK_Struct: Tag = "struct "; break; + case TTK_Interface: Tag = "__interface "; break; + case TTK_Union: Tag = "union "; break; + case TTK_Class: Tag = "class "; break; + case TTK_Enum: Tag = "enum "; break; + } + std::string name = ("anon " + Tag + Name).str(); + type->def.detailed_name = Intern(name); + type->def.short_name_size = name.size(); + } else { + // e.g. "struct {}" + SetName(OrigD, "", "", type->def); + } + } if (is_def) { SmallVector, 2> Stack{{RD, 0}}; llvm::DenseSet Seen; From a7c1633b519e3b6ee16f8bca302fea0043333f94 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 9 Sep 2018 23:46:13 -0700 Subject: [PATCH 202/378] Misc --- src/indexer.cc | 2 +- src/message_handler.cc | 4 ++-- src/messages/workspace_didChangeWatchedFiles.cc | 4 ++-- src/pipeline.cc | 12 +++++++++--- src/project.cc | 16 ++++++++++++---- src/project.h | 2 +- src/query.cc | 17 +++++++++++------ 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 3d9e2d67a..a29988c92 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1261,7 +1261,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, } std::string buf = wfiles->GetContent(file); std::vector> Bufs; - if (buf.size()) { + if (g_config->index.onChange && buf.size()) { // If there is a completion session, reuse its preamble if exists. bool done_remap = false; std::shared_ptr session = diff --git a/src/message_handler.cc b/src/message_handler.cc index f4d6aae03..ab6d937b6 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -160,8 +160,8 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, bool indexing; { std::lock_guard lock(project->mutex_); - indexing = project->absolute_path_to_entry_index_.find(absolute_path) != - project->absolute_path_to_entry_index_.end(); + indexing = project->path_to_entry_index.find(absolute_path) != + project->path_to_entry_index.end(); } if (indexing) LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index 5d8728597..8ba464083 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -57,8 +57,8 @@ struct Handler_WorkspaceDidChangeWatchedFiles Project::Entry entry; { std::lock_guard lock(project->mutex_); - auto it = project->absolute_path_to_entry_index_.find(path); - if (it == project->absolute_path_to_entry_index_.end()) + auto it = project->path_to_entry_index.find(path); + if (it == project->path_to_entry_index.end()) continue; entry = project->entries[it->second]; } diff --git a/src/pipeline.cc b/src/pipeline.cc index e6df6fd9b..31ae2a2a8 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -32,6 +32,8 @@ limitations under the License. using namespace llvm; #include +#include +#include #include #ifndef _WIN32 #include @@ -99,6 +101,7 @@ struct InMemoryIndexFile { std::string content; IndexFile index; }; +std::shared_mutex g_index_mutex; std::unordered_map g_index; bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, @@ -147,6 +150,7 @@ std::string GetCachePath(const std::string &source_file) { std::unique_ptr RawCacheLoad(const std::string &path) { if (g_config->cacheDirectory.empty()) { + std::shared_lock lock(g_index_mutex); auto it = g_index.find(path); if (it == g_index.end()) return nullptr; @@ -189,8 +193,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, Project::Entry entry; { std::lock_guard lock(project->mutex_); - auto it = project->absolute_path_to_entry_index_.find(request.path); - if (it != project->absolute_path_to_entry_index_.end()) + auto it = project->path_to_entry_index.find(request.path); + if (it != project->path_to_entry_index.end()) entry = project->entries[it->second]; else { entry.filename = request.path; @@ -307,6 +311,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev << ")"; if (g_config->cacheDirectory.empty()) { + std::lock_guard lock(g_index_mutex); auto it = g_index.insert_or_assign( path, InMemoryIndexFile{curr->file_contents, *curr}); std::string().swap(it.first->second.index.file_contents); @@ -321,7 +326,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (entry.id >= 0) { std::lock_guard lock(project->mutex_); for (auto &dep : curr->dependencies) - project->absolute_path_to_entry_index_[dep.first()] = entry.id; + project->path_to_entry_index[dep.first()] = entry.id; } // Build delta update. @@ -548,6 +553,7 @@ std::optional LastWriteTime(const std::string &path) { std::optional LoadIndexedContent(const std::string &path) { if (g_config->cacheDirectory.empty()) { + std::shared_lock lock(g_index_mutex); auto it = g_index.find(path); if (it == g_index.end()) return {}; diff --git a/src/project.cc b/src/project.cc index 173ec597d..3cd4aa524 100644 --- a/src/project.cc +++ b/src/project.cc @@ -377,13 +377,21 @@ void Project::Load(const std::string &root_directory) { EnsureEndsInSlash(path); LOG_S(INFO) << "angle_include_dir: " << path; } + + // Setup project entries. + std::lock_guard lock(mutex_); + path_to_entry_index.reserve(entries.size()); + for (size_t i = 0; i < entries.size(); ++i) { + entries[i].id = i; + path_to_entry_index[entries[i].filename] = i; + } } void Project::SetFlagsForFile(const std::vector &flags, const std::string &path) { std::lock_guard lock(mutex_); - auto it = absolute_path_to_entry_index_.find(path); - if (it != absolute_path_to_entry_index_.end()) { + auto it = path_to_entry_index.find(path); + if (it != path_to_entry_index.end()) { // The entry already exists in the project, just set the flags. this->entries[it->second].args = flags; } else { @@ -400,8 +408,8 @@ Project::Entry Project::FindCompilationEntryForFile(const std::string &filename) { { std::lock_guard lock(mutex_); - auto it = absolute_path_to_entry_index_.find(filename); - if (it != absolute_path_to_entry_index_.end()) + auto it = path_to_entry_index.find(filename); + if (it != path_to_entry_index.end()) return entries[it->second]; } diff --git a/src/project.h b/src/project.h index 3baa545ee..b431d1d48 100644 --- a/src/project.h +++ b/src/project.h @@ -43,7 +43,7 @@ struct Project { std::vector entries; std::mutex mutex_; - std::unordered_map absolute_path_to_entry_index_; + std::unordered_map path_to_entry_index; // Loads a project for the given |directory|. // diff --git a/src/query.cc b/src/query.cc index be657184e..6ec741436 100644 --- a/src/query.cc +++ b/src/query.cc @@ -227,16 +227,21 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { SymbolKind kind, Use &use, int delta, int k = 1) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; + SymbolRef sym{{use.range, usr, kind, use.role}}; if (k & 1) { - int &v = - files[use.file_id] - .symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}]; + int &v = files[use.file_id].symbol2refcnt[sym]; v += delta; assert(v >= 0); + if (!v) + files[use.file_id].symbol2refcnt.erase(sym); + } + if (k & 2) { + int &v = files[use.file_id].outline2refcnt[sym]; + v += delta; + assert(v >= 0); + if (!v) + files[use.file_id].outline2refcnt.erase(sym); } - if (k & 2) - files[use.file_id] - .outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta; }; auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, SymbolKind kind, DeclRef &dr, int delta) { From c9e6b31dd040fe8ab0f4e60b6636c0c30fe5238b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 10 Sep 2018 22:37:01 -0700 Subject: [PATCH 203/378] Revamp completion and signatureHelp, set completion.detailedLabel: true and add completion.duplicateOptional --- src/clang_complete.cc | 358 +-------------------- src/clang_complete.hh | 36 ++- src/config.h | 28 +- src/message_handler.h | 6 - src/messages/textDocument_completion.cc | 346 +++++++++++++++----- src/messages/textDocument_signatureHelp.cc | 275 +++++++++------- src/pipeline.cc | 7 - src/working_files.cc | 24 +- src/working_files.h | 1 - 9 files changed, 486 insertions(+), 595 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f6a848201..18b8ef377 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -23,6 +23,7 @@ limitations under the License. #include #include #include +#include #include #include #include @@ -42,268 +43,6 @@ std::string StripFileType(const std::string &path) { return Ret.str(); } -unsigned GetCompletionPriority(const CodeCompletionString &CCS, - CXCursorKind result_kind, - const std::optional &typedText) { - unsigned priority = CCS.getPriority(); - if (CCS.getAvailability() != CXAvailability_Available || - result_kind == CXCursor_Destructor || - result_kind == CXCursor_ConversionFunction || - (result_kind == CXCursor_CXXMethod && typedText && - StartsWith(*typedText, "operator"))) - priority *= 100; - return priority; -} - -lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { - switch (cursor_kind) { - case CXCursor_UnexposedDecl: - return lsCompletionItemKind::Text; - - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - return lsCompletionItemKind::Struct; - case CXCursor_ClassDecl: - return lsCompletionItemKind::Class; - case CXCursor_EnumDecl: - return lsCompletionItemKind::Enum; - case CXCursor_FieldDecl: - return lsCompletionItemKind::Field; - case CXCursor_EnumConstantDecl: - return lsCompletionItemKind::EnumMember; - case CXCursor_FunctionDecl: - return lsCompletionItemKind::Function; - case CXCursor_VarDecl: - case CXCursor_ParmDecl: - return lsCompletionItemKind::Variable; - case CXCursor_ObjCInterfaceDecl: - return lsCompletionItemKind::Interface; - - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_CXXMethod: - case CXCursor_ObjCClassMethodDecl: - return lsCompletionItemKind::Method; - - case CXCursor_FunctionTemplate: - return lsCompletionItemKind::Function; - - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - return lsCompletionItemKind::Constructor; - - case CXCursor_ObjCIvarDecl: - return lsCompletionItemKind::Variable; - - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_UsingDeclaration: - case CXCursor_TypedefDecl: - case CXCursor_TypeAliasDecl: - case CXCursor_TypeAliasTemplateDecl: - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_ObjCCategoryImplDecl: - return lsCompletionItemKind::Class; - - case CXCursor_ObjCPropertyDecl: - return lsCompletionItemKind::Property; - - case CXCursor_MacroInstantiation: - case CXCursor_MacroDefinition: - return lsCompletionItemKind::Interface; - - case CXCursor_Namespace: - case CXCursor_NamespaceAlias: - case CXCursor_NamespaceRef: - return lsCompletionItemKind::Module; - - case CXCursor_MemberRef: - case CXCursor_TypeRef: - case CXCursor_ObjCSuperClassRef: - case CXCursor_ObjCProtocolRef: - case CXCursor_ObjCClassRef: - return lsCompletionItemKind::Reference; - - // return lsCompletionItemKind::Unit; - // return lsCompletionItemKind::Value; - // return lsCompletionItemKind::Keyword; - // return lsCompletionItemKind::Snippet; - // return lsCompletionItemKind::Color; - // return lsCompletionItemKind::File; - - case CXCursor_NotImplemented: - case CXCursor_OverloadCandidate: - return lsCompletionItemKind::Text; - - case CXCursor_TemplateTypeParameter: - case CXCursor_TemplateTemplateParameter: - return lsCompletionItemKind::TypeParameter; - - default: - LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; - return lsCompletionItemKind::Text; - } -} - -void BuildCompletionItemTexts(std::vector &out, - CodeCompletionString &CCS, - bool include_snippets) { - assert(!out.empty()); - auto out_first = out.size() - 1; - - std::string result_type; - - for (unsigned i = 0, num_chunks = CCS.size(); i < num_chunks; ++i) { - const CodeCompletionString::Chunk &Chunk = CCS[i]; - CodeCompletionString::ChunkKind Kind = Chunk.Kind; - std::string text; - switch (Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_Informative: - if (Chunk.Text) - text = Chunk.Text; - for (auto i = out_first; i < out.size(); i++) { - // first TypedText is used for filtering - if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) - out[i].filterText = text; - if (Kind == CodeCompletionString::CK_Placeholder) - out[i].parameters_.push_back(text); - } - break; - case CodeCompletionString::CK_ResultType: - if (Chunk.Text) - result_type = Chunk.Text; - continue; - case CodeCompletionString::CK_CurrentParameter: - // We have our own parsing logic for active parameter. This doesn't seem - // to be very reliable. - continue; - case CodeCompletionString::CK_Optional: { - // duplicate last element, the recursive call will complete it - out.push_back(out.back()); - BuildCompletionItemTexts(out, *Chunk.Optional, include_snippets); - continue; - } - // clang-format off - case CodeCompletionString::CK_LeftParen: text = '('; break; - case CodeCompletionString::CK_RightParen: text = ')'; break; - case CodeCompletionString::CK_LeftBracket: text = '['; break; - case CodeCompletionString::CK_RightBracket: text = ']'; break; - case CodeCompletionString::CK_LeftBrace: text = '{'; break; - case CodeCompletionString::CK_RightBrace: text = '}'; break; - case CodeCompletionString::CK_LeftAngle: text = '<'; break; - case CodeCompletionString::CK_RightAngle: text = '>'; break; - case CodeCompletionString::CK_Comma: text = ", "; break; - case CodeCompletionString::CK_Colon: text = ':'; break; - case CodeCompletionString::CK_SemiColon: text = ';'; break; - case CodeCompletionString::CK_Equal: text = '='; break; - case CodeCompletionString::CK_HorizontalSpace: text = ' '; break; - case CodeCompletionString::CK_VerticalSpace: text = ' '; break; - // clang-format on - } - - if (Kind != CodeCompletionString::CK_Informative) - for (auto i = out_first; i < out.size(); ++i) { - out[i].label += text; - if (!include_snippets && !out[i].parameters_.empty()) - continue; - - if (Kind == CodeCompletionString::CK_Placeholder) { - out[i].insertText += "${" + - std::to_string(out[i].parameters_.size()) + ":" + - text + "}"; - out[i].insertTextFormat = lsInsertTextFormat::Snippet; - } else { - out[i].insertText += text; - } - } - } - - if (result_type.size()) - for (auto i = out_first; i < out.size(); ++i) { - // ' : ' for variables, - // ' -> ' (trailing return type-like) for functions - out[i].label += (out[i].label == out[i].filterText ? " : " : " -> "); - out[i].label += result_type; - } -} - -// |do_insert|: if |!do_insert|, do not append strings to |insert| after -// a placeholder. -void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item, - bool &do_insert, std::vector *parameters, - bool include_snippets, int &angle_stack) { - for (unsigned i = 0, num_chunks = CCS.size(); i < num_chunks; ++i) { - const CodeCompletionString::Chunk &Chunk = CCS[i]; - CodeCompletionString::ChunkKind Kind = Chunk.Kind; - const char *text = nullptr; - switch (Kind) { - case CodeCompletionString::CK_TypedText: - item.label = Chunk.Text; - [[fallthrough]]; - case CodeCompletionString::CK_Text: - item.detail += Chunk.Text; - if (do_insert) - item.insertText += Chunk.Text; - break; - case CodeCompletionString::CK_Placeholder: { - parameters->push_back(Chunk.Text); - item.detail += Chunk.Text; - // Add parameter declarations as snippets if enabled - if (include_snippets) { - item.insertText += - "${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}"; - item.insertTextFormat = lsInsertTextFormat::Snippet; - } else - do_insert = false; - break; - } - case CodeCompletionString::CK_Informative: - item.detail += Chunk.Text; - break; - case CodeCompletionString::CK_Optional: { - // Do not add text to insert string if we're in angle brackets. - bool should_insert = do_insert && angle_stack == 0; - BuildDetailString(*Chunk.Optional, item, should_insert, parameters, - include_snippets, angle_stack); - break; - } - case CodeCompletionString::CK_ResultType: - item.detail = Chunk.Text + item.detail + " "; - break; - case CodeCompletionString::CK_CurrentParameter: - // We have our own parsing logic for active parameter. This doesn't seem - // to be very reliable. - break; - // clang-format off - case CodeCompletionString::CK_LeftParen: text = "("; break; - case CodeCompletionString::CK_RightParen: text = ")"; break; - case CodeCompletionString::CK_LeftBracket: text = "["; break; - case CodeCompletionString::CK_RightBracket: text = "]"; break; - case CodeCompletionString::CK_LeftBrace: text = "{"; break; - case CodeCompletionString::CK_RightBrace: text = "}"; break; - case CodeCompletionString::CK_LeftAngle: text = "<"; angle_stack++; break; - case CodeCompletionString::CK_RightAngle: text = ">"; angle_stack--; break; - case CodeCompletionString::CK_Comma: text = ", "; break; - case CodeCompletionString::CK_Colon: text = ":"; break; - case CodeCompletionString::CK_SemiColon: text = ";"; break; - case CodeCompletionString::CK_Equal: text = "="; break; - case CodeCompletionString::CK_HorizontalSpace: - case CodeCompletionString::CK_VerticalSpace: text = " "; break; - // clang-format on - } - if (text) { - item.detail += text; - if (do_insert && include_snippets) - item.insertText += text; - } - } -} - bool LocationInRange(SourceLocation L, CharSourceRange R, const SourceManager &M) { assert(R.isCharRange()); @@ -336,70 +75,6 @@ CharSourceRange DiagnosticRange(const clang::Diagnostic &D, const LangOptions &L } -class CaptureCompletionResults : public CodeCompleteConsumer { - std::shared_ptr Alloc; - CodeCompletionTUInfo CCTUInfo; - -public: - std::vector ls_items; - - CaptureCompletionResults(const CodeCompleteOptions &Opts) - : CodeCompleteConsumer(Opts, false), - Alloc(std::make_shared()), - CCTUInfo(Alloc) {} - - void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) override { - ls_items.reserve(NumResults); - for (unsigned i = 0; i != NumResults; i++) { - auto &R = Results[i]; - if (R.Availability == CXAvailability_NotAccessible || - R.Availability == CXAvailability_NotAvailable) - continue; - CodeCompletionString *CCS = R.CreateCodeCompletionString( - S, Context, getAllocator(), getCodeCompletionTUInfo(), - includeBriefComments()); - lsCompletionItem ls_item; - ls_item.kind = GetCompletionKind(R.CursorKind); - if (const char *brief = CCS->getBriefComment()) - ls_item.documentation = brief; - - // label/detail/filterText/insertText/priority - if (g_config->completion.detailedLabel) { - ls_item.detail = CCS->getParentContextName().str(); - - size_t first_idx = ls_items.size(); - ls_items.push_back(ls_item); - BuildCompletionItemTexts(ls_items, *CCS, - g_config->client.snippetSupport); - - for (size_t j = first_idx; j < ls_items.size(); j++) { - if (g_config->client.snippetSupport && - ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) - ls_items[j].insertText += "$0"; - ls_items[j].priority_ = GetCompletionPriority( - *CCS, Results[i].CursorKind, ls_items[j].filterText); - } - } else { - bool do_insert = true; - int angle_stack = 0; - BuildDetailString(*CCS, ls_item, do_insert, &ls_item.parameters_, - g_config->client.snippetSupport, angle_stack); - if (g_config->client.snippetSupport && - ls_item.insertTextFormat == lsInsertTextFormat::Snippet) - ls_item.insertText += "$0"; - ls_item.priority_ = - GetCompletionPriority(*CCS, Results[i].CursorKind, ls_item.label); - ls_items.push_back(ls_item); - } - } - } - - CodeCompletionAllocator &getAllocator() override { return *Alloc; } - - CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } -}; class StoreDiags : public DiagnosticConsumer { const LangOptions *LangOpts; @@ -560,6 +235,8 @@ void CompletionMain(CompletionManager *completion_manager) { while (g_config->completion.dropOldRequests && !completion_manager->completion_request_.IsEmpty()) { completion_manager->on_dropped_(request->id); + request->Consumer.reset(); + request->on_complete(nullptr); request = completion_manager->completion_request_.Dequeue(); } @@ -573,15 +250,9 @@ void CompletionMain(CompletionManager *completion_manager) { BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; - clang::CodeCompleteOptions CCOpts; - CCOpts.IncludeBriefComments = true; -#if LLVM_VERSION_MAJOR >= 7 - CCOpts.IncludeFixIts = true; -#endif - CCOpts.IncludeCodePatterns = true; auto &FOpts = CI->getFrontendOpts(); - FOpts.CodeCompleteOpts = CCOpts; - FOpts.CodeCompletionAt.FileName = session->file.filename; + FOpts.CodeCompleteOpts = request->CCOpts; + FOpts.CodeCompletionAt.FileName = path; FOpts.CodeCompletionAt.Line = request->position.line + 1; FOpts.CodeCompletionAt.Column = request->position.character + 1; FOpts.SkipFunctionBodies = true; @@ -595,14 +266,13 @@ void CompletionMain(CompletionManager *completion_manager) { if (!Clang) continue; - auto Consumer = new CaptureCompletionResults(CCOpts); - Clang->setCodeCompletionConsumer(Consumer); + Clang->setCodeCompletionConsumer(request->Consumer.release()); if (!Parse(*Clang)) continue; for (auto &Buf : Bufs) Buf.release(); - request->on_complete(Consumer->ls_items, false /*is_cached_result*/); + request->on_complete(&Clang->getCodeCompletionConsumer()); } } @@ -729,9 +399,6 @@ void CompletionManager::CodeComplete( const lsRequestId &id, const lsTextDocumentPositionParams &completion_location, const OnComplete &on_complete) { - completion_request_.PushBack(std::make_unique( - id, completion_location.textDocument, completion_location.position, - on_complete)); } void CompletionManager::DiagnosticsUpdate( @@ -844,14 +511,3 @@ void CompletionManager::FlushAllSessions() { preloaded_sessions_.Clear(); completion_sessions_.Clear(); } - -void CodeCompleteCache::WithLock(std::function action) { - std::lock_guard lock(mutex_); - action(); -} - -bool CodeCompleteCache::IsCacheValid(lsTextDocumentPositionParams position) { - std::lock_guard lock(mutex_); - return cached_path_ == position.textDocument.uri.GetPath() && - cached_completion_position_ == position.position; -} diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 94e9fc36d..81fd00209 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -25,6 +25,7 @@ limitations under the License. #include #include +#include #include #include @@ -79,8 +80,9 @@ struct CompletionSession struct CompletionManager { using OnDiagnostic = std::function diagnostics)>; - using OnComplete = std::function &results, bool is_cached_result)>; + // If OptConsumer is nullptr, the request has been cancelled. + using OnComplete = + std::function; using OnDropped = std::function; struct PreloadRequest { @@ -93,13 +95,19 @@ struct CompletionManager { struct CompletionRequest { CompletionRequest(const lsRequestId &id, const lsTextDocumentIdentifier &document, - const lsPosition &position, const OnComplete &on_complete) + const lsPosition &position, + std::unique_ptr Consumer, + clang::CodeCompleteOptions CCOpts, + const OnComplete &on_complete) : id(id), document(document), position(position), + Consumer(std::move(Consumer)), CCOpts(CCOpts), on_complete(on_complete) {} lsRequestId id; lsTextDocumentIdentifier document; lsPosition position; + std::unique_ptr Consumer; + clang::CodeCompleteOptions CCOpts; OnComplete on_complete; }; struct DiagnosticRequest { @@ -176,14 +184,22 @@ struct CompletionManager { // Cached completion information, so we can give fast completion results when // the user erases a character. vscode will resend the completion request if // that happens. -struct CodeCompleteCache { +template +struct CompleteConsumerCache { // NOTE: Make sure to access these variables under |WithLock|. - std::optional cached_path_; - std::optional cached_completion_position_; - std::vector cached_results_; + std::optional path; + std::optional position; + T result; - std::mutex mutex_; + std::mutex mutex; - void WithLock(std::function action); - bool IsCacheValid(lsTextDocumentPositionParams position); + void WithLock(std::function action) { + std::lock_guard lock(mutex); + action(); + } + bool IsCacheValid(const lsTextDocumentPositionParams ¶ms) { + std::lock_guard lock(mutex); + return path == params.textDocument.uri.GetPath() && + position == params.position; + } }; diff --git a/src/config.h b/src/config.h index 310d8dba7..19093af1b 100644 --- a/src/config.h +++ b/src/config.h @@ -92,16 +92,7 @@ struct Config { // When this option is enabled, the completion item label is very detailed, // it shows the full signature of the candidate. // The detail just contains the completion item parent context. - // Also, in this mode, functions with default arguments, - // generates one more item per default argument - // so that the right function call can be selected. - // That is, you get something like: - // "int foo()" "Foo" - // "void bar()" "Foo" - // "void bar(int i = 0)" "Foo" - // Be wary, this is quickly quite verbose, - // items can end up truncated by the UIs. - bool detailedLabel = false; + bool detailedLabel = true; // On large projects, completion can take a long time. By default if ccls // receives multiple completion requests while completion is still running @@ -109,6 +100,15 @@ struct Config { // completion requests will be serviced. bool dropOldRequests = true; + // Functions with default arguments, generate one more item per default + // argument. That is, you get something like: + // "int foo()" "Foo" + // "void bar()" "Foo" + // "void bar(int i = 0)" "Foo" + // Be wary, this is quickly quite verbose, + // items can end up truncated by the UIs. + bool duplicateOptional = true; + // If true, filter and sort completion response. ccls filters and sorts // completions to try to be nicer to clients that can't handle big numbers // of completion candidates. This behaviour can be disabled by specifying @@ -238,10 +238,10 @@ struct Config { MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, resourceDir); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); -MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests, - detailedLabel, filterAndSort, includeBlacklist, - includeMaxPathSize, includeSuffixWhitelist, - includeWhitelist); +MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, + dropOldRequests, duplicateOptional, filterAndSort, + includeBlacklist, includeMaxPathSize, + includeSuffixWhitelist, includeWhitelist); MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, onOpen, onSave, spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) diff --git a/src/message_handler.h b/src/message_handler.h index 3d314222d..ac1c80217 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -27,11 +27,9 @@ limitations under the License. #include struct CompletionManager; -struct CodeCompleteCache; struct Config; class DiagnosticsPublisher; struct VFS; -struct ImportManager; struct IncludeComplete; struct MultiQueueWaiter; struct Project; @@ -116,14 +114,10 @@ struct MessageHandler { Project *project = nullptr; DiagnosticsPublisher *diag_pub = nullptr; VFS *vfs = nullptr; - ImportManager *import_manager = nullptr; SemanticHighlightSymbolCache *semantic_cache = nullptr; WorkingFiles *working_files = nullptr; CompletionManager *clang_complete = nullptr; IncludeComplete *include_complete = nullptr; - CodeCompleteCache *global_code_complete_cache = nullptr; - CodeCompleteCache *non_global_code_complete_cache = nullptr; - CodeCompleteCache *signature_cache = nullptr; virtual MethodType GetMethodType() const = 0; virtual void Run(std::unique_ptr message) = 0; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 78383969a..663a4a887 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -16,12 +16,16 @@ limitations under the License. #include "clang_complete.hh" #include "fuzzy_match.h" #include "include_complete.h" +#include "log.hh" #include "message_handler.h" #include "pipeline.hh" #include "working_files.h" using namespace ccls; +#include +#include #include +using namespace clang; using namespace llvm; #include @@ -261,24 +265,245 @@ bool IsOpenParenOrAngle(const std::vector &lines, return false; } -struct Handler_TextDocumentCompletion : MessageHandler { +unsigned GetCompletionPriority(const CodeCompletionString &CCS, + CXCursorKind result_kind, + const std::optional &typedText) { + unsigned priority = CCS.getPriority(); + if (CCS.getAvailability() != CXAvailability_Available || + result_kind == CXCursor_Destructor || + result_kind == CXCursor_ConversionFunction || + (result_kind == CXCursor_CXXMethod && typedText && + StartsWith(*typedText, "operator"))) + priority *= 100; + return priority; +} + +lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { + switch (cursor_kind) { + case CXCursor_UnexposedDecl: + return lsCompletionItemKind::Text; + + case CXCursor_StructDecl: + case CXCursor_UnionDecl: + return lsCompletionItemKind::Struct; + case CXCursor_ClassDecl: + return lsCompletionItemKind::Class; + case CXCursor_EnumDecl: + return lsCompletionItemKind::Enum; + case CXCursor_FieldDecl: + return lsCompletionItemKind::Field; + case CXCursor_EnumConstantDecl: + return lsCompletionItemKind::EnumMember; + case CXCursor_FunctionDecl: + return lsCompletionItemKind::Function; + case CXCursor_VarDecl: + case CXCursor_ParmDecl: + return lsCompletionItemKind::Variable; + case CXCursor_ObjCInterfaceDecl: + return lsCompletionItemKind::Interface; + + case CXCursor_ObjCInstanceMethodDecl: + case CXCursor_CXXMethod: + case CXCursor_ObjCClassMethodDecl: + return lsCompletionItemKind::Method; + + case CXCursor_FunctionTemplate: + return lsCompletionItemKind::Function; + + case CXCursor_Constructor: + case CXCursor_Destructor: + case CXCursor_ConversionFunction: + return lsCompletionItemKind::Constructor; + + case CXCursor_ObjCIvarDecl: + return lsCompletionItemKind::Variable; + + case CXCursor_ClassTemplate: + case CXCursor_ClassTemplatePartialSpecialization: + case CXCursor_UsingDeclaration: + case CXCursor_TypedefDecl: + case CXCursor_TypeAliasDecl: + case CXCursor_TypeAliasTemplateDecl: + case CXCursor_ObjCCategoryDecl: + case CXCursor_ObjCProtocolDecl: + case CXCursor_ObjCImplementationDecl: + case CXCursor_ObjCCategoryImplDecl: + return lsCompletionItemKind::Class; + + case CXCursor_ObjCPropertyDecl: + return lsCompletionItemKind::Property; + + case CXCursor_MacroInstantiation: + case CXCursor_MacroDefinition: + return lsCompletionItemKind::Interface; + + case CXCursor_Namespace: + case CXCursor_NamespaceAlias: + case CXCursor_NamespaceRef: + return lsCompletionItemKind::Module; + + case CXCursor_MemberRef: + case CXCursor_TypeRef: + case CXCursor_ObjCSuperClassRef: + case CXCursor_ObjCProtocolRef: + case CXCursor_ObjCClassRef: + return lsCompletionItemKind::Reference; + + // return lsCompletionItemKind::Unit; + // return lsCompletionItemKind::Value; + // return lsCompletionItemKind::Keyword; + // return lsCompletionItemKind::Snippet; + // return lsCompletionItemKind::Color; + // return lsCompletionItemKind::File; + + case CXCursor_NotImplemented: + case CXCursor_OverloadCandidate: + return lsCompletionItemKind::Text; + + case CXCursor_TemplateTypeParameter: + case CXCursor_TemplateTemplateParameter: + return lsCompletionItemKind::TypeParameter; + + default: + LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; + return lsCompletionItemKind::Text; + } +} + +void BuildItem(std::vector &out, + const CodeCompletionString &CCS) { + assert(!out.empty()); + auto first = out.size() - 1; + + std::string result_type; + + for (const auto &Chunk : CCS) { + CodeCompletionString::ChunkKind Kind = Chunk.Kind; + std::string text; + switch (Kind) { + case CodeCompletionString::CK_TypedText: + text = Chunk.Text; + for (auto i = first; i < out.size(); i++) + if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) + out[i].filterText = text; + break; + case CodeCompletionString::CK_Placeholder: + text = Chunk.Text; + for (auto i = first; i < out.size(); i++) + out[i].parameters_.push_back(text); + break; + case CodeCompletionString::CK_ResultType: + result_type = Chunk.Text; + continue; + case CodeCompletionString::CK_CurrentParameter: + // This should never be present while collecting completion items. + llvm_unreachable("unexpected CK_CurrentParameter"); + continue; + case CodeCompletionString::CK_Optional: { + // Duplicate last element, the recursive call will complete it. + if (g_config->completion.duplicateOptional) { + out.push_back(out.back()); + BuildItem(out, *Chunk.Optional); + } + continue; + } + default: + text = Chunk.Text; + break; + } + + for (auto i = first; i < out.size(); ++i) { + out[i].label += text; + if (!g_config->client.snippetSupport && !out[i].parameters_.empty()) + continue; + + if (Kind == CodeCompletionString::CK_Placeholder) { + out[i].insertText += + "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; + out[i].insertTextFormat = lsInsertTextFormat::Snippet; + } else { + out[i].insertText += text; + } + } + } + + if (result_type.size()) + for (auto i = first; i < out.size(); ++i) { + // ' : ' for variables, + // ' -> ' (trailing return type-like) for functions + out[i].label += (out[i].label == out[i].filterText ? " : " : " -> "); + out[i].label += result_type; + } +} + +class CompletionConsumer : public CodeCompleteConsumer { + std::shared_ptr Alloc; + CodeCompletionTUInfo CCTUInfo; + +public: + bool from_cache; + std::vector ls_items; + + CompletionConsumer(const CodeCompleteOptions &Opts, bool from_cache) + : CodeCompleteConsumer(Opts, false), + Alloc(std::make_shared()), + CCTUInfo(Alloc), from_cache(from_cache) {} + + void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override { + ls_items.reserve(NumResults); + for (unsigned i = 0; i != NumResults; i++) { + auto &R = Results[i]; + if (R.Availability == CXAvailability_NotAccessible || + R.Availability == CXAvailability_NotAvailable) + continue; + CodeCompletionString *CCS = R.CreateCodeCompletionString( + S, Context, getAllocator(), getCodeCompletionTUInfo(), + includeBriefComments()); + lsCompletionItem ls_item; + ls_item.kind = GetCompletionKind(R.CursorKind); + if (const char *brief = CCS->getBriefComment()) + ls_item.documentation = brief; + ls_item.detail = CCS->getParentContextName().str(); + + size_t first_idx = ls_items.size(); + ls_items.push_back(ls_item); + BuildItem(ls_items, *CCS); + + for (size_t j = first_idx; j < ls_items.size(); j++) { + if (g_config->client.snippetSupport && + ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) + ls_items[j].insertText += "$0"; + ls_items[j].priority_ = GetCompletionPriority( + *CCS, Results[i].CursorKind, ls_items[j].filterText); + if (!g_config->completion.detailedLabel) { + ls_items[j].detail = ls_items[j].label; + ls_items[j].label = ls_items[j].filterText.value_or(""); + } + } + } + } + + CodeCompletionAllocator &getAllocator() override { return *Alloc; } + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } +}; + +struct Handler_TextDocumentCompletion + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(std::unique_ptr message) override { - auto request = std::shared_ptr( - static_cast(message.release())); - auto ¶ms = request->params; + void Run(In_TextDocumentComplete *request) override { + static CompleteConsumerCache> cache; - auto write_empty_result = [request]() { - Out_TextDocumentComplete out; - out.id = request->id; - pipeline::WriteStdout(kMethodType, out); - }; + auto ¶ms = request->params; + Out_TextDocumentComplete out; + out.id = request->id; std::string path = params.textDocument.uri.GetPath(); WorkingFile *file = working_files->GetFileByFilename(path); if (!file) { - write_empty_result(); + pipeline::WriteStdout(kMethodType, out); return; } @@ -323,19 +548,15 @@ struct Handler_TextDocumentCompletion : MessageHandler { } if (did_fail_check) { - write_empty_result(); + pipeline::WriteStdout(kMethodType, out); return; } } - bool is_global_completion = false; - std::string existing_completion; + std::string completion_text; lsPosition end_pos = params.position; - if (file) { - params.position = file->FindStableCompletionSource( - request->params.position, &is_global_completion, &existing_completion, - &end_pos); - } + params.position = file->FindStableCompletionSource( + request->params.position, &completion_text, &end_pos); ParseIncludeLineResult result = ParseIncludeLine(buffer_line); bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos); @@ -380,69 +601,44 @@ struct Handler_TextDocumentCompletion : MessageHandler { pipeline::WriteStdout(kMethodType, out); } else { - CompletionManager::OnComplete callback = std::bind( - [this, request, params, is_global_completion, existing_completion, - has_open_paren](const std::vector &results, - bool is_cached_result) { + CompletionManager::OnComplete callback = + [completion_text, has_open_paren, id = request->id, + params = request->params](CodeCompleteConsumer *OptConsumer) { + if (!OptConsumer) + return; + auto *Consumer = static_cast(OptConsumer); Out_TextDocumentComplete out; - out.id = request->id; - out.result.items = results; + out.id = id; + out.result.items = Consumer->ls_items; - // Emit completion results. - FilterAndSortCompletionResponse(&out, existing_completion, + FilterAndSortCompletionResponse(&out, completion_text, has_open_paren); pipeline::WriteStdout(kMethodType, out); - - // Cache completion results. - if (!is_cached_result) { + if (!Consumer->from_cache) { std::string path = params.textDocument.uri.GetPath(); - if (is_global_completion) { - global_code_complete_cache->WithLock([&]() { - global_code_complete_cache->cached_path_ = path; - global_code_complete_cache->cached_results_ = results; - }); - } else { - non_global_code_complete_cache->WithLock([&]() { - non_global_code_complete_cache->cached_path_ = path; - non_global_code_complete_cache->cached_completion_position_ = - params.position; - non_global_code_complete_cache->cached_results_ = results; - }); - } - } - }, - std::placeholders::_1, std::placeholders::_2); - - bool is_cache_match = false; - global_code_complete_cache->WithLock([&]() { - is_cache_match = is_global_completion && - global_code_complete_cache->cached_path_ == path && - !global_code_complete_cache->cached_results_.empty(); - }); - if (is_cache_match) { - CompletionManager::OnComplete freshen_global = - [this](std::vector results, - bool is_cached_result) { - assert(!is_cached_result); - - // note: path is updated in the normal completion handler. - global_code_complete_cache->WithLock([&]() { - global_code_complete_cache->cached_results_ = results; + cache.WithLock([&]() { + cache.path = path; + cache.position = params.position; + cache.result = Consumer->ls_items; }); - }; - - global_code_complete_cache->WithLock([&]() { - callback(global_code_complete_cache->cached_results_, - true /*is_cached_result*/); - }); - clang_complete->CodeComplete(request->id, params, freshen_global); - } else if (non_global_code_complete_cache->IsCacheValid(params)) { - non_global_code_complete_cache->WithLock([&]() { - callback(non_global_code_complete_cache->cached_results_, - true /*is_cached_result*/); - }); + } + }; + + clang::CodeCompleteOptions CCOpts; + CCOpts.IncludeBriefComments = true; +#if LLVM_VERSION_MAJOR >= 7 + CCOpts.IncludeFixIts = true; +#endif + if (cache.IsCacheValid(params)) { + CompletionConsumer Consumer(CCOpts, true); + cache.WithLock([&]() { Consumer.ls_items = cache.result; }); + callback(&Consumer); } else { - clang_complete->CodeComplete(request->id, params, callback); + clang_complete->completion_request_.PushBack( + std::make_unique( + request->id, params.textDocument, params.position, + std::make_unique(CCOpts, false), CCOpts, + callback)); } } } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 1a763e218..4fcbd764e 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -18,44 +18,29 @@ limitations under the License. #include "pipeline.hh" using namespace ccls; +#include +using namespace clang; + #include namespace { MethodType kMethodType = "textDocument/signatureHelp"; -struct In_TextDocumentSignatureHelp : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentSignatureHelp, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentSignatureHelp); - // Represents a parameter of a callable-signature. A parameter can // have a label and a doc-comment. struct lsParameterInformation { - // The label of this parameter. Will be shown in - // the UI. std::string label; - - // The human-readable doc-comment of this parameter. Will be shown - // in the UI but can be omitted. - std::optional documentation; + // Not available in clang + // std::optional documentation; }; -MAKE_REFLECT_STRUCT(lsParameterInformation, label, documentation); +MAKE_REFLECT_STRUCT(lsParameterInformation, label); // Represents the signature of something callable. A signature // can have a label, like a function-name, a doc-comment, and // a set of parameters. struct lsSignatureInformation { - // The label of this signature. Will be shown in - // the UI. std::string label; - - // The human-readable doc-comment of this signature. Will be shown - // in the UI but can be omitted. std::optional documentation; - - // The parameters of this signature. std::vector parameters; }; MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters); @@ -64,30 +49,20 @@ MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters); // callable. There can be multiple signature but only one // active and only one active parameter. struct lsSignatureHelp { - // One or more signatures. std::vector signatures; - - // The active signature. If omitted or the value lies outside the - // range of `signatures` the value defaults to zero or is ignored if - // `signatures.length === 0`. Whenever possible implementors should - // make an active decision about the active signature and shouldn't - // rely on a default value. - // In future version of the protocol this property might become - // mandantory to better express this. - std::optional activeSignature; - - // The active parameter of the active signature. If omitted or the value - // lies outside the range of `signatures[activeSignature].parameters` - // defaults to 0 if the active signature has parameters. If - // the active signature has no parameters it is ignored. - // In future version of the protocol this property might become - // mandantory to better express the active parameter if the - // active signature does have any. - std::optional activeParameter; + int activeSignature = 0; + int activeParameter; }; MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, activeParameter); +struct In_TextDocumentSignatureHelp : public RequestInMessage { + MethodType GetMethodType() const override { return kMethodType; } + lsTextDocumentPositionParams params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentSignatureHelp, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentSignatureHelp); + struct Out_TextDocumentSignatureHelp : public lsOutMessage { lsRequestId id; @@ -95,88 +70,164 @@ struct Out_TextDocumentSignatureHelp }; MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result); -struct Handler_TextDocumentSignatureHelp : MessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(std::unique_ptr message) override { - auto request = static_cast(message.get()); - lsTextDocumentPositionParams ¶ms = request->params; - WorkingFile *file = - working_files->GetFileByFilename(params.textDocument.uri.GetPath()); - std::string search; - int active_param = 0; - if (file) { - lsPosition completion_position; - search = file->FindClosestCallNameInBuffer(params.position, &active_param, - &completion_position); - params.position = completion_position; +std::string BuildOptional(const CodeCompletionString &CCS, + std::vector &ls_params) { + std::string ret; + for (const auto &Chunk : CCS) { + switch (Chunk.Kind) { + case CodeCompletionString::CK_Optional: + ret += BuildOptional(*Chunk.Optional, ls_params); + break; + case CodeCompletionString::CK_Placeholder: + // A string that acts as a placeholder for, e.g., a function call + // argument. + // Intentional fallthrough here. + case CodeCompletionString::CK_CurrentParameter: { + // A piece of text that describes the parameter that corresponds to + // the code-completion location within a function call, message send, + // macro invocation, etc. + ret += Chunk.Text; + ls_params.push_back(lsParameterInformation{Chunk.Text}); + break; + } + case CodeCompletionString::CK_VerticalSpace: + break; + default: + ret += Chunk.Text; + break; } - if (search.empty()) - return; + } + return ret; +} + +class SignatureHelpConsumer : public CodeCompleteConsumer { + std::shared_ptr Alloc; + CodeCompletionTUInfo CCTUInfo; +public: + bool from_cache; + lsSignatureHelp ls_sighelp; + SignatureHelpConsumer(const clang::CodeCompleteOptions &CCOpts, + bool from_cache) + : CodeCompleteConsumer(CCOpts, false), + Alloc(std::make_shared()), + CCTUInfo(Alloc), from_cache(from_cache) {} + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates +#if LLVM_VERSION_MAJOR >= 8 + , + SourceLocation OpenParLoc +#endif + ) override { + ls_sighelp.activeParameter = (int)CurrentArg; + for (unsigned i = 0; i < NumCandidates; i++) { + OverloadCandidate Cand = Candidates[i]; + // We want to avoid showing instantiated signatures, because they may be + // long in some cases (e.g. when 'T' is substituted with 'std::string', we + // would get 'std::basic_string'). + if (auto *Func = Cand.getFunction()) + if (auto *Pattern = Func->getTemplateInstantiationPattern()) + Cand = OverloadCandidate(Pattern); + + const auto *CCS = + Cand.CreateSignatureString(CurrentArg, S, *Alloc, CCTUInfo, true); + + const char *ret_type = nullptr; + lsSignatureInformation &ls_sig = ls_sighelp.signatures.emplace_back(); +#if LLVM_VERSION_MAJOR >= 8 + const RawComment *RC = getCompletionComment(S.getASTContext(), Cand.getFunction()); + ls_sig.documentation = RC ? RC->getBriefText(S.getASTContext()) : ""; +#endif + for (const auto &Chunk : *CCS) + switch (Chunk.Kind) { + case CodeCompletionString::CK_ResultType: + ret_type = Chunk.Text; + break; + case CodeCompletionString::CK_Placeholder: + case CodeCompletionString::CK_CurrentParameter: { + ls_sig.label += Chunk.Text; + ls_sig.parameters.push_back(lsParameterInformation{Chunk.Text}); + break; + } + case CodeCompletionString::CK_Optional: + ls_sig.label += BuildOptional(*Chunk.Optional, ls_sig.parameters); + break; + case CodeCompletionString::CK_VerticalSpace: + break; + default: + ls_sig.label += Chunk.Text; + break; + } + if (ret_type) { + ls_sig.label += " -> "; + ls_sig.label += ret_type; + } + } + std::sort( + ls_sighelp.signatures.begin(), ls_sighelp.signatures.end(), + [](const lsSignatureInformation &l, const lsSignatureInformation &r) { + if (l.parameters.size() != r.parameters.size()) + return l.parameters.size() < r.parameters.size(); + if (l.label.size() != r.label.size()) + return l.label.size() < r.label.size(); + return l.label < r.label; + }); + } - CompletionManager::OnComplete callback = std::bind( - [this](InMessage *message, std::string search, int active_param, - const std::vector &results, - bool is_cached_result) { - auto msg = static_cast(message); + CodeCompletionAllocator &getAllocator() override { return *Alloc; } + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } +}; - Out_TextDocumentSignatureHelp out; - out.id = msg->id; - - for (auto &result : results) { - if (result.label != search) - continue; - - lsSignatureInformation signature; - signature.label = result.detail; - for (auto ¶meter : result.parameters_) { - lsParameterInformation ls_param; - ls_param.label = parameter; - signature.parameters.push_back(ls_param); - } - out.result.signatures.push_back(signature); - } +struct Handler_TextDocumentSignatureHelp + : BaseMessageHandler { + MethodType GetMethodType() const override { return kMethodType; } - // Prefer the signature with least parameter count but still larger - // than active_param. - out.result.activeSignature = 0; - if (out.result.signatures.size()) { - size_t num_parameters = SIZE_MAX; - for (size_t i = 0; i < out.result.signatures.size(); ++i) { - size_t t = out.result.signatures[i].parameters.size(); - if (active_param < t && t < num_parameters) { - out.result.activeSignature = int(i); - num_parameters = t; - } - } - } + void Run(In_TextDocumentSignatureHelp *request) override { + static CompleteConsumerCache cache; - // Set signature to what we parsed from the working file. - out.result.activeParameter = active_param; + auto ¶ms = request->params; + std::string path = params.textDocument.uri.GetPath(); + if (WorkingFile *file = working_files->GetFileByFilename(path)) { + std::string completion_text; + lsPosition end_pos = params.position; + params.position = file->FindStableCompletionSource( + request->params.position, &completion_text, &end_pos); + } + CompletionManager::OnComplete callback = + [id = request->id, + params = request->params](CodeCompleteConsumer *OptConsumer) { + if (!OptConsumer) + return; + auto *Consumer = static_cast(OptConsumer); + Out_TextDocumentSignatureHelp out; + out.id = id; + out.result = Consumer->ls_sighelp; pipeline::WriteStdout(kMethodType, out); - - if (!is_cached_result) { - signature_cache->WithLock([&]() { - signature_cache->cached_path_ = - msg->params.textDocument.uri.GetPath(); - signature_cache->cached_completion_position_ = - msg->params.position; - signature_cache->cached_results_ = results; + if (!Consumer->from_cache) { + std::string path = params.textDocument.uri.GetPath(); + cache.WithLock([&]() { + cache.path = path; + cache.position = params.position; + cache.result = Consumer->ls_sighelp; }); } - - delete message; - }, - message.release(), search, active_param, std::placeholders::_1, - std::placeholders::_2); - - if (signature_cache->IsCacheValid(params)) { - signature_cache->WithLock([&]() { - callback(signature_cache->cached_results_, true /*is_cached_result*/); - }); + }; + + CodeCompleteOptions CCOpts; + CCOpts.IncludeGlobals = false; + CCOpts.IncludeMacros = false; + CCOpts.IncludeBriefComments = false; + if (cache.IsCacheValid(params)) { + SignatureHelpConsumer Consumer(CCOpts, true); + cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); + callback(&Consumer); } else { - clang_complete->CodeComplete(request->id, params, std::move(callback)); + clang_complete->completion_request_.PushBack( + std::make_unique( + request->id, params.textDocument, params.position, + std::make_unique(CCOpts, false), CCOpts, + callback)); } } }; diff --git a/src/pipeline.cc b/src/pipeline.cc index 31ae2a2a8..be30a5f88 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -486,9 +486,6 @@ void MainLoop() { }); IncludeComplete include_complete(&project); - auto global_code_complete_cache = std::make_unique(); - auto non_global_code_complete_cache = std::make_unique(); - auto signature_cache = std::make_unique(); DB db; // Setup shared references. @@ -502,10 +499,6 @@ void MainLoop() { handler->working_files = &working_files; handler->clang_complete = &clang_complete; handler->include_complete = &include_complete; - handler->global_code_complete_cache = global_code_complete_cache.get(); - handler->non_global_code_complete_cache = - non_global_code_complete_cache.get(); - handler->signature_cache = signature_cache.get(); } while (true) { diff --git a/src/working_files.cc b/src/working_files.cc index 74b9f30de..319a887e0 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -387,31 +387,17 @@ std::string WorkingFile::FindClosestCallNameInBuffer( return buffer_content.substr(offset, start_offset - offset + 1); } -lsPosition WorkingFile::FindStableCompletionSource( - lsPosition position, bool *is_global_completion, - std::string *existing_completion, lsPosition *replace_end_pos) const { - *is_global_completion = true; - +lsPosition +WorkingFile::FindStableCompletionSource(lsPosition position, + std::string *existing_completion, + lsPosition *replace_end_pos) const { int start_offset = GetOffsetForPosition(position, buffer_content); int offset = start_offset; while (offset > 0) { char c = buffer_content[offset - 1]; - if (!isalnum(c) && c != '_') { - // Global completion is everything except for dot (.), arrow (->), and - // double colon (::) - if (c == '.') - *is_global_completion = false; - if (offset > 2) { - char pc = buffer_content[offset - 2]; - if (pc == ':' && c == ':') - *is_global_completion = false; - else if (pc == '-' && c == '>') - *is_global_completion = false; - } - + if (!isalnum(c) && c != '_') break; - } --offset; } diff --git a/src/working_files.h b/src/working_files.h index dcd8fa843..caa001fd3 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -82,7 +82,6 @@ struct WorkingFile { // The out param |existing_completion| is set to any existing completion // content the user has entered. lsPosition FindStableCompletionSource(lsPosition position, - bool *is_global_completion, std::string *existing_completion, lsPosition *replace_end_pos) const; From a45686ae1b2aa8b0fa26e79452e9775ad2cc0f23 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 11 Sep 2018 16:42:04 -0700 Subject: [PATCH 204/378] diagnostics; use custom DenseMapInfo --- src/clang_complete.cc | 19 +++++---- src/clang_complete.hh | 4 -- src/messages/textDocument_didSave.cc | 2 - src/query.cc | 61 ++++++++++++++-------------- src/query.h | 27 ++++++------ src/query_utils.cc | 6 +-- 6 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 18b8ef377..335123c97 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -200,17 +200,15 @@ bool Parse(CompilerInstance &Clang) { return true; } -void CompletionPreloadMain(CompletionManager *completion_manager) { +void CompletionPreloadMain(CompletionManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. - auto request = completion_manager->preload_requests_.Dequeue(); + auto request = manager->preload_requests_.Dequeue(); // If we don't get a session then that means we don't care about the file // anymore - abandon the request. - std::shared_ptr session = - completion_manager->TryGetSession(request.path, - false /*mark_as_completion*/, - false /*create_if_needed*/); + std::shared_ptr session = manager->TryGetSession( + request.path, false /*mark_as_completion*/, false /*create_if_needed*/); if (!session) continue; @@ -222,6 +220,11 @@ void CompletionPreloadMain(CompletionManager *completion_manager) { if (std::unique_ptr CI = BuildCompilerInvocation(args, session->FS)) session->BuildPreamble(*CI); + if (g_config->diagnostics.onSave) { + lsTextDocumentIdentifier document; + document.uri = lsDocumentUri::FromPath(request.path); + manager->diagnostic_request_.PushBack({document}, true); + } } } @@ -416,7 +419,7 @@ void CompletionManager::DiagnosticsUpdate( void CompletionManager::NotifyView(const std::string &path) { // Only reparse the file if we create a new CompletionSession. if (EnsureCompletionOrCreatePreloadSession(path)) - preload_requests_.PushBack(PreloadRequest(path), true); + preload_requests_.PushBack(PreloadRequest{path}, true); } void CompletionManager::NotifySave(const std::string &filename) { @@ -425,7 +428,7 @@ void CompletionManager::NotifySave(const std::string &filename) { // EnsureCompletionOrCreatePreloadSession(filename); - preload_requests_.PushBack(PreloadRequest(filename), true); + preload_requests_.PushBack(PreloadRequest{filename}, true); } void CompletionManager::NotifyClose(const std::string &filename) { diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 81fd00209..c72326922 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -86,10 +86,6 @@ struct CompletionManager { using OnDropped = std::function; struct PreloadRequest { - PreloadRequest(const std::string &path) - : request_time(std::chrono::high_resolution_clock::now()), path(path) {} - - std::chrono::time_point request_time; std::string path; }; struct CompletionRequest { diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 08520a92e..0badb21c1 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -49,8 +49,6 @@ struct Handler_TextDocumentDidSave Project::Entry entry = project->FindCompilationEntryForFile(path); pipeline::Index(entry.filename, entry.args, IndexMode::Normal); clang_complete->NotifySave(path); - if (g_config->diagnostics.onSave) - clang_complete->DiagnosticsUpdate(params.textDocument); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); diff --git a/src/query.cc b/src/query.cc index 6ec741436..e84040d40 100644 --- a/src/query.cc +++ b/src/query.cc @@ -250,36 +250,37 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta; }; - auto UpdateUses = [&](Usr usr, SymbolKind kind, - llvm::DenseMap &entity_usr, - auto &entities, auto &p, bool hint_implicit) { - auto R = entity_usr.try_emplace({usr}, entity_usr.size()); - if (R.second) - vars.emplace_back().usr = usr; - auto &entity = entities[R.first->second]; - for (Use &use : p.first) { - if (hint_implicit && use.role & Role::Implicit) { - // Make ranges of implicit function calls larger (spanning one more - // column to the left/right). This is hacky but useful. e.g. - // textDocument/definition on the space/semicolon in `A a;` or ` 42;` - // will take you to the constructor. - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; - } - Ref(prev_lid2file_id, usr, kind, use, -1); - } - RemoveRange(entity.uses, p.first); - for (Use &use : p.second) { - if (hint_implicit && use.role & Role::Implicit) { - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; - } - Ref(lid2file_id, usr, kind, use, 1); - } - AddRange(entity.uses, p.second); - }; + auto UpdateUses = + [&](Usr usr, SymbolKind kind, + llvm::DenseMap &entity_usr, + auto &entities, auto &p, bool hint_implicit) { + auto R = entity_usr.try_emplace(usr, entity_usr.size()); + if (R.second) + vars.emplace_back().usr = usr; + auto &entity = entities[R.first->second]; + for (Use &use : p.first) { + if (hint_implicit && use.role & Role::Implicit) { + // Make ranges of implicit function calls larger (spanning one more + // column to the left/right). This is hacky but useful. e.g. + // textDocument/definition on the space/semicolon in `A a;` or ` + // 42;` will take you to the constructor. + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; + } + Ref(prev_lid2file_id, usr, kind, use, -1); + } + RemoveRange(entity.uses, p.first); + for (Use &use : p.second) { + if (hint_implicit && use.role & Role::Implicit) { + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; + } + Ref(lid2file_id, usr, kind, use, 1); + } + AddRange(entity.uses, p.second); + }; if (u->files_removed) files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def = diff --git a/src/query.h b/src/query.h index 7cf17018d..1d4ebf3cb 100644 --- a/src/query.h +++ b/src/query.h @@ -147,14 +147,11 @@ struct IndexUpdate { UseUpdate vars_uses; }; -struct WrappedUsr { - Usr usr; -}; -template <> struct llvm::DenseMapInfo { - static inline WrappedUsr getEmptyKey() { return {0}; } - static inline WrappedUsr getTombstoneKey() { return {~0ULL}; } - static unsigned getHashValue(WrappedUsr w) { return w.usr; } - static bool isEqual(WrappedUsr l, WrappedUsr r) { return l.usr == r.usr; } +struct DenseMapInfoForUsr { + static inline Usr getEmptyKey() { return 0; } + static inline Usr getTombstoneKey() { return ~0ULL; } + static unsigned getHashValue(Usr w) { return w; } + static bool isEqual(Usr l, Usr r) { return l == r; } }; using Lid2file_id = std::unordered_map; @@ -164,7 +161,7 @@ using Lid2file_id = std::unordered_map; struct DB { std::vector files; llvm::StringMap name2file_id; - llvm::DenseMap func_usr, type_usr, var_usr; + llvm::DenseMap func_usr, type_usr, var_usr; std::vector funcs; std::vector types; std::vector vars; @@ -184,13 +181,13 @@ struct DB { std::vector> &&us); std::string_view GetSymbolName(SymbolIdx sym, bool qualified); - bool HasFunc(Usr usr) const { return func_usr.count({usr}); } - bool HasType(Usr usr) const { return type_usr.count({usr}); } - bool HasVar(Usr usr) const { return var_usr.count({usr}); } + bool HasFunc(Usr usr) const { return func_usr.count(usr); } + bool HasType(Usr usr) const { return type_usr.count(usr); } + bool HasVar(Usr usr) const { return var_usr.count(usr); } - QueryFunc &Func(Usr usr) { return funcs[func_usr[{usr}]]; } - QueryType &Type(Usr usr) { return types[type_usr[{usr}]]; } - QueryVar &Var(Usr usr) { return vars[var_usr[{usr}]]; } + QueryFunc &Func(Usr usr) { return funcs[func_usr[usr]]; } + QueryType &Type(Usr usr) { return types[type_usr[usr]]; } + QueryVar &Var(Usr usr) { return vars[var_usr[usr]]; } QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; } QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); } diff --git a/src/query_utils.cc b/src/query_utils.cc index af885525e..749b90888 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -30,9 +30,9 @@ int ComputeRangeSize(const Range &range) { } template -std::vector GetDeclarations(llvm::DenseMap &entity_usr, - std::vector &entities, - const std::vector &usrs) { +std::vector +GetDeclarations(llvm::DenseMap &entity_usr, + std::vector &entities, const std::vector &usrs) { std::vector ret; ret.reserve(usrs.size()); for (Usr usr : usrs) { From a607dcec248a2404e5122e2f7d692efb5cd60afa Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Wed, 12 Sep 2018 03:13:54 +0800 Subject: [PATCH 205/378] Normalize paths on Windows 1. Normalize paths in LSP document URIs and project root to forward slash and uppercase drive letters. 2. Normalize paths in compile_commands.json to forward slash and uppercase drive letters. 3. Normalize paths from directory listing to forward slash. (Drive letter should be same as input dir path, which is already uppercase since path of project root dir is normalized) 4. Add llvm::sys::path::convert_to_slash after certain llvm::sys::path and llvm::fs calls. --- src/clang_complete.cc | 2 +- src/clang_utils.cc | 2 +- src/filesystem.cc | 2 +- src/indexer.cc | 2 +- src/lsp.cc | 15 +++++++++++++-- src/platform_win.cc | 11 ++++++++--- src/project.cc | 8 +++++--- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 335123c97..3fa70c32c 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -40,7 +40,7 @@ namespace { std::string StripFileType(const std::string &path) { SmallString<128> Ret; sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path)); - return Ret.str(); + return sys::path::convert_to_slash(Ret); } bool LocationInRange(SourceLocation L, CharSourceRange R, diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 6a92b73ba..a58237e12 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -34,7 +34,7 @@ std::string FileName(const FileEntry &file) { if (!StartsWith(ret, g_config->projectRoot)) { SmallString<256> dest; sys::fs::real_path(ret, dest); - ret = dest.str(); + ret = sys::path::convert_to_slash(dest.str()); } return ret; } diff --git a/src/filesystem.cc b/src/filesystem.cc index 74eb836b8..613666ade 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -59,7 +59,7 @@ void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix, if (sys::fs::is_regular_file(Status)) { if (!dir_prefix) path = path.substr(folder.size()); - handler(path); + handler(sys::path::convert_to_slash(path)); } else if (recursive && sys::fs::is_directory(Status) && !seen.count(ID = Status.getUniqueID())) { curr.push_back(path); diff --git a/src/indexer.cc b/src/indexer.cc index a29988c92..4ae432f2b 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -567,7 +567,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!llvm::sys::path::is_absolute(Path) && !SM.getFileManager().makeAbsolutePath(Path)) return -1; - it->second.second = Path.str(); + it->second.second = llvm::sys::path::convert_to_slash(Path.str()); } return it->second.first; } diff --git a/src/lsp.cc b/src/lsp.cc index afb0b76c2..6fac3d6c0 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -220,10 +220,15 @@ void lsDocumentUri::SetPath(const std::string &path) { } std::string lsDocumentUri::GetPath() const { - if (raw_uri.compare(0, 8, "file:///")) + if (raw_uri.compare(0, 7, "file://")) { + LOG_S(WARNING) + << "Received potentially bad URI (not starting with file://): " + << raw_uri; return raw_uri; + } std::string ret; #ifdef _WIN32 + // Skipping the initial "/" on Windows size_t i = 8; #else size_t i = 7; @@ -236,8 +241,14 @@ std::string lsDocumentUri::GetPath() const { ret.push_back(from_hex(raw_uri[i + 1]) * 16 + from_hex(raw_uri[i + 2])); i += 2; } else - ret.push_back(raw_uri[i] == '\\' ? '/' : raw_uri[i]); + ret.push_back(raw_uri[i]); + } +#ifdef _WIN32 + std::replace(ret.begin(), ret.end(), '\\', '/'); + if (ret.size() > 1 && ret[0] >= 'a' && ret[0] <= 'z' && ret[1] == ':') { + ret[0] = toupper(ret[0]); } +#endif return ret; } diff --git a/src/platform_win.cc b/src/platform_win.cc index be03055ce..3acbe7e20 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -35,14 +35,19 @@ std::string NormalizePath(const std::string &path) { TCHAR buffer[MAX_PATH] = TEXT(""); TCHAR **lpp_part = {NULL}; + std::string result; retval = GetFullPathName(path.c_str(), MAX_PATH, buffer, lpp_part); // fail, return original if (retval == 0) - return path; + result = path; + else + result = buffer; - std::string result = buffer; std::replace(result.begin(), result.end(), '\\', '/'); - // std::transform(result.begin(), result.end(), result.begin(), ::tolower); + // Normalize drive letter. + if (result.size() > 1 && result[0] >= 'a' && result[0] <= 'z' && + result[1] == ':') + result[0] = toupper(result[0]); return result; } diff --git a/src/project.cc b/src/project.cc index 3cd4aa524..64c633081 100644 --- a/src/project.cc +++ b/src/project.cc @@ -172,7 +172,8 @@ struct ProjectProcessor { HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts(); for (auto &E : HeaderOpts.UserEntries) { - std::string path = ResolveIfRelative(entry.directory, E.Path); + std::string path = + NormalizePath(ResolveIfRelative(entry.directory, E.Path)); switch (E.Group) { default: config->angle_dirs.insert(path); @@ -327,8 +328,9 @@ LoadEntriesFromDirectory(ProjectConfig *project, ProjectProcessor proc(project); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { Project::Entry entry; - entry.directory = std::move(Cmd.Directory); - entry.filename = ResolveIfRelative(entry.directory, Cmd.Filename); + entry.directory = NormalizePath(Cmd.Directory); + entry.filename = + NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); entry.args = std::move(Cmd.CommandLine); proc.Process(entry); if (Seen.insert(entry.filename).second) From c7a6c5cd12a0184834be2571db28920346cc7ecd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 11 Sep 2018 23:31:06 -0700 Subject: [PATCH 206/378] Make $ccls/reload reset DB and reload cached index files $ccls/reload is renamed from $ccls/freshenIndex This is useful when DB (merged index) diverges from backing IndexFile. Also fix a semantic highlighting bug. --- CMakeLists.txt | 2 +- .../{ccls_freshenIndex.cc => ccls_reload.cc} | 34 ++++++++++++------- src/pipeline.cc | 11 ++++-- src/query.cc | 11 ++++++ src/query.h | 4 ++- 5 files changed, 45 insertions(+), 17 deletions(-) rename src/messages/{ccls_freshenIndex.cc => ccls_reload.cc} (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9574aad8d..01eead6c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,10 +212,10 @@ target_sources(ccls PRIVATE src/messages/ccls_callHierarchy.cc src/messages/ccls_callers.cc src/messages/ccls_fileInfo.cc - src/messages/ccls_freshenIndex.cc src/messages/ccls_inheritanceHierarchy.cc src/messages/ccls_memberHierarchy.cc src/messages/ccls_navigate.cc + src/messages/ccls_reload.cc src/messages/ccls_vars.cc src/messages/exit.cc src/messages/initialize.cc diff --git a/src/messages/ccls_freshenIndex.cc b/src/messages/ccls_reload.cc similarity index 78% rename from src/messages/ccls_freshenIndex.cc rename to src/messages/ccls_reload.cc index a49e0243a..6652b0491 100644 --- a/src/messages/ccls_freshenIndex.cc +++ b/src/messages/ccls_reload.cc @@ -25,9 +25,9 @@ using namespace ccls; #include namespace { -MethodType kMethodType = "$ccls/freshenIndex"; +MethodType kMethodType = "$ccls/reload"; -struct In_CclsFreshenIndex : public NotificationInMessage { +struct In_CclsReload : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { bool dependencies = true; @@ -36,15 +36,28 @@ struct In_CclsFreshenIndex : public NotificationInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, dependencies, whitelist, +MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist, blacklist); -MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params); -REGISTER_IN_MESSAGE(In_CclsFreshenIndex); +MAKE_REFLECT_STRUCT(In_CclsReload, params); +REGISTER_IN_MESSAGE(In_CclsReload); -struct Handler_CclsFreshenIndex : BaseMessageHandler { +struct Handler_CclsReload : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsFreshenIndex *request) override { - GroupMatch matcher(request->params.whitelist, request->params.blacklist); + void Run(In_CclsReload *request) override { + const auto ¶ms = request->params; + // Send index requests for every file. + if (params.whitelist.empty() && params.blacklist.empty()) { + { + std::lock_guard lock(vfs->mutex); + vfs->state.clear(); + } + db->clear(); + project->Index(working_files, lsRequestId()); + return; + } + + // TODO + GroupMatch matcher(params.whitelist, params.blacklist); std::queue q; // |need_index| stores every filename ever enqueued. @@ -89,10 +102,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { } } } - - // Send index requests for every file. - project->Index(working_files, lsRequestId()); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); +REGISTER_MESSAGE_HANDLER(Handler_CclsReload); } // namespace diff --git a/src/pipeline.cc b/src/pipeline.cc index be30a5f88..4ee4f9713 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -248,14 +248,19 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); + std::lock_guard lock(vfs->mutex); + vfs->state[path_to_index].loaded = true; } - for (const auto &dep : dependencies) - if (vfs->Mark(dep.first().str(), 0, 2) && - (prev = RawCacheLoad(dep.first().str()))) { + for (const auto &dep : dependencies) { + std::string path = dep.first().str(); + if (vfs->Mark(path, 0, 2) && (prev = RawCacheLoad(path))) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); + std::lock_guard lock(vfs->mutex); + vfs->state[path].loaded = true; } + } return true; } diff --git a/src/query.cc b/src/query.cc index e84040d40..d09f33b18 100644 --- a/src/query.cc +++ b/src/query.cc @@ -148,6 +148,17 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { return r; } +void DB::clear() { + files.clear(); + name2file_id.clear(); + func_usr.clear(); + type_usr.clear(); + var_usr.clear(); + funcs.clear(); + types.clear(); + vars.clear(); +} + template void DB::RemoveUsrs(SymbolKind kind, int file_id, const std::vector> &to_remove) { diff --git a/src/query.h b/src/query.h index 1d4ebf3cb..ea7d0bcf6 100644 --- a/src/query.h +++ b/src/query.h @@ -45,7 +45,7 @@ struct QueryFile { std::vector includes; // Parts of the file which are disabled. std::vector skipped_ranges; - // Used by |$ccls/freshenIndex|. + // Used by |$ccls/reload|. std::vector dependencies; }; @@ -166,6 +166,8 @@ struct DB { std::vector types; std::vector vars; + void clear(); + template void RemoveUsrs(SymbolKind kind, int file_id, const std::vector> &to_remove); From e2f29d7b1b3d81b01a21f9a1313598f383ce2aeb Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Sep 2018 11:12:00 -0700 Subject: [PATCH 207/378] pipeline improvement for files not having a project entry (e.g. .h) --- src/messages/textDocument_didChange.cc | 6 ++-- src/messages/textDocument_didOpen.cc | 10 +++--- src/messages/textDocument_didSave.cc | 4 +-- src/pipeline.cc | 44 +++++++++++++++----------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index 5b50714c8..7488ff2f5 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -39,10 +39,8 @@ struct Handler_TextDocumentDidChange const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); working_files->OnChange(params); - if (g_config->index.onChange) { - Project::Entry entry = project->FindCompilationEntryForFile(path); - pipeline::Index(entry.filename, entry.args, IndexMode::OnChange); - } + if (g_config->index.onChange) + pipeline::Index(path, {}, IndexMode::OnChange); clang_complete->NotifyView(path); if (g_config->diagnostics.onChange) clang_complete->DiagnosticsUpdate( diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 146c22c0c..939ec8bd1 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -69,12 +69,10 @@ struct Handler_TextDocumentDidOpen // Submit new index request if it is not a header file. if (SourceFileLanguage(path) != LanguageId::Unknown) { - Project::Entry entry = project->FindCompilationEntryForFile(path); - pipeline::Index(entry.filename, - params.args.size() ? params.args : entry.args, - IndexMode::Normal); - - clang_complete->FlushSession(entry.filename); + pipeline::Index( + path, params.args.size() ? params.args : std::vector{}, + IndexMode::Normal); + clang_complete->FlushSession(path); } clang_complete->NotifyView(path); diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 0badb21c1..87b7e7930 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -45,9 +45,7 @@ struct Handler_TextDocumentDidSave void Run(In_TextDocumentDidSave *request) override { const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); - - Project::Entry entry = project->FindCompilationEntryForFile(path); - pipeline::Index(entry.filename, entry.args, IndexMode::Normal); + pipeline::Index(path, {}, IndexMode::Normal); clang_complete->NotifySave(path); } }; diff --git a/src/pipeline.cc b/src/pipeline.cc index 4ee4f9713..dd52fcbc0 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -190,25 +190,23 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, return false; } - Project::Entry entry; - { - std::lock_guard lock(project->mutex_); - auto it = project->path_to_entry_index.find(request.path); - if (it != project->path_to_entry_index.end()) - entry = project->entries[it->second]; - else { - entry.filename = request.path; - entry.args = request.args; - } - } + Project::Entry entry = project->FindCompilationEntryForFile(request.path); + if (request.args.size()) + entry.args = request.args; std::string path_to_index = entry.filename; std::unique_ptr prev; - // Try to load the file from cache. std::optional write_time = LastWriteTime(path_to_index); if (!write_time) return true; int reparse = vfs->Stamp(path_to_index, *write_time); + if (request.path != path_to_index) { + std::optional mtime1 = LastWriteTime(request.path); + if (!mtime1) + return true; + if (vfs->Stamp(request.path, *mtime1)) + reparse = 2; + } if (g_config->index.onChange) reparse = 2; if (!vfs->Mark(path_to_index, g_thread_id, 1) && !reparse) @@ -257,8 +255,14 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); - std::lock_guard lock(vfs->mutex); - vfs->state[path].loaded = true; + { + std::lock_guard lock(vfs->mutex); + vfs->state[path].loaded = true; + } + if (entry.id >= 0) { + std::lock_guard lock(project->mutex_); + project->path_to_entry_index[path] = entry.id; + } } } return true; @@ -268,9 +272,9 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, std::vector> remapped; if (g_config->index.onChange) { - std::string content = wfiles->GetContent(request.path); + std::string content = wfiles->GetContent(path_to_index); if (content.size()) - remapped.emplace_back(request.path, content); + remapped.emplace_back(path_to_index, content); } auto indexes = idx::Index(completion, wfiles, vfs, entry.directory, path_to_index, entry.args, remapped); @@ -289,7 +293,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, for (std::unique_ptr &curr : indexes) { std::string path = curr->path; - bool do_update = path == path_to_index, loaded; + bool do_update = path == path_to_index || path == request.path, loaded; { std::lock_guard lock(vfs->mutex); VFS::State &st = vfs->state[path]; @@ -300,11 +304,13 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, loaded = st.loaded; st.loaded = true; } - if (!do_update) - continue; if (std::string reason; !matcher.IsMatch(path, &reason)) { LOG_IF_S(INFO, loud) << "skip emitting and storing index of " << path << " for " << reason; + do_update = false; + } + if (!do_update) { + vfs->Reset(path); continue; } From 6bca153ee307488e999e79f7715a311709e9f1e8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Sep 2018 13:46:20 -0700 Subject: [PATCH 208/378] Make $ccls/inheritanceHierarchy and textDocument/typeDefinition find declarations if definitions do not exist; spelling ranges of operator= --- index_tests/operators/operator.cc | 2 +- src/indexer.cc | 1 + src/messages/ccls_inheritanceHierarchy.cc | 3 ++ src/messages/textDocument_typeDefinition.cc | 34 +++++++++++++-------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 3a569983e..009db1c0b 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -45,7 +45,7 @@ Foo &operator += (const Foo&, const int&); "kind": 6, "storage": 0, "declarations": [], - "spell": "2:8-2:16|15041163540773201510|2|1026|-1", + "spell": "2:8-2:18|15041163540773201510|2|1026|-1", "extent": "2:3-2:27|15041163540773201510|2|0|-1", "bases": [], "derived": [], diff --git a/src/indexer.cc b/src/indexer.cc index 4ae432f2b..cc8fc8bcb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -679,6 +679,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { switch (OrigD->getKind()) { case Decl::CXXConversion: // *operator* int => *operator int* case Decl::CXXDestructor: // *~*A => *~A* + case Decl::CXXMethod: // *operator*= => *operator=* if (Loc.isFileID()) { SourceRange R = cast(OrigD)->getNameInfo().getSourceRange(); diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index bea195154..617198dcd 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -83,6 +83,9 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, if (def->spell) { if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) entry->location = *loc; + } else if (entity.declarations.size()) { + if (auto loc = GetLsLocation(m->db, m->working_files, entity.declarations[0])) + entry->location = *loc; } } else if (!derived) { entry->numChildren = 0; diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index ff1383f7c..307868502 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -42,32 +42,40 @@ struct Handler_TextDocumentTypeDefinition QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, - nullptr)) { + nullptr)) return; - } WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentTypeDefinition out; out.id = request->id; + auto Add = [&](const QueryType &type) { + for (const auto &def : type.def) + if (def.spell) { + if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, + g_config->xref.container)) + out.result.push_back(*ls_loc); + } + if (out.result.empty()) + for (const DeclRef &dr : type.declarations) + if (auto ls_loc = GetLsLocationEx(db, working_files, dr, + g_config->xref.container)) + out.result.push_back(*ls_loc); + }; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { - Usr usr = sym.usr; switch (sym.kind) { case SymbolKind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); - if (!def || !def->type) - continue; - usr = def->type; - [[fallthrough]]; + if (def && def->type) + Add(db->Type(def->type)); + break; } case SymbolKind::Type: { - QueryType &type = db->Type(usr); - for (const auto &def : type.def) - if (def.spell) { - if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, - g_config->xref.container)) - out.result.push_back(*ls_loc); + for (auto &def : db->GetType(sym).def) + if (def.alias_of) { + Add(db->Type(def.alias_of)); + break; } break; } From 196973178143303adfaf13d8393ff3459781f557 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Sep 2018 21:03:35 -0700 Subject: [PATCH 209/378] textDocument/documentSymbol --- src/messages/textDocument_documentSymbol.cc | 2 +- src/messages/workspace_symbol.cc | 3 +-- src/query_utils.cc | 10 +++------- src/query_utils.h | 8 +++----- src/symbol.h | 2 +- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 53b639600..9991cc931 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -84,7 +84,7 @@ struct Handler_TextDocumentDocumentSymbol for (auto [sym, refcnt] : symbol2refcnt) { if (refcnt <= 0) continue; if (std::optional info = - GetSymbolInfo(db, working_files, sym, false)) { + GetSymbolInfo(db, sym, false)) { if (sym.kind == SymbolKind::Var) { QueryVar &var = db->GetVar(sym); auto *def = var.AnyDef(); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 2449e0727..c78e94622 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -31,8 +31,7 @@ MethodType kMethodType = "workspace/symbol"; bool AddSymbol( DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed, std::vector> *result) { - std::optional info = - GetSymbolInfo(db, working_files, sym, true); + std::optional info = GetSymbolInfo(db, sym, true); if (!info) return false; diff --git a/src/query_utils.cc b/src/query_utils.cc index 749b90888..4390ae145 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -286,11 +286,8 @@ lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { return ret; } -// Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(DB *db, - WorkingFiles *working_files, - SymbolIdx sym, - bool detailed_name) { +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, + bool detailed) { switch (sym.kind) { case SymbolKind::Invalid: break; @@ -307,12 +304,11 @@ std::optional GetSymbolInfo(DB *db, default: { lsSymbolInformation info; EachEntityDef(db, sym, [&](const auto &def) { - if (detailed_name) + if (detailed) info.name = def.detailed_name; else info.name = def.Name(true); info.kind = def.kind; - info.containerName = def.detailed_name; return false; }); return info; diff --git a/src/query_utils.h b/src/query_utils.h index 262fbdfac..cd07d963b 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -47,11 +47,9 @@ std::optional GetLsLocationEx(DB *db, WorkingFiles *working_files, Use use, bool container); std::vector GetLsLocationExs(DB *db, WorkingFiles *working_files, const std::vector &refs); -// Returns a symbol. The symbol will have *NOT* have a location assigned. -std::optional GetSymbolInfo(DB *db, - WorkingFiles *working_files, - SymbolIdx sym, - bool detailed_name); +// Returns a symbol. The symbol will *NOT* have a location assigned. +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, + bool detailed); std::vector FindSymbolsAtLocation(WorkingFile *working_file, QueryFile *file, diff --git a/src/symbol.h b/src/symbol.h index a4f3c05d6..16e4de11d 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -76,6 +76,6 @@ struct lsSymbolInformation { std::string_view name; lsSymbolKind kind; lsLocation location; - std::string_view containerName; + std::optional containerName; }; MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); From a174105abe0c98905dfaa542bf71e1d3c9bfb9ba Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Sep 2018 23:07:47 -0700 Subject: [PATCH 210/378] Better diagnostics --- src/clang_complete.cc | 82 ++++++++++++++++++---- src/messages/textDocument_signatureHelp.cc | 2 +- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 3fa70c32c..078da29de 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -279,6 +279,34 @@ void CompletionMain(CompletionManager *completion_manager) { } } +llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) { + switch (Lvl) { + case DiagnosticsEngine::Ignored: + return "ignored"; + case DiagnosticsEngine::Note: + return "note"; + case DiagnosticsEngine::Remark: + return "remark"; + case DiagnosticsEngine::Warning: + return "warning"; + case DiagnosticsEngine::Error: + return "error"; + case DiagnosticsEngine::Fatal: + return "fatal error"; + } +} + +void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { + if (d.inside_main) + OS << llvm::sys::path::filename(d.file); + else + OS << d.file; + auto pos = d.range.start; + OS << ":" << (pos.line + 1) << ":" << (pos.column + 1) << ":" + << (d.inside_main ? " " : "\n"); + OS << diagLeveltoString(d.level) << ": " << d.message; +} + void DiagnosticMain(CompletionManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. @@ -307,30 +335,56 @@ void DiagnosticMain(CompletionManager *manager) { for (auto &Buf : Bufs) Buf.release(); - std::vector ls_diags; - for (auto &d : DC.Take()) { - if (!d.inside_main) - continue; - lsDiagnostic &ls_diag = ls_diags.emplace_back(); - ls_diag.range = lsRange{{d.range.start.line, d.range.start.column}, - {d.range.end.line, d.range.end.column}}; - ls_diag.message = d.message; + auto Fill = [](const DiagBase &d, lsDiagnostic &ret) { + ret.range = lsRange{{d.range.start.line, d.range.start.column}, + {d.range.end.line, d.range.end.column}}; switch (d.level) { case DiagnosticsEngine::Ignored: // llvm_unreachable - case DiagnosticsEngine::Note: case DiagnosticsEngine::Remark: - ls_diag.severity = lsDiagnosticSeverity::Information; - continue; + ret.severity = lsDiagnosticSeverity::Hint; + break; + case DiagnosticsEngine::Note: + ret.severity = lsDiagnosticSeverity::Information; + break; case DiagnosticsEngine::Warning: - ls_diag.severity = lsDiagnosticSeverity::Warning; + ret.severity = lsDiagnosticSeverity::Warning; break; case DiagnosticsEngine::Error: case DiagnosticsEngine::Fatal: - ls_diag.severity = lsDiagnosticSeverity::Error; + ret.severity = lsDiagnosticSeverity::Error; + break; } - ls_diag.code = d.category; + ret.code = d.category; + return ret; + }; + + std::vector ls_diags; + for (auto &d : DC.Take()) { + if (!d.inside_main) + continue; + std::string buf; + llvm::raw_string_ostream OS(buf); + lsDiagnostic &ls_diag = ls_diags.emplace_back(); + Fill(d, ls_diag); ls_diag.fixits_ = d.edits; + OS << d.message; + for (auto &n : d.notes) { + OS << "\n\n"; + printDiag(OS, n); + } + OS.flush(); + ls_diag.message = std::move(buf); + for (auto &n : d.notes) { + if (!n.inside_main) + continue; + lsDiagnostic &ls_diag1 = ls_diags.emplace_back(); + Fill(n, ls_diag1); + OS << n.message << "\n\n"; + printDiag(OS, d); + OS.flush(); + ls_diag1.message = std::move(buf); + } } manager->on_diagnostic_(path, ls_diags); } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 4fcbd764e..007003db1 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -51,7 +51,7 @@ MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters); struct lsSignatureHelp { std::vector signatures; int activeSignature = 0; - int activeParameter; + int activeParameter = 0; }; MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, activeParameter); From 70deeca8ad89fedd7f07af03a959dfe7f62d668f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 13 Sep 2018 00:18:37 -0700 Subject: [PATCH 211/378] Rename hierarchies to $ccls/{call,inheritance,member} bool flat = false; -> bool hierarchy = false; (set it to true to enable hierarchical view) Delete $ccls/callers (which is what $ccls/call does now) --- CMakeLists.txt | 7 +- src/hierarchy.hh | 39 +++++++++ .../{ccls_callHierarchy.cc => ccls_call.cc} | 48 ++++++----- src/messages/ccls_callers.cc | 62 -------------- ...itanceHierarchy.cc => ccls_inheritance.cc} | 72 +++++++--------- ...ccls_memberHierarchy.cc => ccls_member.cc} | 85 ++++++++----------- src/query_utils.cc | 12 --- src/query_utils.h | 20 ----- 8 files changed, 137 insertions(+), 208 deletions(-) create mode 100644 src/hierarchy.hh rename src/messages/{ccls_callHierarchy.cc => ccls_call.cc} (83%) delete mode 100644 src/messages/ccls_callers.cc rename src/messages/{ccls_inheritanceHierarchy.cc => ccls_inheritance.cc} (72%) rename src/messages/{ccls_memberHierarchy.cc => ccls_member.cc} (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01eead6c2..20a4bd918 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,11 +209,10 @@ target_sources(ccls PRIVATE ) target_sources(ccls PRIVATE - src/messages/ccls_callHierarchy.cc - src/messages/ccls_callers.cc + src/messages/ccls_call.cc src/messages/ccls_fileInfo.cc - src/messages/ccls_inheritanceHierarchy.cc - src/messages/ccls_memberHierarchy.cc + src/messages/ccls_inheritance.cc + src/messages/ccls_member.cc src/messages/ccls_navigate.cc src/messages/ccls_reload.cc src/messages/ccls_vars.cc diff --git a/src/hierarchy.hh b/src/hierarchy.hh new file mode 100644 index 000000000..c79cbd0d8 --- /dev/null +++ b/src/hierarchy.hh @@ -0,0 +1,39 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#pragma once + +#include "lsp.h" + +#include +#include + +template +void FlattenHierarchy(const Node &root, Out_LocationList &out) { + std::queue q; + for (auto &entry : root.children) + q.push(&entry); + while (q.size()) { + auto *entry = q.front(); + q.pop(); + if (entry->location.uri.raw_uri.size()) + out.result.push_back({entry->location}); + for (auto &entry1 : entry->children) + q.push(&entry1); + } + std::sort(out.result.begin(), out.result.end()); + out.result.erase(std::unique(out.result.begin(), out.result.end()), + out.result.end()); +} diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_call.cc similarity index 83% rename from src/messages/ccls_callHierarchy.cc rename to src/messages/ccls_call.cc index ce593425d..98016480b 100644 --- a/src/messages/ccls_callHierarchy.cc +++ b/src/messages/ccls_call.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "hierarchy.hh" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" @@ -22,7 +23,7 @@ using namespace ccls; namespace { -MethodType kMethodType = "$ccls/callHierarchy"; +MethodType kMethodType = "$ccls/call"; enum class CallType : uint8_t { Direct = 0, @@ -36,7 +37,7 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct In_CclsCallHierarchy : public RequestInMessage { +struct In_CclsCall : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -56,15 +57,16 @@ struct In_CclsCallHierarchy : public RequestInMessage { CallType callType = CallType::All; bool qualified = true; int levels = 1; + bool hierarchy = false; }; Params params; }; -MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id, - callee, callType, qualified, levels); -MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CclsCallHierarchy); +MAKE_REFLECT_STRUCT(In_CclsCall::Params, textDocument, position, id, + callee, callType, qualified, levels, hierarchy); +MAKE_REFLECT_STRUCT(In_CclsCall, id, params); +REGISTER_IN_MESSAGE(In_CclsCall); -struct Out_CclsCallHierarchy : public lsOutMessage { +struct Out_CclsCall : public lsOutMessage { struct Entry { Usr usr; std::string id; @@ -79,12 +81,12 @@ struct Out_CclsCallHierarchy : public lsOutMessage { lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType, +MAKE_REFLECT_STRUCT(Out_CclsCall::Entry, id, name, location, callType, numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, jsonrpc, id, +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCall, jsonrpc, id, result); -bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee, +bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, CallType call_type, bool qualified, int levels) { const QueryFunc &func = m->db->Func(entry->usr); const QueryFunc::Def *def = func.AnyDef(); @@ -94,7 +96,7 @@ bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee, auto handle = [&](Use use, CallType call_type1) { entry->numChildren++; if (levels > 0) { - Out_CclsCallHierarchy::Entry entry1; + Out_CclsCall::Entry entry1; entry1.id = std::to_string(use.usr); entry1.usr = use.usr; if (auto loc = GetLsLocation(m->db, m->working_files, use)) @@ -160,17 +162,17 @@ bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee, return true; } -struct Handler_CclsCallHierarchy : BaseMessageHandler { +struct Handler_CclsCall : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional + std::optional BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified, int levels) { const auto *def = db->Func(root_usr).AnyDef(); if (!def) return {}; - Out_CclsCallHierarchy::Entry entry; + Out_CclsCall::Entry entry; entry.id = std::to_string(root_usr); entry.usr = root_usr; entry.callType = CallType::Direct; @@ -183,9 +185,9 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler { return entry; } - void Run(In_CclsCallHierarchy *request) override { + void Run(In_CclsCall *request) override { auto ¶ms = request->params; - Out_CclsCallHierarchy out; + Out_CclsCall out; out.id = request->id; if (params.id.size()) { @@ -194,7 +196,7 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler { } catch (...) { return; } - Out_CclsCallHierarchy::Entry entry; + Out_CclsCall::Entry entry; entry.id = std::to_string(params.usr); entry.usr = params.usr; entry.callType = CallType::Direct; @@ -219,9 +221,17 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler { } } - pipeline::WriteStdout(kMethodType, out); + if (params.hierarchy) { + pipeline::WriteStdout(kMethodType, out); + return; + } + Out_LocationList out1; + out1.id = request->id; + if (out.result) + FlattenHierarchy(*out.result, out1); + pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsCall); } // namespace diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc deleted file mode 100644 index 7b6c28f9a..000000000 --- a/src/messages/ccls_callers.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "$ccls/callers"; - -struct In_CclsCallers : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_CclsCallers, id, params); -REGISTER_IN_MESSAGE(In_CclsCallers); - -struct Handler_CclsCallers : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsCallers *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - Out_LocationList out; - out.id = request->id; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - if (sym.kind == SymbolKind::Func) { - QueryFunc &func = db->GetFunc(sym); - std::vector uses = func.uses; - for (Use func_ref : GetUsesForAllBases(db, func)) - uses.push_back(func_ref); - for (Use func_ref : GetUsesForAllDerived(db, func)) - uses.push_back(func_ref); - out.result = GetLsLocationExs(db, working_files, uses); - break; - } - } - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsCallers); -} // namespace diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritance.cc similarity index 72% rename from src/messages/ccls_inheritanceHierarchy.cc rename to src/messages/ccls_inheritance.cc index 617198dcd..0ed235850 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritance.cc @@ -13,18 +13,18 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "hierarchy.hh" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" using namespace ccls; -#include #include namespace { -MethodType kMethodType = "$ccls/inheritanceHierarchy"; +MethodType kMethodType = "$ccls/inheritance"; -struct In_CclsInheritanceHierarchy : public RequestInMessage { +struct In_CclsInheritance : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // If id+kind are specified, expand a node; otherwise textDocument+position @@ -40,17 +40,17 @@ struct In_CclsInheritanceHierarchy : public RequestInMessage { bool derived = false; bool qualified = true; int levels = 1; - bool flat = false; + bool hierarchy = false; } params; }; -MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, textDocument, position, - id, kind, derived, qualified, levels, flat); -MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); +MAKE_REFLECT_STRUCT(In_CclsInheritance::Params, textDocument, position, + id, kind, derived, qualified, levels, hierarchy); +MAKE_REFLECT_STRUCT(In_CclsInheritance, id, params); +REGISTER_IN_MESSAGE(In_CclsInheritance); -struct Out_CclsInheritanceHierarchy - : public lsOutMessage { +struct Out_CclsInheritance + : public lsOutMessage { struct Entry { Usr usr; std::string id; @@ -66,16 +66,16 @@ struct Out_CclsInheritanceHierarchy lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name, +MAKE_REFLECT_STRUCT(Out_CclsInheritance::Entry, id, kind, name, location, numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, jsonrpc, +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritance, jsonrpc, id, result); -bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, +bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry, bool derived, bool qualified, int levels); template -bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, +bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry, bool derived, bool qualified, int levels, Q &entity) { const auto *def = entity.AnyDef(); if (def) { @@ -97,7 +97,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, for (auto usr : entity.derived) { if (!seen.insert(usr).second) continue; - Out_CclsInheritanceHierarchy::Entry entry1; + Out_CclsInheritance::Entry entry1; entry1.id = std::to_string(usr); entry1.usr = usr; entry1.kind = entry->kind; @@ -112,7 +112,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, for (auto usr : def->bases) { if (!seen.insert(usr).second) continue; - Out_CclsInheritanceHierarchy::Entry entry1; + Out_CclsInheritance::Entry entry1; entry1.id = std::to_string(usr); entry1.usr = usr; entry1.kind = entry->kind; @@ -126,7 +126,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, return true; } -bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, +bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry, bool derived, bool qualified, int levels) { if (entry->kind == SymbolKind::Func) return ExpandHelper(m, entry, derived, qualified, levels, @@ -136,13 +136,13 @@ bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, m->db->Type(entry->usr)); } -struct Handler_CclsInheritanceHierarchy - : BaseMessageHandler { +struct Handler_CclsInheritance + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional + std::optional BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) { - Out_CclsInheritanceHierarchy::Entry entry; + Out_CclsInheritance::Entry entry; entry.id = std::to_string(sym.usr); entry.usr = sym.usr; entry.kind = sym.kind; @@ -150,18 +150,18 @@ struct Handler_CclsInheritanceHierarchy return entry; } - void Run(In_CclsInheritanceHierarchy *request) override { + void Run(In_CclsInheritance *request) override { auto ¶ms = request->params; - Out_CclsInheritanceHierarchy out; + Out_CclsInheritance out; out.id = request->id; - if (!params.flat && params.id.size()) { + if (params.id.size()) { try { params.usr = std::stoull(params.id); } catch (...) { return; } - Out_CclsInheritanceHierarchy::Entry entry; + Out_CclsInheritance::Entry entry; entry.id = std::to_string(params.usr); entry.usr = params.usr; entry.kind = params.kind; @@ -184,31 +184,17 @@ struct Handler_CclsInheritanceHierarchy } } - if (!params.flat) { + if (params.hierarchy) { pipeline::WriteStdout(kMethodType, out); return; } Out_LocationList out1; out1.id = request->id; - if (out.result) { - std::queue q; - for (auto &entry1 : out.result->children) - q.push(&entry1); - while (q.size()) { - auto *entry = q.front(); - q.pop(); - if (entry->location.uri.raw_uri.size()) - out1.result.push_back({entry->location}); - for (auto &entry1 : entry->children) - q.push(&entry1); - } - std::sort(out1.result.begin(), out1.result.end()); - out1.result.erase(std::unique(out1.result.begin(), out1.result.end()), - out1.result.end()); - } + if (out.result) + FlattenHierarchy(*out.result, out1); pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsInheritance); } // namespace diff --git a/src/messages/ccls_memberHierarchy.cc b/src/messages/ccls_member.cc similarity index 78% rename from src/messages/ccls_memberHierarchy.cc rename to src/messages/ccls_member.cc index 7de03d9e4..d70add570 100644 --- a/src/messages/ccls_memberHierarchy.cc +++ b/src/messages/ccls_member.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "hierarchy.hh" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" @@ -21,13 +22,12 @@ using namespace ccls; #include using namespace clang; -#include #include namespace { -MethodType kMethodType = "$ccls/memberHierarchy"; +MethodType kMethodType = "$ccls/member"; -struct In_CclsMemberHierarchy : public RequestInMessage { +struct In_CclsMember : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -42,16 +42,16 @@ struct In_CclsMemberHierarchy : public RequestInMessage { bool qualified = false; int levels = 1; - bool flat = false; + bool hierarchy = false; } params; }; -MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, - qualified, levels, flat); -MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); -REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); +MAKE_REFLECT_STRUCT(In_CclsMember::Params, textDocument, position, id, + qualified, levels, hierarchy); +MAKE_REFLECT_STRUCT(In_CclsMember, id, params); +REGISTER_IN_MESSAGE(In_CclsMember); -struct Out_CclsMemberHierarchy : public lsOutMessage { +struct Out_CclsMember : public lsOutMessage { struct Entry { Usr usr; std::string id; @@ -67,21 +67,21 @@ struct Out_CclsMemberHierarchy : public lsOutMessage { lsRequestId id; std::optional result; }; -MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName, +MAKE_REFLECT_STRUCT(Out_CclsMember::Entry, id, name, fieldName, location, numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, jsonrpc, id, +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMember, jsonrpc, id, result); -bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, +bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, bool qualified, int levels); // Add a field to |entry| which is a Func/Type. -void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, +void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, const QueryVar &var, int64_t offset, bool qualified, int levels) { const QueryVar::Def *def1 = var.AnyDef(); if (!def1) return; - Out_CclsMemberHierarchy::Entry entry1; + Out_CclsMember::Entry entry1; // With multiple inheritance, the offset is incorrect. if (offset >= 0) { if (offset / 8 < 10) @@ -118,7 +118,7 @@ void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, } // Expand a type node by adding members recursively to it. -bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, +bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, bool qualified, int levels) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(int(entry->usr)); @@ -139,15 +139,16 @@ bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, const auto *def = stack.back()->AnyDef(); stack.pop_back(); if (def) { - EachDefinedType(m->db, def->bases, [&](QueryType &type1) { - if (!seen.count(type1.usr)) { + for (Usr usr : def->bases) { + auto &type1 = m->db->Type(usr); + if (type1.def.size()) { seen.insert(type1.usr); stack.push_back(&type1); } - }); + } if (def->alias_of) { const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); - Out_CclsMemberHierarchy::Entry entry1; + Out_CclsMember::Entry entry1; entry1.id = std::to_string(def->alias_of); entry1.usr = def->alias_of; if (def1 && def1->spell) { @@ -185,11 +186,11 @@ bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, return true; } -struct Handler_CclsMemberHierarchy - : BaseMessageHandler { +struct Handler_CclsMember + : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional + std::optional BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) { switch (kind) { default: @@ -199,7 +200,7 @@ struct Handler_CclsMemberHierarchy if (!def) return {}; - Out_CclsMemberHierarchy::Entry entry; + Out_CclsMember::Entry entry; // Not type, |id| is invalid. entry.name = def->Name(qualified); if (def->spell) { @@ -207,9 +208,11 @@ struct Handler_CclsMemberHierarchy GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - EachDefinedVar(db, def->vars, [&](QueryVar &var) { - DoField(this, &entry, var, -1, qualified, levels - 1); - }); + for (Usr usr : def->vars) { + auto &var = db->Var(usr); + if (var.def.size()) + DoField(this, &entry, var, -1, qualified, levels - 1); + } return entry; } case SymbolKind::Type: { @@ -217,7 +220,7 @@ struct Handler_CclsMemberHierarchy if (!def) return {}; - Out_CclsMemberHierarchy::Entry entry; + Out_CclsMember::Entry entry; entry.id = std::to_string(root_usr); entry.usr = root_usr; if (def->spell) { @@ -231,9 +234,9 @@ struct Handler_CclsMemberHierarchy } } - void Run(In_CclsMemberHierarchy *request) override { + void Run(In_CclsMember *request) override { auto ¶ms = request->params; - Out_CclsMemberHierarchy out; + Out_CclsMember out; out.id = request->id; if (params.id.size()) { @@ -242,7 +245,7 @@ struct Handler_CclsMemberHierarchy } catch (...) { return; } - Out_CclsMemberHierarchy::Entry entry; + Out_CclsMember::Entry entry; entry.id = std::to_string(params.usr); entry.usr = params.usr; // entry.name is empty as it is known by the client. @@ -277,31 +280,17 @@ struct Handler_CclsMemberHierarchy } } - if (!params.flat) { + if (params.hierarchy) { pipeline::WriteStdout(kMethodType, out); return; } Out_LocationList out1; out1.id = request->id; - if (out.result) { - std::queue q; - for (auto &entry1 : out.result->children) - q.push(&entry1); - while (q.size()) { - auto *entry = q.front(); - q.pop(); - if (entry->location.uri.raw_uri.size()) - out1.result.push_back({entry->location}); - for (auto &entry1 : entry->children) - q.push(&entry1); - } - std::sort(out1.result.begin(), out1.result.end()); - out1.result.erase(std::unique(out1.result.begin(), out1.result.end()), - out1.result.end()); - } + if (out.result) + FlattenHierarchy(*out.result, out1); pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); +REGISTER_MESSAGE_HANDLER(Handler_CclsMember); } // namespace diff --git a/src/query_utils.cc b/src/query_utils.cc index 4390ae145..c2e0f0b76 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -167,18 +167,6 @@ std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { return ret; } -std::optional GetLsPosition(WorkingFile *wfile, - const Position &position) { - if (!wfile || wfile->index_lines.empty()) - return lsPosition{position.line, position.column}; - - int column = position.column; - if (std::optional start = - wfile->GetBufferPosFromIndexPos(position.line, &column, false)) - return lsPosition{*start, column}; - return std::nullopt; -} - std::optional GetLsRange(WorkingFile *wfile, const Range &location) { if (!wfile || wfile->index_lines.empty()) diff --git a/src/query_utils.h b/src/query_utils.h index cd07d963b..0ec2501c5 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -34,8 +34,6 @@ std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym); std::vector GetUsesForAllBases(DB *db, QueryFunc &root); std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); -std::optional GetLsPosition(WorkingFile *working_file, - const Position &position); std::optional GetLsRange(WorkingFile *working_file, const Range &location); lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); @@ -105,21 +103,3 @@ void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { fn(obj); } } - -template -void EachDefinedType(DB *db, const std::vector &usrs, Fn &&fn) { - for (Usr usr : usrs) { - auto &obj = db->Type(usr); - if (!obj.def.empty()) - fn(obj); - } -} - -template -void EachDefinedVar(DB *db, const std::vector &usrs, Fn &&fn) { - for (Usr usr : usrs) { - auto &obj = db->Var(usr); - if (!obj.def.empty()) - fn(obj); - } -} From 56c6ec43dfd87ed2e44418b8d172307d87327a64 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Sep 2018 16:57:43 -0700 Subject: [PATCH 212/378] Skip informative scope foo:: --- src/messages/textDocument_completion.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 663a4a887..545490da0 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -392,6 +392,11 @@ void BuildItem(std::vector &out, for (auto i = first; i < out.size(); i++) out[i].parameters_.push_back(text); break; + case CodeCompletionString::CK_Informative: + if (StringRef(Chunk.Text).endswith("::")) + continue; + text = Chunk.Text; + break; case CodeCompletionString::CK_ResultType: result_type = Chunk.Text; continue; From 34c1ebcefd3cd6c15fe6dabc280d9f148da2b0d6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Sep 2018 11:29:48 -0700 Subject: [PATCH 213/378] Remove [spell.start, spell.end) -> [spell.start, extent.end) hack --- src/messages/textDocument_definition.cc | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 1b616c80c..7cff442c8 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -43,7 +43,7 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { case SymbolKind::Var: { std::vector ret = GetNonDefDeclarations(db, sym); - // If there is no declaration, jump the its type. + // If there is no declaration, jump to its type. if (ret.empty()) { for (auto &def : db->GetVar(sym).def) if (def.type) { @@ -76,44 +76,45 @@ struct Handler_TextDocumentDefinition out.id = request->id; Maybe range; + SymbolKind kind; Maybe on_def; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); lsPosition &ls_pos = params.position; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { - if (!range) + if (!range) { range = sym.range; - else if (!(*range == sym.range)) + kind = sym.kind; + } else if (!(sym.range == *range && sym.kind == kind)) { break; + } // Found symbol. Return definition. // Special cases which are handled: // - symbol has declaration but no definition (ie, pure virtual) - // - start at spelling but end at extent for better mouse tooltip // - goto declaration while in definition of recursive type std::vector uses; EachEntityDef(db, sym, [&](const auto &def) { - if (def.spell && def.extent) { + if (def.spell) { Use spell = *def.spell; - // If on a definition, clear |uses| to find declarations below. if (spell.file_id == file_id && spell.range.Contains(ls_pos.line, ls_pos.character)) { on_def = spell; uses.clear(); return false; } - // We use spelling start and extent end because this causes vscode - // to highlight the entire definition when previewing / hoving with - // the mouse. - spell.range.end = def.extent->range.end; uses.push_back(spell); } return true; }); + // |uses| is empty if on a declaration/definition, otherwise it includes + // all declarations/definitions. if (uses.empty()) { - // The symbol has no definition or the cursor is on a definition. - uses = GetNonDefDeclarationTargets(db, sym); + for (Use use : GetNonDefDeclarationTargets(db, sym)) + if (!(use.file_id == file_id && + use.range.Contains(ls_pos.line, ls_pos.character))) + uses.push_back(use); // There is no declaration but the cursor is on a definition. if (uses.empty() && on_def) uses.push_back(*on_def); From a18977b9fc384509f6fd4b1b2588c329e39b25bd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Sep 2018 11:07:15 -0700 Subject: [PATCH 214/378] Add clang.pathMappings to reuse cache files with differect source paths --- src/clang_tu.cc | 3 ++ src/config.cc | 13 ++++++++ src/config.h | 19 ++++++++++- src/messages/initialize.cc | 9 +++--- src/pipeline.cc | 7 ++-- src/project.cc | 19 ++++------- src/serializer.cc | 65 +++++++++++++++++++++++++++----------- src/serializers/json.h | 2 ++ 8 files changed, 99 insertions(+), 38 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index d4646705b..ecac6ab7b 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -16,6 +16,7 @@ limitations under the License. #include "clang_tu.h" #include "clang_utils.h" +#include "config.h" #include using namespace clang; @@ -67,9 +68,11 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, std::unique_ptr BuildCompilerInvocation(const std::vector &args, IntrusiveRefCntPtr VFS) { + std::string save = "-resource-dir=" + g_config->clang.resourceDir; std::vector cargs; for (auto &arg : args) cargs.push_back(arg.c_str()); + cargs.push_back(save.c_str()); IntrusiveRefCntPtr Diags( CompilerInstance::createDiagnostics(new DiagnosticOptions)); std::unique_ptr CI = diff --git a/src/config.cc b/src/config.cc index bd0ecc2bd..47dbfd005 100644 --- a/src/config.cc +++ b/src/config.cc @@ -17,3 +17,16 @@ limitations under the License. Config *g_config; thread_local int g_thread_id; + +namespace ccls { +void DoPathMapping(std::string &arg) { + for (const std::string &mapping : g_config->clang.pathMappings) { + auto colon = mapping.find(':'); + if (colon != std::string::npos) { + auto p = arg.find(mapping.substr(0, colon)); + if (p != std::string::npos) + arg.replace(p, colon, mapping.substr(colon + 1)); + } + } +} +} diff --git a/src/config.h b/src/config.h index 19093af1b..23b2fdb8d 100644 --- a/src/config.h +++ b/src/config.h @@ -61,6 +61,18 @@ struct Config { // Additional arguments to pass to clang. std::vector extraArgs; + // Translate absolute paths in compile_commands.json entries, .ccls options + // and cache files. This allows to reuse cache files built otherwhere if the + // source paths are different. + // + // This is a list of colon-separated strings, e.g. ["/container:/host"] + // + // An entry of "clang -I /container/include /container/a.cc" will be + // translated to "clang -I /host/include /host/a.cc". This is simple string + // replacement, so "clang /prefix/container/a.cc" will become "clang + // /prefix/host/a.cc". + std::vector pathMappings; + // Value to use for clang -resource-dir if not specified. // // This option defaults to clang -print-resource-dir and should not be @@ -235,7 +247,8 @@ struct Config { int maxNum = 2000; } xref; }; -MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, resourceDir); +MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, + resourceDir); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, @@ -258,3 +271,7 @@ MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, extern Config *g_config; thread_local extern int g_thread_id; + +namespace ccls { +void DoPathMapping(std::string &arg); +} diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index c4516ef13..f93c04943 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -453,6 +453,7 @@ struct Handler_Initialize : BaseMessageHandler { // Ensure there is a resource directory. if (g_config->clang.resourceDir.empty()) g_config->clang.resourceDir = GetDefaultResourceDirectory(); + DoPathMapping(g_config->clang.resourceDir); LOG_S(INFO) << "Using -resource-dir=" << g_config->clang.resourceDir; // Send initialization before starting indexers, so we don't send a @@ -471,10 +472,10 @@ struct Handler_Initialize : BaseMessageHandler { if (g_config->cacheDirectory.size()) { // Create two cache directories for files inside and outside of the // project. - sys::fs::create_directories(g_config->cacheDirectory + - EscapeFileName(g_config->projectRoot)); - sys::fs::create_directories(g_config->cacheDirectory + '@' + - EscapeFileName(g_config->projectRoot)); + auto len = g_config->projectRoot.size(); + std::string escaped = EscapeFileName(g_config->projectRoot.substr(0, len - 1)); + sys::fs::create_directories(g_config->cacheDirectory + escaped); + sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); } diag_pub->Init(); diff --git a/src/pipeline.cc b/src/pipeline.cc index dd52fcbc0..67e5706c7 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -136,12 +136,13 @@ std::string AppendSerializationFormat(const std::string &base) { std::string GetCachePath(const std::string &source_file) { std::string cache_file; - size_t len = g_config->projectRoot.size(); + auto len = g_config->projectRoot.size(); if (StartsWith(source_file, g_config->projectRoot)) { - cache_file = EscapeFileName(g_config->projectRoot) + + cache_file = EscapeFileName(g_config->projectRoot.substr(0, len - 1)) + '/' + EscapeFileName(source_file.substr(len)); } else { - cache_file = '@' + EscapeFileName(g_config->projectRoot) + + cache_file = '@' + + EscapeFileName(g_config->projectRoot.substr(0, len - 1)) + '/' + EscapeFileName(source_file); } diff --git a/src/project.cc b/src/project.cc index 64c633081..2d6eed1e9 100644 --- a/src/project.cc +++ b/src/project.cc @@ -117,17 +117,6 @@ struct ProjectProcessor { } hash_combine(hash, std::hash{}(arg)); } - for (size_t i = 1; i < args.size(); i++) - // This is most likely the file path we will be passing to clang. The - // path needs to be absolute, otherwise clang_codeCompleteAt is extremely - // slow. See - // https://github.com/cquery-project/cquery/commit/af63df09d57d765ce12d40007bf56302a0446678. - if (args[i][0] != '-' && EndsWith(args[i], base_name)) { - args[i] = ResolveIfRelative(entry.directory, args[i]); - continue; - } - - args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-working-directory=" + entry.directory); if (!command_set.insert(hash).second) { @@ -197,8 +186,10 @@ ReadCompilerArgumentsFromFile(const std::string &path) { if (!MBOrErr) return {}; std::vector args; - for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) + for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) { args.push_back(*I); + DoPathMapping(args.back()); + } return args; } @@ -329,9 +320,13 @@ LoadEntriesFromDirectory(ProjectConfig *project, for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { Project::Entry entry; entry.directory = NormalizePath(Cmd.Directory); + DoPathMapping(entry.directory); entry.filename = NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); + DoPathMapping(entry.filename); entry.args = std::move(Cmd.CommandLine); + for (std::string &arg : entry.args) + DoPathMapping(arg); proc.Process(entry); if (Seen.insert(entry.filename).second) result.push_back(entry); diff --git a/src/serializer.cc b/src/serializer.cc index 41c10d9a5..e0f595352 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -159,26 +159,39 @@ void Reflect(Writer &visitor, std::unordered_map &map) { visitor.EndArray(); } -// Used by IndexFile::dependencies. Timestamps are emitted for Binary. -void Reflect(Reader &visitor, StringMap &map) { - visitor.IterArray([&](Reader &entry) { - std::string name; - Reflect(entry, name); - if (visitor.Format() == SerializeFormat::Binary) - Reflect(entry, map[name]); - else - map[name] = 0; - }); +// Used by IndexFile::dependencies. +void Reflect(Reader &vis, StringMap &v) { + std::string name; + if (vis.Format() == SerializeFormat::Json) { + auto &vis1 = static_cast(vis); + for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it) + v[it->name.GetString()] = it->value.GetInt64(); + } else { + vis.IterArray([&](Reader &entry) { + Reflect(entry, name); + Reflect(entry, v[name]); + }); + } } -void Reflect(Writer &visitor, StringMap &map) { - visitor.StartArray(map.size()); - for (auto &it : map) { - std::string key = it.first(); - Reflect(visitor, key); - if (visitor.Format() == SerializeFormat::Binary) - Reflect(visitor, it.second); +void Reflect(Writer &vis, StringMap &v) { + if (vis.Format() == SerializeFormat::Json) { + auto &vis1 = static_cast(vis); + vis.StartObject(); + for (auto &it : v) { + std::string key = it.first(); + vis1.m().Key(key.c_str()); + vis1.m().Int64(it.second); + } + vis.EndObject(); + } else { + vis.StartArray(v.size()); + for (auto &it : v) { + std::string key = it.first(); + Reflect(vis, key); + Reflect(vis, it.second); + } + vis.EndArray(); } - visitor.EndArray(); } // TODO: Move this to indexer.cc @@ -448,6 +461,22 @@ Deserialize(SerializeFormat format, const std::string &path, // Restore non-serialized state. file->path = path; + if (g_config->clang.pathMappings.size()) { + DoPathMapping(file->import_file); + for (std::string &arg : file->args) + DoPathMapping(arg); + for (auto &[_, path] : file->lid2path) + DoPathMapping(path); + for (auto &include : file->includes) + DoPathMapping(include.resolved_path); + StringMap dependencies; + for (auto &it : file->dependencies) { + std::string path = it.first().str(); + DoPathMapping(path); + dependencies[path] = it.second; + } + file->dependencies = std::move(dependencies); + } return file; } } // namespace ccls diff --git a/src/serializers/json.h b/src/serializers/json.h index 131556c26..fb3751bc2 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -27,6 +27,7 @@ class JsonReader : public Reader { public: JsonReader(rapidjson::GenericValue> *m) : m_(m) {} SerializeFormat Format() const override { return SerializeFormat::Json; } + rapidjson::GenericValue> &m() { return *m_; } bool IsBool() override { return m_->IsBool(); } bool IsNull() override { return m_->IsNull(); } @@ -95,6 +96,7 @@ class JsonWriter : public Writer { public: JsonWriter(rapidjson::Writer *m) : m_(m) {} SerializeFormat Format() const override { return SerializeFormat::Json; } + rapidjson::Writer &m() { return *m_; } void Null() override { m_->Null(); } void Bool(bool x) override { m_->Bool(x); } From 14b73f0d6f69b2be0780ecde9d72266b4abf5cfc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Sep 2018 16:32:06 -0700 Subject: [PATCH 215/378] Add hierarchicalDocumentSymbolSupport --- src/config.h | 5 +- src/indexer.cc | 23 ++-- src/messages/initialize.cc | 12 +- src/messages/textDocument_documentSymbol.cc | 113 ++++++++++++++++++ .../workspace_didChangeWatchedFiles.cc | 22 ++-- 5 files changed, 147 insertions(+), 28 deletions(-) diff --git a/src/config.h b/src/config.h index 23b2fdb8d..1b7b7ae57 100644 --- a/src/config.h +++ b/src/config.h @@ -81,6 +81,8 @@ struct Config { } clang; struct ClientCapability { + // TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport + bool hierarchicalDocumentSymbolSupport = false; // TextDocumentClientCapabilities.completion.completionItem.snippetSupport bool snippetSupport = false; } client; @@ -249,7 +251,8 @@ struct Config { }; MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, resourceDir); -MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); +MAKE_REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, + snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, dropOldRequests, duplicateOptional, filterAndSort, diff --git a/src/indexer.cc b/src/indexer.cc index cc8fc8bcb..e4c86d312 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -904,22 +904,23 @@ class IndexDataConsumer : public index::IndexDataConsumer { type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) { + StringRef Tag; + switch (RD->getTagKind()) { + case TTK_Struct: Tag = "struct"; break; + case TTK_Interface: Tag = "__interface"; break; + case TTK_Union: Tag = "union"; break; + case TTK_Class: Tag = "class"; break; + case TTK_Enum: Tag = "enum"; break; + } if (TypedefNameDecl *TD = RD->getTypedefNameForAnonDecl()) { StringRef Name = TD->getName(); - StringRef Tag; - switch (RD->getTagKind()) { - case TTK_Struct: Tag = "struct "; break; - case TTK_Interface: Tag = "__interface "; break; - case TTK_Union: Tag = "union "; break; - case TTK_Class: Tag = "class "; break; - case TTK_Enum: Tag = "enum "; break; - } - std::string name = ("anon " + Tag + Name).str(); + std::string name = ("anon " + Tag + " " + Name).str(); type->def.detailed_name = Intern(name); type->def.short_name_size = name.size(); } else { - // e.g. "struct {}" - SetName(OrigD, "", "", type->def); + std::string name = ("anon " + Tag).str(); + type->def.detailed_name = Intern(name); + type->def.short_name_size = name.size(); } } if (is_def) { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index f93c04943..407f7b184 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -270,6 +270,10 @@ struct lsTextDocumentClientCapabilities { } completionItem; } completion; + struct lsDocumentSymbol { + bool hierarchicalDocumentSymbolSupport = false; + } documentSymbol; + struct lsGenericDynamicReg { // Whether foo supports dynamic registration. std::optional dynamicRegistration; @@ -291,6 +295,8 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, dynamicRegistration, willSave, willSaveWaitUntil, didSave); MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion, dynamicRegistration, completionItem); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsDocumentSymbol, + hierarchicalDocumentSymbolSupport); MAKE_REFLECT_STRUCT( lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem, snippetSupport); @@ -299,8 +305,8 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg, MAKE_REFLECT_STRUCT( lsTextDocumentClientCapabilities::CodeLensRegistrationOptions, dynamicRegistration, resolveProvider); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, synchronization, - completion, rename); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, completion, + documentSymbol, rename, synchronization); struct lsClientCapabilities { // Workspace specific client capabilities. @@ -449,6 +455,8 @@ struct Handler_Initialize : BaseMessageHandler { const auto &capabilities = params.capabilities; g_config->client.snippetSupport = capabilities.textDocument.completion.completionItem.snippetSupport; + g_config->client.hierarchicalDocumentSymbolSupport = + capabilities.textDocument.documentSymbol.hierarchicalDocumentSymbolSupport; // Ensure there is a resource directory. if (g_config->clang.resourceDir.empty()) diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 9991cc931..f6064d196 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -19,6 +19,8 @@ limitations under the License. using namespace ccls; using namespace clang; +MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); + namespace { MethodType kMethodType = "textDocument/documentSymbol"; @@ -52,6 +54,28 @@ struct Out_TextDocumentDocumentSymbol }; MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result); +struct lsDocumentSymbol { + std::string name; + std::string detail; + lsSymbolKind kind; + lsRange range; + lsRange selectionRange; + std::vector> children; +}; +void Reflect(Writer &vis, std::unique_ptr &v); +MAKE_REFLECT_STRUCT(lsDocumentSymbol, name, detail, kind, range, selectionRange, + children); +void Reflect(Writer &vis, std::unique_ptr &v) { + Reflect(vis, *v); +} + +struct Out_HierarchicalDocumentSymbol + : public lsOutMessage { + lsRequestId id; + std::vector> result; +}; +MAKE_REFLECT_STRUCT(Out_HierarchicalDocumentSymbol, jsonrpc, id, result); + struct Handler_TextDocumentDocumentSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -63,6 +87,9 @@ struct Handler_TextDocumentDocumentSymbol if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file, &file_id)) return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; const auto &symbol2refcnt = params.all ? file->symbol2refcnt : file->outline2refcnt; @@ -78,6 +105,92 @@ struct Handler_TextDocumentDocumentSymbol out.result.push_back(ls_loc->range); std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); + } else if (g_config->client.hierarchicalDocumentSymbolSupport) { + std::unordered_map< + SymbolIdx, std::pair>> + sym2ds; + for (auto [sym, refcnt] : symbol2refcnt) { + if (refcnt <= 0) + continue; + auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); + if (!r.second) + continue; + auto &kv = r.first->second; + kv.second = std::make_unique(); + lsDocumentSymbol &ds = *kv.second; + WithEntity(db, sym, [&](const auto &entity) { + auto *def = entity.AnyDef(); + if (!def) + return; + ds.name = def->Name(false); + ds.detail = def->Name(true); + for (auto &def : entity.def) + if (def.file_id == file_id) { + if (!def.spell || !def.extent) + break; + ds.kind = def.kind; + if (auto ls_range = GetLsRange(wfile, def.extent->range)) + ds.range = *ls_range; + else + break; + if (auto ls_range = GetLsRange(wfile, def.spell->range)) + ds.selectionRange = *ls_range; + else + break; + kv.first = static_cast(&def); + } + }); + if (kv.first && sym.kind == SymbolKind::Var) + if (static_cast(kv.first)->is_local()) + kv.first = nullptr; + if (!kv.first) { + kv.second.reset(); + continue; + } + } + for (auto &[sym, def_ds] : sym2ds) { + if (!def_ds.second) + continue; + lsDocumentSymbol &ds = *def_ds.second; + switch (sym.kind) { + case SymbolKind::Func: { + auto &def = *static_cast(def_ds.first); + for (Usr usr1 : def.vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second.second) + ds.children.push_back(std::move(it->second.second)); + } + break; + } + case SymbolKind::Type: { + auto &def = *static_cast(def_ds.first); + for (Usr usr1 : def.funcs) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); + if (it != sym2ds.end() && it->second.second) + ds.children.push_back(std::move(it->second.second)); + } + for (Usr usr1 : def.types) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); + if (it != sym2ds.end() && it->second.second) + ds.children.push_back(std::move(it->second.second)); + } + for (auto [usr1, _] : def.vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second.second) + ds.children.push_back(std::move(it->second.second)); + } + break; + } + default: + break; + } + } + Out_HierarchicalDocumentSymbol out; + out.id = request->id; + for (auto &[sym, def_ds] : sym2ds) + if (def_ds.second) + out.result.push_back(std::move(def_ds.second)); + pipeline::WriteStdout(kMethodType, out); } else { Out_TextDocumentDocumentSymbol out; out.id = request->id; diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index 8ba464083..fd5806d16 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -54,28 +54,22 @@ struct Handler_WorkspaceDidChangeWatchedFiles void Run(In_WorkspaceDidChangeWatchedFiles *request) override { for (lsFileEvent &event : request->params.changes) { std::string path = event.uri.GetPath(); - Project::Entry entry; - { - std::lock_guard lock(project->mutex_); - auto it = project->path_to_entry_index.find(path); - if (it == project->path_to_entry_index.end()) - continue; - entry = project->entries[it->second]; - } - IndexMode mode = - working_files->GetFileByFilename(entry.filename) != nullptr - ? IndexMode::Normal - : IndexMode::NonInteractive; + IndexMode mode = working_files->GetFileByFilename(path) + ? IndexMode::Normal + : IndexMode::NonInteractive; switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - pipeline::Index(path, entry.args, mode); + pipeline::Index(path, {}, mode); if (mode == IndexMode::Normal) clang_complete->NotifySave(path); + else + clang_complete->FlushSession(path); break; } case lsFileChangeType::Deleted: - pipeline::Index(path, entry.args, mode); + pipeline::Index(path, {}, mode); + clang_complete->FlushSession(path); break; } } From 763106c3d41a8c198e24f8567ac989492b4eb6d2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 17 Sep 2018 18:03:59 -0700 Subject: [PATCH 216/378] Simplify pipeline and fix race --- src/config.cc | 1 - src/config.h | 1 - src/file_consumer.cc | 36 ++----- src/file_consumer.h | 8 +- src/indexer.cc | 4 +- src/match.cc | 17 +--- src/messages/ccls_reload.cc | 11 --- src/messages/initialize.cc | 1 - src/pipeline.cc | 191 +++++++++++++++++------------------- src/pipeline.hh | 1 + src/project.cc | 4 +- src/project.h | 2 - 12 files changed, 107 insertions(+), 170 deletions(-) diff --git a/src/config.cc b/src/config.cc index 47dbfd005..0d4b9039d 100644 --- a/src/config.cc +++ b/src/config.cc @@ -16,7 +16,6 @@ limitations under the License. #include "config.h" Config *g_config; -thread_local int g_thread_id; namespace ccls { void DoPathMapping(std::string &arg) { diff --git a/src/config.h b/src/config.h index 1b7b7ae57..816c024ca 100644 --- a/src/config.h +++ b/src/config.h @@ -273,7 +273,6 @@ MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, index, largeFileSize, workspaceSymbol, xref); extern Config *g_config; -thread_local extern int g_thread_id; namespace ccls { void DoPathMapping(std::string &arg); diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 3542b2638..7f8cca71a 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -69,43 +69,21 @@ VFS::State VFS::Get(const std::string &file) { auto it = state.find(file); if (it != state.end()) return it->second; - return {0, 0, 0}; + return {0, 0}; } -bool VFS::Mark(const std::string &file, int owner, int stage) { - std::lock_guard lock(mutex); - State &st = state[file]; - if (st.stage < stage) { - st.owner = owner; - st.stage = stage; - return true; - } else - return false; -} - -bool VFS::Stamp(const std::string &file, int64_t ts) { +bool VFS::Stamp(const std::string &file, int64_t ts, int64_t offset) { std::lock_guard lock(mutex); State &st = state[file]; if (st.timestamp < ts) { - st.timestamp = ts; + st.timestamp = ts + offset; return true; } else return false; } -void VFS::ResetLocked(const std::string &file) { - State &st = state[file]; - if (st.owner == 0 || st.owner == g_thread_id) - st.stage = 0; -} - -void VFS::Reset(const std::string &file) { - std::lock_guard lock(mutex); - ResetLocked(file); -} - FileConsumer::FileConsumer(VFS *vfs, const std::string &parse_file) - : vfs_(vfs), parse_file_(parse_file), thread_id_(g_thread_id) {} + : vfs_(vfs), parse_file_(parse_file) {} IndexFile *FileConsumer::TryConsumeFile( const clang::FileEntry &File, @@ -116,9 +94,9 @@ IndexFile *FileConsumer::TryConsumeFile( return it->second.get(); std::string file_name = FileName(File); - // We did not take the file from global. Cache that we failed so we don't try - // again and return nullptr. - if (!vfs_->Mark(file_name, thread_id_, 2)) { + int64_t tim = File.getModificationTime(); + assert(tim); + if (!vfs_->Stamp(file_name, tim, 0)) { local_[UniqueID] = nullptr; return nullptr; } diff --git a/src/file_consumer.h b/src/file_consumer.h index d2c758946..ab2bebcca 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -43,18 +43,13 @@ struct FileContents { struct VFS { struct State { int64_t timestamp; - int owner; - int stage; bool loaded = false; }; mutable std::unordered_map state; mutable std::mutex mutex; State Get(const std::string &file); - bool Mark(const std::string &file, int owner, int stage); - bool Stamp(const std::string &file, int64_t ts); - void ResetLocked(const std::string &file); - void Reset(const std::string &file); + bool Stamp(const std::string &file, int64_t ts, int64_t offset); }; namespace std { @@ -95,5 +90,4 @@ struct FileConsumer { local_; VFS *vfs_; std::string parse_file_; - int thread_id_; }; diff --git a/src/indexer.cc b/src/indexer.cc index e4c86d312..592d35f0b 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1263,9 +1263,10 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, } std::string buf = wfiles->GetContent(file); std::vector> Bufs; - if (g_config->index.onChange && buf.size()) { + if (buf.size()) { // If there is a completion session, reuse its preamble if exists. bool done_remap = false; +#if 0 std::shared_ptr session = completion->TryGetSession(file, false, false); if (session) @@ -1278,6 +1279,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, done_remap = true; } } +#endif for (auto &[filename, content] : remapped) { if (filename == file && done_remap) continue; diff --git a/src/match.cc b/src/match.cc index 3ddb0c37d..b86dfd902 100644 --- a/src/match.cc +++ b/src/match.cc @@ -19,18 +19,7 @@ limitations under the License. #include "pipeline.hh" using namespace ccls; -// static std::optional Matcher::Create(const std::string &search) { - /* - std::string real_search; - real_search.reserve(search.size() * 3 + 2); - for (auto c : search) { - real_search += ".*"; - real_search += c; - } - real_search += ".*"; - */ - try { Matcher m; m.regex_string = search; @@ -73,18 +62,16 @@ GroupMatch::GroupMatch(const std::vector &whitelist, bool GroupMatch::IsMatch(const std::string &value, std::string *match_failure_reason) const { - for (const Matcher &m : whitelist) { + for (const Matcher &m : whitelist) if (m.IsMatch(value)) return true; - } - for (const Matcher &m : blacklist) { + for (const Matcher &m : blacklist) if (m.IsMatch(value)) { if (match_failure_reason) *match_failure_reason = "blacklist \"" + m.regex_string + "\""; return false; } - } return true; } diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 6652b0491..bc67cc26f 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -82,17 +82,6 @@ struct Handler_CclsReload : BaseMessageHandler { q.pop(); need_index.insert(file->def->path); - std::optional write_time = - pipeline::LastWriteTime(file->def->path); - if (!write_time) - continue; - { - std::lock_guard lock(vfs->mutex); - VFS::State &st = vfs->state[file->def->path]; - if (st.timestamp < write_time) - st.stage = 0; - } - if (request->params.dependencies) for (const std::string &path : graph[file->def->path]) { auto it = path_to_file.find(path); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 407f7b184..07a5e90d9 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -502,7 +502,6 @@ struct Handler_Initialize : BaseMessageHandler { LOG_S(INFO) << "start " << g_config->index.threads << " indexers"; for (int i = 0; i < g_config->index.threads; i++) { std::thread([=]() { - g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); pipeline::Indexer_Main(clang_complete, vfs, project, working_files); diff --git a/src/pipeline.cc b/src/pipeline.cc index 67e5706c7..3b8fb3c5f 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -26,7 +26,6 @@ limitations under the License. #include "project.h" #include "query_utils.h" -#include #include #include using namespace llvm; @@ -75,6 +74,9 @@ void DiagnosticsPublisher::Publish(WorkingFiles *working_files, } namespace ccls::pipeline { + +int64_t loaded_ts = 0, tick = 0; + namespace { struct Index_Request { @@ -82,6 +84,7 @@ struct Index_Request { std::vector args; IndexMode mode; lsRequestId id; + int64_t ts = tick++; }; struct Stdout_Request { @@ -172,6 +175,8 @@ std::unique_ptr RawCacheLoad(const std::string &path) { bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, Project *project, VFS *vfs, const GroupMatch &matcher) { + const int N_MUTEXES = 256; + static std::mutex mutexes[N_MUTEXES]; std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -186,8 +191,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, return false; } - if (std::string reason; !matcher.IsMatch(request.path, &reason)) { - LOG_IF_S(INFO, loud) << "skip " << request.path << " for " << reason; + if (!matcher.IsMatch(request.path)) { + LOG_IF_S(INFO, loud) << "skip " << request.path; return false; } @@ -200,74 +205,75 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, std::optional write_time = LastWriteTime(path_to_index); if (!write_time) return true; - int reparse = vfs->Stamp(path_to_index, *write_time); + int reparse = vfs->Stamp(path_to_index, *write_time, -1); if (request.path != path_to_index) { std::optional mtime1 = LastWriteTime(request.path); if (!mtime1) return true; - if (vfs->Stamp(request.path, *mtime1)) - reparse = 2; + if (vfs->Stamp(request.path, *mtime1, -1)) + reparse = 1; } if (g_config->index.onChange) reparse = 2; - if (!vfs->Mark(path_to_index, g_thread_id, 1) && !reparse) + if (!reparse) return true; - prev = RawCacheLoad(path_to_index); - if (!prev) - reparse = 2; - else { - if (CacheInvalid(vfs, prev.get(), path_to_index, entry.args, std::nullopt)) - reparse = 2; - int reparseForDep = g_config->index.reparseForDependency; - if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded)) - for (const auto &dep : prev->dependencies) { - if (auto write_time1 = LastWriteTime(dep.first().str())) { - if (dep.second < *write_time1) { - reparse = 2; - std::lock_guard lock(vfs->mutex); - vfs->state[dep.first().str()].stage = 0; - } - } else - reparse = 2; + if (reparse < 2) do { + std::unique_lock lock( + mutexes[std::hash()(path_to_index) % N_MUTEXES]); + prev = RawCacheLoad(path_to_index); + if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args, + std::nullopt)) + break; + bool update = false; + for (const auto &dep : prev->dependencies) + if (auto mtime1 = LastWriteTime(dep.first.val().str())) { + if (dep.second < *mtime1) + update = true; + } else { + update = true; } - } - - // Grab the ownership - if (reparse) { - std::lock_guard lock(vfs->mutex); - vfs->state[path_to_index].owner = g_thread_id; - vfs->state[path_to_index].stage = 0; - } - - if (reparse < 2) { - LOG_S(INFO) << "load cache for " << path_to_index; - auto dependencies = prev->dependencies; - if (reparse) { - IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); - std::lock_guard lock(vfs->mutex); - vfs->state[path_to_index].loaded = true; - } - for (const auto &dep : dependencies) { - std::string path = dep.first().str(); - if (vfs->Mark(path, 0, 2) && (prev = RawCacheLoad(path))) { + int forDep = g_config->index.reparseForDependency; + if (update && (forDep > 1 || (forDep == 1 && request.ts < loaded_ts))) + break; + + if (reparse < 2) { + LOG_S(INFO) << "load cache for " << path_to_index; + auto dependencies = prev->dependencies; + if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); + std::lock_guard lock1(vfs->mutex); + vfs->state[path_to_index].loaded = true; + } + lock.unlock(); + for (const auto &dep : dependencies) { + std::string path = dep.first.val().str(); + std::lock_guard lock1( + mutexes[std::hash()(path) % N_MUTEXES]); + prev = RawCacheLoad(path); + if (!prev) + continue; { - std::lock_guard lock(vfs->mutex); - vfs->state[path].loaded = true; + std::lock_guard lock2(vfs->mutex); + VFS::State &st = vfs->state[path]; + if (st.loaded) + continue; + st.loaded = true; + st.timestamp = prev->mtime; } + IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); + on_indexed->PushBack(std::move(update), + request.mode != IndexMode::NonInteractive); if (entry.id >= 0) { - std::lock_guard lock(project->mutex_); + std::lock_guard lock2(project->mutex_); project->path_to_entry_index[path] = entry.id; } } + return true; } - return true; - } + } while (0); LOG_IF_S(INFO, loud) << "parse " << path_to_index; @@ -288,64 +294,52 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, out.error.message = "Failed to index " + path_to_index; pipeline::WriteStdout(kMethodType_Unknown, out); } - vfs->Reset(path_to_index); return true; } for (std::unique_ptr &curr : indexes) { std::string path = curr->path; - bool do_update = path == path_to_index || path == request.path, loaded; - { - std::lock_guard lock(vfs->mutex); - VFS::State &st = vfs->state[path]; - if (st.timestamp < curr->mtime) { - st.timestamp = curr->mtime; - do_update = true; - } - loaded = st.loaded; - st.loaded = true; - } - if (std::string reason; !matcher.IsMatch(path, &reason)) { - LOG_IF_S(INFO, loud) << "skip emitting and storing index of " << path << " for " - << reason; - do_update = false; - } - if (!do_update) { - vfs->Reset(path); + if (!matcher.IsMatch(path)) { + LOG_IF_S(INFO, loud) << "skip index for " << path; continue; } - prev.reset(); - if (loaded) - prev = RawCacheLoad(path); - - // Store current index. LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev << ")"; - if (g_config->cacheDirectory.empty()) { - std::lock_guard lock(g_index_mutex); - auto it = g_index.insert_or_assign( - path, InMemoryIndexFile{curr->file_contents, *curr}); - std::string().swap(it.first->second.index.file_contents); - } else { - std::string cache_path = GetCachePath(path); - WriteToFile(cache_path, curr->file_contents); - WriteToFile(AppendSerializationFormat(cache_path), - Serialize(g_config->cacheFormat, *curr)); - } - - vfs->Reset(path); - if (entry.id >= 0) { - std::lock_guard lock(project->mutex_); - for (auto &dep : curr->dependencies) - project->path_to_entry_index[dep.first()] = entry.id; + { + std::lock_guard lock(mutexes[std::hash()(path) % N_MUTEXES]); + bool loaded; + { + std::lock_guard lock1(vfs->mutex); + loaded = vfs->state[path].loaded; + } + if (loaded) + prev = RawCacheLoad(path); + else + prev.reset(); + if (g_config->cacheDirectory.empty()) { + std::lock_guard lock(g_index_mutex); + auto it = g_index.insert_or_assign( + path, InMemoryIndexFile{curr->file_contents, *curr}); + std::string().swap(it.first->second.index.file_contents); + } else { + std::string cache_path = GetCachePath(path); + WriteToFile(cache_path, curr->file_contents); + WriteToFile(AppendSerializationFormat(cache_path), + Serialize(g_config->cacheFormat, *curr)); + } + on_indexed->PushBack(IndexUpdate::CreateDelta(prev.get(), curr.get()), + request.mode != IndexMode::NonInteractive); + { + std::lock_guard lock1(vfs->mutex); + vfs->state[path].loaded = true; + } + if (entry.id >= 0) { + std::lock_guard lock(project->mutex_); + for (auto &dep : curr->dependencies) + project->path_to_entry_index[dep.first()] = entry.id; + } } - - // Build delta update. - IndexUpdate update = IndexUpdate::CreateDelta(prev.get(), curr.get()); - - on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); } return true; @@ -376,7 +370,6 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, WorkingFiles *working_files, IndexUpdate *update) { if (update->refresh) { - Project::loaded = true; LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); diff --git a/src/pipeline.hh b/src/pipeline.hh index 6e311d5ca..946236e1e 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -35,6 +35,7 @@ enum class IndexMode { }; namespace pipeline { +extern int64_t loaded_ts, tick; void Init(); void LaunchStdin(); void LaunchStdout(); diff --git a/src/project.cc b/src/project.cc index 2d6eed1e9..fcbce38fa 100644 --- a/src/project.cc +++ b/src/project.cc @@ -351,10 +351,7 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace -bool Project::loaded = false; - void Project::Load(const std::string &root_directory) { - Project::loaded = false; ProjectConfig project; project.extra_flags = g_config->clang.extraArgs; project.project_dir = root_directory; @@ -470,6 +467,7 @@ void Project::Index(WorkingFiles *wfiles, lsRequestId id) { interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); }); + pipeline::loaded_ts = pipeline::tick; // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. pipeline::Index("", {}, IndexMode::NonInteractive); diff --git a/src/project.h b/src/project.h index b431d1d48..10c0b3c3e 100644 --- a/src/project.h +++ b/src/project.h @@ -72,6 +72,4 @@ struct Project { ForAllFilteredFiles(std::function action); void Index(WorkingFiles *wfiles, lsRequestId id); - - static bool loaded; }; From 525b6da1accfb0e6a7d69fc8016f12ab85a4eebd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 19 Sep 2018 00:51:15 -0700 Subject: [PATCH 217/378] intern strings in dependencies and IndexInclude::resolved_path --- src/indexer.cc | 5 +++-- src/indexer.h | 7 ++++--- src/pipeline.cc | 2 +- src/query.cc | 2 +- src/query.h | 2 +- src/serializer.cc | 30 +++++++++++++++++------------- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 592d35f0b..1f28475c1 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1104,7 +1104,7 @@ class IndexPPCallbacks : public PPCallbacks { if (IndexFile *db = param.ConsumeFile(*FE)) { std::string file_name = FileName(*File); if (file_name.size()) - db->includes.push_back({spell.start.line, std::move(file_name)}); + db->includes.push_back({spell.start.line, Intern(file_name)}); } } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { @@ -1368,7 +1368,8 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, // dependency set. for (auto &[_, path] : param.SeenUniqueID) if (path != entry->path && path != entry->import_file) - entry->dependencies[path] = param.file2mtime[path]; + entry->dependencies[llvm::CachedHashStringRef(Intern(path))] = + param.file2mtime[path]; } return result; diff --git a/src/indexer.h b/src/indexer.h index ab20ba305..7235f3731 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -27,7 +27,8 @@ limitations under the License. #include "utils.h" #include -#include +#include +#include #include #include @@ -232,7 +233,7 @@ struct IndexInclude { // information - a line is good enough for clicking. int line = 0; // Absolute path to the index. - std::string resolved_path; + const char *resolved_path; }; struct IndexFile { @@ -266,7 +267,7 @@ struct IndexFile { std::vector skipped_ranges; std::vector includes; - llvm::StringMap dependencies; + llvm::DenseMap dependencies; std::unordered_map usr2func; std::unordered_map usr2type; std::unordered_map usr2var; diff --git a/src/pipeline.cc b/src/pipeline.cc index 3b8fb3c5f..f651f271a 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -337,7 +337,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (entry.id >= 0) { std::lock_guard lock(project->mutex_); for (auto &dep : curr->dependencies) - project->path_to_entry_index[dep.first()] = entry.id; + project->path_to_entry_index[dep.first.val().str()] = entry.id; } } } diff --git a/src/query.cc b/src/query.cc index d09f33b18..f052c42c2 100644 --- a/src/query.cc +++ b/src/query.cc @@ -62,7 +62,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile &indexed) { def.skipped_ranges = std::move(indexed.skipped_ranges); def.dependencies.reserve(indexed.dependencies.size()); for (auto &dep : indexed.dependencies) - def.dependencies.push_back(dep.first()); + def.dependencies.push_back(dep.first.val().data()); // llvm 8 -> data() def.language = indexed.language; return {std::move(def), std::move(indexed.file_contents)}; } diff --git a/src/query.h b/src/query.h index ea7d0bcf6..4dfe62bb9 100644 --- a/src/query.h +++ b/src/query.h @@ -46,7 +46,7 @@ struct QueryFile { // Parts of the file which are disabled. std::vector skipped_ranges; // Used by |$ccls/reload|. - std::vector dependencies; + std::vector dependencies; }; using DefUpdate = std::pair; diff --git a/src/serializer.cc b/src/serializer.cc index e0f595352..d523b1186 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -27,6 +27,7 @@ limitations under the License. #include #include +using namespace ccls; using namespace llvm; bool gTestOutputMode = false; @@ -127,7 +128,7 @@ void Reflect(Writer &visitor, std::string_view &data) { void Reflect(Reader &vis, const char *&v) { const char *str = vis.GetString(); - v = ccls::Intern(str); + v = Intern(str); } void Reflect(Writer &vis, const char *&v) { vis.String(v); } @@ -160,33 +161,33 @@ void Reflect(Writer &visitor, std::unordered_map &map) { } // Used by IndexFile::dependencies. -void Reflect(Reader &vis, StringMap &v) { +void Reflect(Reader &vis, DenseMap &v) { std::string name; if (vis.Format() == SerializeFormat::Json) { auto &vis1 = static_cast(vis); for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it) - v[it->name.GetString()] = it->value.GetInt64(); + v[CachedHashStringRef(Intern(it->name.GetString()))] = + it->value.GetInt64(); } else { vis.IterArray([&](Reader &entry) { Reflect(entry, name); - Reflect(entry, v[name]); + Reflect(entry, v[CachedHashStringRef(Intern(name))]); }); } } -void Reflect(Writer &vis, StringMap &v) { +void Reflect(Writer &vis, DenseMap &v) { if (vis.Format() == SerializeFormat::Json) { auto &vis1 = static_cast(vis); vis.StartObject(); for (auto &it : v) { - std::string key = it.first(); - vis1.m().Key(key.c_str()); + vis1.m().Key(it.first.val().data()); // llvm 8 -> data() vis1.m().Int64(it.second); } vis.EndObject(); } else { vis.StartArray(v.size()); for (auto &it : v) { - std::string key = it.first(); + std::string key = it.first.val().str(); Reflect(vis, key); Reflect(vis, it.second); } @@ -467,13 +468,16 @@ Deserialize(SerializeFormat format, const std::string &path, DoPathMapping(arg); for (auto &[_, path] : file->lid2path) DoPathMapping(path); - for (auto &include : file->includes) - DoPathMapping(include.resolved_path); - StringMap dependencies; + for (auto &include : file->includes) { + std::string p(include.resolved_path); + DoPathMapping(p); + include.resolved_path = Intern(p); + } + decltype(file->dependencies) dependencies; for (auto &it : file->dependencies) { - std::string path = it.first().str(); + std::string path = it.first.val().str(); DoPathMapping(path); - dependencies[path] = it.second; + dependencies[CachedHashStringRef(Intern(path))] = it.second; } file->dependencies = std::move(dependencies); } From 08645d64c190dc11341f28b3d35f5c3eacdac22f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 19 Sep 2018 09:31:45 -0700 Subject: [PATCH 218/378] intern args --- index_tests/types/anonymous_struct.cc | 4 +- src/clang_tu.cc | 9 ++-- src/clang_tu.h | 2 +- src/indexer.cc | 2 +- src/indexer.h | 4 +- src/messages/textDocument_didOpen.cc | 11 +++-- src/pipeline.cc | 17 +++---- src/pipeline.hh | 2 +- src/project.cc | 68 +++++++++++++-------------- src/project.h | 6 +-- src/query.h | 2 +- src/serializer.cc | 9 +++- src/test.cc | 11 +++-- 13 files changed, 76 insertions(+), 71 deletions(-) diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index b3dbecc3b..9d88a8bf1 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -26,9 +26,9 @@ union vector3 { "uses": [] }, { "usr": 1428566502523368801, - "detailed_name": "struct {}", + "detailed_name": "anon struct", "qual_name_offset": 0, - "short_name": "", + "short_name": "anon struct", "kind": 23, "declarations": [], "spell": "2:3-2:9|17937907487590875128|2|1026|-1", diff --git a/src/clang_tu.cc b/src/clang_tu.cc index ecac6ab7b..536454899 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -66,17 +66,14 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, } std::unique_ptr -BuildCompilerInvocation(const std::vector &args, +BuildCompilerInvocation(std::vector args, IntrusiveRefCntPtr VFS) { std::string save = "-resource-dir=" + g_config->clang.resourceDir; - std::vector cargs; - for (auto &arg : args) - cargs.push_back(arg.c_str()); - cargs.push_back(save.c_str()); + args.push_back(save.c_str()); IntrusiveRefCntPtr Diags( CompilerInstance::createDiagnostics(new DiagnosticOptions)); std::unique_ptr CI = - createInvocationFromCommandLine(cargs, Diags, VFS); + createInvocationFromCommandLine(args, Diags, VFS); if (CI) { CI->getDiagnosticOpts().IgnoreWarnings = true; CI->getFrontendOpts().DisableFree = false; diff --git a/src/clang_tu.h b/src/clang_tu.h index ec4b57707..1edcd5ee1 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -36,5 +36,5 @@ Range FromTokenRange(const clang::SourceManager &SM, llvm::sys::fs::UniqueID *UniqueID = nullptr); std::unique_ptr -BuildCompilerInvocation(const std::vector &args, +BuildCompilerInvocation(std::vector args, llvm::IntrusiveRefCntPtr VFS); diff --git a/src/indexer.cc b/src/indexer.cc index 1f28475c1..a6b70ca12 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1236,7 +1236,7 @@ void Init() { std::vector> Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, - const std::vector &args, + const std::vector &args, const std::vector> &remapped) { if (!g_config->index.enabled) return {}; diff --git a/src/indexer.h b/src/indexer.h index 7235f3731..173065522 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -247,7 +247,7 @@ struct IndexFile { llvm::sys::fs::UniqueID UniqueID; std::string path; - std::vector args; + std::vector args; // This is unfortunately time_t as used by clang::FileEntry int64_t mtime = 0; LanguageId language = LanguageId::C; @@ -293,6 +293,6 @@ void Init(); std::vector> Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, - const std::vector &args, + const std::vector &args, const std::vector> &remapped); } diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 939ec8bd1..4e76e8e9f 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -64,14 +64,15 @@ struct Handler_TextDocumentDidOpen } include_complete->AddFile(working_file->filename); - if (params.args.size()) - project->SetFlagsForFile(params.args, path); + std::vector args; + for (const std::string &arg : params.args) + args.push_back(Intern(arg)); + if (args.size()) + project->SetArgsForFile(args, path); // Submit new index request if it is not a header file. if (SourceFileLanguage(path) != LanguageId::Unknown) { - pipeline::Index( - path, params.args.size() ? params.args : std::vector{}, - IndexMode::Normal); + pipeline::Index(path, args, IndexMode::Normal); clang_complete->FlushSession(path); } diff --git a/src/pipeline.cc b/src/pipeline.cc index f651f271a..0b5a0f6fb 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -81,7 +81,7 @@ namespace { struct Index_Request { std::string path; - std::vector args; + std::vector args; IndexMode mode; lsRequestId id; int64_t ts = tick++; @@ -108,7 +108,7 @@ std::shared_mutex g_index_mutex; std::unordered_map g_index; bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, - const std::vector &args, + const std::vector &args, const std::optional &from) { { std::lock_guard lock(vfs->mutex); @@ -119,13 +119,14 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, } } - if (prev->args != args) { + bool changed = prev->args.size() != args.size(); + for (size_t i = 0; !changed && i < args.size(); i++) + if (strcmp(prev->args[i], args[i])) + changed = true; + if (changed) LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); - return true; - } - - return false; + return changed; }; std::string AppendSerializationFormat(const std::string &base) { @@ -537,7 +538,7 @@ void MainLoop() { } } -void Index(const std::string &path, const std::vector &args, +void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id) { index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } diff --git a/src/pipeline.hh b/src/pipeline.hh index 946236e1e..0cbabffc3 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -43,7 +43,7 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, WorkingFiles *wfiles); void MainLoop(); -void Index(const std::string &path, const std::vector &args, +void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {}); std::optional LastWriteTime(const std::string &path); diff --git a/src/project.cc b/src/project.cc index fcbce38fa..98f840832 100644 --- a/src/project.cc +++ b/src/project.cc @@ -55,7 +55,6 @@ enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; struct ProjectConfig { std::unordered_set quote_dirs; std::unordered_set angle_dirs; - std::vector extra_flags; std::string project_dir; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -85,17 +84,17 @@ struct ProjectProcessor { const std::string base_name = sys::path::filename(entry.filename); // Expand %c %cpp %clang - std::vector args; - args.reserve(entry.args.size() + config->extra_flags.size() + 3); + std::vector args; + args.reserve(entry.args.size() + g_config->clang.extraArgs.size() + 1); const LanguageId lang = SourceFileLanguage(entry.filename); - for (const std::string &arg : entry.args) { - if (arg.compare(0, 3, "%c ") == 0) { + for (const char *arg : entry.args) { + if (strncmp(arg, "%c ", 3) == 0) { if (lang == LanguageId::C) - args.push_back(arg.substr(3)); - } else if (arg.compare(0, 5, "%cpp ") == 0) { + args.push_back(arg + 3); + } else if (strncmp(arg, "%cpp ", 5) == 0) { if (lang == LanguageId::Cpp) - args.push_back(arg.substr(5)); - } else if (arg == "%clang") { + args.push_back(arg + 5); + } else if (strcmp(arg, "%clang") == 0) { args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); } else if (!llvm::is_contained(g_config->clang.excludeArgs, arg)) { args.push_back(arg); @@ -103,8 +102,8 @@ struct ProjectProcessor { } if (args.empty()) return; - args.insert(args.end(), config->extra_flags.begin(), - config->extra_flags.end()); + for (const std::string &arg : g_config->clang.extraArgs) + args.push_back(Intern(arg)); size_t hash = std::hash{}(entry.directory); for (auto &arg : args) { @@ -117,7 +116,7 @@ struct ProjectProcessor { } hash_combine(hash, std::hash{}(arg)); } - args.push_back("-working-directory=" + entry.directory); + args.push_back(Intern("-working-directory=" + entry.directory)); if (!command_set.insert(hash).second) { entry.args = std::move(args); @@ -141,13 +140,9 @@ struct ProjectProcessor { } Driver.setCheckInputsExist(false); - std::vector cargs; - cargs.reserve(args.size() + 1); - for (auto &arg : args) - cargs.push_back(arg.c_str()); - cargs.push_back("-fsyntax-only"); + args.push_back("-fsyntax-only"); - std::unique_ptr C(Driver.BuildCompilation(cargs)); + std::unique_ptr C(Driver.BuildCompilation(args)); const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1) return; @@ -180,15 +175,16 @@ struct ProjectProcessor { } }; -std::vector +std::vector ReadCompilerArgumentsFromFile(const std::string &path) { auto MBOrErr = MemoryBuffer::getFile(path); if (!MBOrErr) return {}; - std::vector args; + std::vector args; for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) { - args.push_back(*I); - DoPathMapping(args.back()); + std::string line = *I; + DoPathMapping(line); + args.push_back(Intern(line)); } return args; } @@ -198,12 +194,12 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { config->mode = ProjectMode::DotCcls; SmallString<256> Path; sys::path::append(Path, config->project_dir, ".ccls"); - LOG_IF_S(WARNING, !sys::fs::exists(Path) && config->extra_flags.empty()) + LOG_IF_S(WARNING, !sys::fs::exists(Path) && g_config->clang.extraArgs.empty()) << "ccls has no clang arguments. Use either " "compile_commands.json or .ccls, See ccls README for " "more information."; - std::unordered_map> folder_args; + std::unordered_map> folder_args; std::vector files; GetFilesInFolder(config->project_dir, true /*recursive*/, @@ -246,7 +242,7 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { e.args = GetCompilerArgumentForFile(file); if (e.args.empty()) e.args.push_back("%clang"); // Add a Dummy. - e.args.push_back(e.filename); + e.args.push_back(Intern(e.filename)); proc.Process(e); result.push_back(e); } @@ -324,9 +320,12 @@ LoadEntriesFromDirectory(ProjectConfig *project, entry.filename = NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); DoPathMapping(entry.filename); - entry.args = std::move(Cmd.CommandLine); - for (std::string &arg : entry.args) + std::vector args = std::move(Cmd.CommandLine); + entry.args.reserve(args.size()); + for (std::string &arg : args) { DoPathMapping(arg); + entry.args.push_back(Intern(arg)); + } proc.Process(entry); if (Seen.insert(entry.filename).second) result.push_back(entry); @@ -353,7 +352,6 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { void Project::Load(const std::string &root_directory) { ProjectConfig project; - project.extra_flags = g_config->clang.extraArgs; project.project_dir = root_directory; entries = LoadEntriesFromDirectory(&project, g_config->compilationDatabaseDirectory); @@ -381,19 +379,19 @@ void Project::Load(const std::string &root_directory) { } } -void Project::SetFlagsForFile(const std::vector &flags, - const std::string &path) { +void Project::SetArgsForFile(const std::vector &args, + const std::string &path) { std::lock_guard lock(mutex_); auto it = path_to_entry_index.find(path); if (it != path_to_entry_index.end()) { // The entry already exists in the project, just set the flags. - this->entries[it->second].args = flags; + this->entries[it->second].args = args; } else { // Entry wasn't found, so we create a new one. Entry entry; entry.is_inferred = false; entry.filename = path; - entry.args = flags; + entry.args = args; this->entries.emplace_back(entry); } } @@ -424,7 +422,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) { result.filename = filename; if (!best_entry) { result.args.push_back("%clang"); - result.args.push_back(filename); + result.args.push_back(Intern(filename)); } else { result.args = best_entry->args; @@ -432,11 +430,11 @@ Project::FindCompilationEntryForFile(const std::string &filename) { // that path to the new filename. std::string best_entry_base_name = sys::path::filename(best_entry->filename); - for (std::string &arg : result.args) { + for (const char *&arg : result.args) { try { if (arg == best_entry->filename || sys::path::filename(arg) == best_entry_base_name) - arg = filename; + arg = Intern(filename); } catch (...) { } } diff --git a/src/project.h b/src/project.h index 10c0b3c3e..e5582a40a 100644 --- a/src/project.h +++ b/src/project.h @@ -30,7 +30,7 @@ struct Project { struct Entry { std::string directory; std::string filename; - std::vector args; + std::vector args; // If true, this entry is inferred and was not read from disk. bool is_inferred = false; int id = -1; @@ -64,8 +64,8 @@ struct Project { // If the client has overridden the flags, or specified them for a file // that is not in the compilation_database.json make sure those changes // are permanent. - void SetFlagsForFile(const std::vector &flags, - const std::string &path); + void SetArgsForFile(const std::vector &args, + const std::string &path); // Run |action| on every file in the project. void diff --git a/src/query.h b/src/query.h index 4dfe62bb9..3cc50fd6e 100644 --- a/src/query.h +++ b/src/query.h @@ -39,7 +39,7 @@ template <> struct DenseMapInfo { struct QueryFile { struct Def { std::string path; - std::vector args; + std::vector args; LanguageId language; // Includes in the file. std::vector includes; diff --git a/src/serializer.cc b/src/serializer.cc index d523b1186..8faf8ebd6 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -464,8 +464,13 @@ Deserialize(SerializeFormat format, const std::string &path, file->path = path; if (g_config->clang.pathMappings.size()) { DoPathMapping(file->import_file); - for (std::string &arg : file->args) - DoPathMapping(arg); + std::vector args; + for (const char *arg : file->args) { + std::string s(arg); + DoPathMapping(s); + args.push_back(Intern(s)); + } + file->args = std::move(args); for (auto &[_, path] : file->lid2path) DoPathMapping(path); for (auto &include : file->includes) { diff --git a/src/test.cc b/src/test.cc index 19d52a9e6..52bd35062 100644 --- a/src/test.cc +++ b/src/test.cc @@ -259,6 +259,9 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); + CompletionManager completion( + nullptr, nullptr, [&](std::string, std::vector) {}, + [](lsRequestId id) {}); GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string &path) { @@ -302,11 +305,11 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { // Run test. g_config = new Config; VFS vfs; - CompletionManager completion( - nullptr, nullptr, [&](std::string, std::vector) {}, - [](lsRequestId id) {}); WorkingFiles wfiles; - auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, flags, {}); + std::vector cargs; + for (auto &arg : flags) + cargs.push_back(arg.c_str()); + auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, cargs, {}); for (const auto &entry : all_expected_output) { const std::string &expected_path = entry.first; From f515b4b4660bf9ee9c3b09212b10e73c5977ab3b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 19 Sep 2018 13:05:52 -0700 Subject: [PATCH 219/378] Improve VarDef::type for textDocument/typeDefinition --- index_tests/foobar.cc | 42 +------ index_tests/lambdas/lambda.cc | 4 +- ...ace_template_type_usage_folded_into_one.cc | 40 +------ index_tests/templates/specialization.cc | 71 ++---------- ...mplate_class_type_usage_folded_into_one.cc | 40 +------ .../template_type_usage_folded_into_one.cc | 40 +------ .../usage/type_usage_as_template_parameter.cc | 42 +------ ...ype_usage_as_template_parameter_complex.cc | 14 +-- ...type_usage_as_template_parameter_simple.cc | 21 +--- src/indexer.cc | 103 ++++++++---------- 10 files changed, 78 insertions(+), 339 deletions(-) diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index e92f23cfb..4b9d2f65f 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -31,23 +31,6 @@ Foo b; "vars": [], "instances": [], "uses": ["9:5-9:6|0|1|4|-1"] - }, { - "usr": 7074603899792463171, - "detailed_name": "Inner", - "qual_name_offset": 0, - "short_name": "Inner", - "kind": 26, - "declarations": [], - "spell": "6:10-6:15|0|1|2|-1", - "extent": "6:3-6:18|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [16721564935990383768], - "uses": [] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", @@ -63,25 +46,8 @@ Foo b; "types": [13938528237873543349], "funcs": [], "vars": [], - "instances": [], - "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] - }, { - "usr": 11976530632376795217, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 26, - "declarations": [], - "spell": "5:8-5:11|0|1|2|-1", - "extent": "4:1-7:2|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], "instances": [12028309045033782423], - "uses": [] + "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] }, { "usr": 13892793056005362145, "detailed_name": "enum B {}", @@ -114,7 +80,7 @@ Foo b; "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [16721564935990383768], "uses": ["9:9-9:14|0|1|4|-1"] }], "usr2var": [{ @@ -125,7 +91,7 @@ Foo b; "declarations": [], "spell": "10:8-10:9|0|1|2|-1", "extent": "10:1-10:9|0|1|0|-1", - "type": 11976530632376795217, + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 0 @@ -137,7 +103,7 @@ Foo b; "declarations": [], "spell": "9:15-9:16|0|1|2|-1", "extent": "9:1-9:16|0|1|0|-1", - "type": 7074603899792463171, + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 2f5371f91..b4e58a30e 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -65,10 +65,8 @@ void foo() { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 26, + "kind": 0, "declarations": [], - "spell": "4:22-4:23|4259594751088586730|3|2|-1", - "extent": "4:22-4:23|4259594751088586730|3|0|-1", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index c7ce4fae8..b3144b08a 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -13,40 +13,6 @@ namespace ns { "skipped_ranges": [], "usr2func": [], "usr2type": [{ - "usr": 3948666349864691553, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 26, - "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|2|-1", - "extent": "2:3-3:15|11072669167287398027|2|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [3182917058194750998], - "uses": [] - }, { - "usr": 8224244241460152567, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 26, - "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|2|-1", - "extent": "2:3-3:15|11072669167287398027|2|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [15768138241775955040], - "uses": [] - }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, @@ -82,7 +48,7 @@ namespace ns { "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [15768138241775955040, 3182917058194750998], "uses": ["5:3-5:6|11072669167287398027|2|4|-1", "6:3-6:6|11072669167287398027|2|4|-1"] }], "usr2var": [{ @@ -93,7 +59,7 @@ namespace ns { "declarations": [], "spell": "6:13-6:14|11072669167287398027|2|1026|-1", "extent": "6:3-6:14|11072669167287398027|2|0|-1", - "type": 3948666349864691553, + "type": 14042997404480181958, "uses": [], "kind": 13, "storage": 0 @@ -105,7 +71,7 @@ namespace ns { "declarations": [], "spell": "5:12-5:13|11072669167287398027|2|1026|-1", "extent": "5:3-5:13|11072669167287398027|2|0|-1", - "type": 8224244241460152567, + "type": 14042997404480181958, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index d597a78cf..52cfe543b 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -132,7 +132,7 @@ void foo(float Value); "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [2933643612409209903], "uses": ["7:1-7:9|0|1|4|-1"] }, { "usr": 1663022413889915338, @@ -151,23 +151,6 @@ void foo(float Value); "vars": [], "instances": [15931696253641284761], "uses": ["26:7-26:13|0|1|4|-1", "33:1-33:7|0|1|4|-1"] - }, { - "usr": 3231449734830406187, - "detailed_name": "function", - "qual_name_offset": 0, - "short_name": "function", - "kind": 26, - "declarations": [], - "spell": "5:7-5:15|0|1|2|-1", - "extent": "4:1-5:30|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [2933643612409209903], - "uses": [] }, { "usr": 5760043510674081814, "detailed_name": "struct Z1 {}", @@ -200,7 +183,7 @@ void foo(float Value); "types": [], "funcs": [18107614608385228556], "vars": [], - "instances": [], + "instances": [5792869548777559988], "uses": ["21:16-21:22|0|1|4|-1", "30:1-30:7|0|1|4|-1", "32:1-32:7|0|1|4|-1"] }, { "usr": 9201299975592934124, @@ -236,40 +219,6 @@ void foo(float Value); "vars": [], "instances": [], "uses": ["26:14-26:16|0|1|4|-1", "33:8-33:10|0|1|4|-1"] - }, { - "usr": 11153492883079050853, - "detailed_name": "vector", - "qual_name_offset": 0, - "short_name": "vector", - "kind": 26, - "declarations": [], - "spell": "17:7-17:13|0|1|2|-1", - "extent": "16:1-17:20|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [86949563628772958], - "uses": [] - }, { - "usr": 13322943937025195708, - "detailed_name": "vector", - "qual_name_offset": 0, - "short_name": "vector", - "kind": 26, - "declarations": [], - "spell": "12:7-12:13|0|1|2|-1", - "extent": "11:1-14:2|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [5792869548777559988], - "uses": [] }, { "usr": 14111105212951082474, "detailed_name": "T", @@ -304,13 +253,11 @@ void foo(float Value); "uses": [] }, { "usr": 15440970074034693939, - "detailed_name": "vector", + "detailed_name": "", "qual_name_offset": 0, - "short_name": "vector", - "kind": 26, + "short_name": "", + "kind": 0, "declarations": [], - "spell": "21:16-21:22|0|1|2|-1", - "extent": "21:1-21:26|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], @@ -349,7 +296,7 @@ void foo(float Value); "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [86949563628772958], "uses": ["31:1-31:7|0|1|4|-1"] }], "usr2var": [{ @@ -360,7 +307,7 @@ void foo(float Value); "declarations": [], "spell": "31:14-31:17|0|1|2|-1", "extent": "31:1-31:17|0|1|0|-1", - "type": 11153492883079050853, + "type": 16155717907537731864, "uses": [], "kind": 13, "storage": 0 @@ -372,7 +319,7 @@ void foo(float Value); "declarations": [], "spell": "7:21-7:22|0|1|2|-1", "extent": "7:1-7:22|0|1|0|-1", - "type": 3231449734830406187, + "type": 218068462278884837, "uses": [], "kind": 13, "storage": 0 @@ -409,7 +356,7 @@ void foo(float Value); "declarations": [], "spell": "30:14-30:16|0|1|2|-1", "extent": "30:1-30:16|0|1|0|-1", - "type": 13322943937025195708, + "type": 7440942986741176606, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index e1b1b8290..09bc2e7c6 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -50,23 +50,6 @@ VarDecl b "vars": [], "instances": [], "uses": ["9:5-9:6|0|1|4|-1"] - }, { - "usr": 7074603899792463171, - "detailed_name": "Inner", - "qual_name_offset": 0, - "short_name": "Inner", - "kind": 26, - "declarations": [], - "spell": "6:10-6:15|0|1|2|-1", - "extent": "6:3-6:18|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [16721564935990383768], - "uses": [] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", @@ -116,25 +99,8 @@ VarDecl b "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [16721564935990383768, 12028309045033782423], "uses": ["9:9-9:14|0|1|4|-1", "10:9-10:14|0|1|4|-1"] - }, { - "usr": 15961308565836244174, - "detailed_name": "Inner", - "qual_name_offset": 0, - "short_name": "Inner", - "kind": 26, - "declarations": [], - "spell": "6:10-6:15|0|1|2|-1", - "extent": "6:3-6:18|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [12028309045033782423], - "uses": [] }], "usr2var": [{ "usr": 12028309045033782423, @@ -144,7 +110,7 @@ VarDecl b "declarations": [], "spell": "10:15-10:16|0|1|2|-1", "extent": "10:1-10:16|0|1|0|-1", - "type": 15961308565836244174, + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 0 @@ -156,7 +122,7 @@ VarDecl b "declarations": [], "spell": "9:15-9:16|0|1|2|-1", "extent": "9:1-9:16|0|1|0|-1", - "type": 7074603899792463171, + "type": 13938528237873543349, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index bb9745e83..fb7191797 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -11,23 +11,6 @@ Foo b; "skipped_ranges": [], "usr2func": [], "usr2type": [{ - "usr": 5123806965838456033, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 26, - "declarations": [], - "spell": "2:7-2:10|0|1|2|-1", - "extent": "1:1-2:13|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [16721564935990383768], - "uses": [] - }, { "usr": 10528472276654770367, "detailed_name": "class Foo {}", "qual_name_offset": 6, @@ -42,25 +25,8 @@ Foo b; "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [16721564935990383768, 12028309045033782423], "uses": ["4:1-4:4|0|1|4|-1", "5:1-5:4|0|1|4|-1"] - }, { - "usr": 14134940367505932005, - "detailed_name": "Foo", - "qual_name_offset": 0, - "short_name": "Foo", - "kind": 26, - "declarations": [], - "spell": "2:7-2:10|0|1|2|-1", - "extent": "1:1-2:13|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [12028309045033782423], - "uses": [] }], "usr2var": [{ "usr": 12028309045033782423, @@ -70,7 +36,7 @@ Foo b; "declarations": [], "spell": "5:11-5:12|0|1|2|-1", "extent": "5:1-5:12|0|1|0|-1", - "type": 14134940367505932005, + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 0 @@ -82,7 +48,7 @@ Foo b; "declarations": [], "spell": "4:10-4:11|0|1|2|-1", "extent": "4:1-4:11|0|1|0|-1", - "type": 5123806965838456033, + "type": 10528472276654770367, "uses": [], "kind": 13, "storage": 0 diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 5c4dc8241..169d5ad47 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -46,25 +46,8 @@ unique_ptr* return_type() { "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [12857919739649552168, 18075066956054788088, 3364438781074774169], "uses": ["6:8-6:18|0|1|4|-1", "7:8-7:18|0|1|4|-1", "9:1-9:11|0|1|4|-1", "10:3-10:13|16359708726068806331|3|4|-1"] - }, { - "usr": 4186953406371619898, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, - "short_name": "unique_ptr", - "kind": 26, - "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "1:1-2:20|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [18075066956054788088, 3364438781074774169], - "uses": [] }, { "usr": 4750332761459066907, "detailed_name": "struct S {}", @@ -82,23 +65,6 @@ unique_ptr* return_type() { "vars": [], "instances": [], "uses": ["7:19-7:20|0|1|4|-1", "9:12-9:13|0|1|4|-1", "10:14-10:15|16359708726068806331|3|4|-1"] - }, { - "usr": 16848604152578034754, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, - "short_name": "unique_ptr", - "kind": 26, - "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "1:1-2:20|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [12857919739649552168], - "uses": [] }], "usr2var": [{ "usr": 3364438781074774169, @@ -108,7 +74,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "10:18-10:23|16359708726068806331|3|2|-1", "extent": "10:3-10:23|16359708726068806331|3|0|-1", - "type": 4186953406371619898, + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 0 @@ -120,7 +86,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "6:25-6:27|0|1|2|-1", "extent": "6:1-6:27|0|1|0|-1", - "type": 16848604152578034754, + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 2 @@ -132,7 +98,7 @@ unique_ptr* return_type() { "declarations": [], "spell": "7:22-7:24|0|1|2|-1", "extent": "7:1-7:24|0|1|0|-1", - "type": 4186953406371619898, + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 2 diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 0b4e20e06..a49ccb840 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -202,7 +202,7 @@ unique_ptr* Foo::foo() { return nullptr; } "types": [], "funcs": [], "vars": [], - "instances": [], + "instances": [2933643612409209903, 500112618220246], "uses": [] }, { "usr": 15041163540773201510, @@ -223,20 +223,18 @@ unique_ptr* Foo::foo() { return nullptr; } "uses": ["79:21-79:24|0|1|4|-1"] }, { "usr": 18153735331422331128, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, + "detailed_name": "template<> class unique_ptr, S2>", + "qual_name_offset": 17, "short_name": "unique_ptr", "kind": 5, "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "1:1-2:17|0|1|0|-1", "alias_of": 0, "bases": [], "derived": [], "types": [], "funcs": [], "vars": [], - "instances": [2933643612409209903, 500112618220246], + "instances": [], "uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"] }], "usr2var": [{ @@ -247,7 +245,7 @@ unique_ptr* Foo::foo() { return nullptr; } "declarations": [], "spell": "54:39-54:44|18320186404467436976|3|2|-1", "extent": "54:3-54:44|18320186404467436976|3|0|-1", - "type": 18153735331422331128, + "type": 14209198335088845323, "uses": [], "kind": 13, "storage": 0 @@ -257,7 +255,7 @@ unique_ptr* Foo::foo() { return nullptr; } "qual_name_offset": 42, "short_name": "f", "declarations": ["15:43-15:44|15:1-15:44|0|1|1|-1"], - "type": 18153735331422331128, + "type": 14209198335088845323, "uses": [], "kind": 13, "storage": 1 diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 1893c26e4..9f7c8da2f 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -26,25 +26,8 @@ static unique_ptr foo; "types": [], "funcs": [], "vars": [], - "instances": [], - "uses": ["6:8-6:18|0|1|4|-1"] - }, { - "usr": 4186953406371619898, - "detailed_name": "unique_ptr", - "qual_name_offset": 0, - "short_name": "unique_ptr", - "kind": 26, - "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "1:1-2:20|0|1|0|-1", - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], "instances": [3398408600781120939], - "uses": [] + "uses": ["6:8-6:18|0|1|4|-1"] }, { "usr": 4750332761459066907, "detailed_name": "struct S", @@ -69,7 +52,7 @@ static unique_ptr foo; "declarations": [], "spell": "6:22-6:25|0|1|2|-1", "extent": "6:1-6:25|0|1|0|-1", - "type": 4186953406371619898, + "type": 3286534761799572592, "uses": [], "kind": 13, "storage": 2 diff --git a/src/indexer.cc b/src/indexer.cc index a6b70ca12..27607db57 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -283,41 +283,6 @@ const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { return D; } -const Decl *GetSpecialized(const Decl *D) { - if (!D) - return D; - Decl *Template = nullptr; - if (const CXXRecordDecl *CXXRecord = dyn_cast(D)) { - if (const ClassTemplatePartialSpecializationDecl *PartialSpec = - dyn_cast(CXXRecord)) - Template = PartialSpec->getSpecializedTemplate(); - else if (const ClassTemplateSpecializationDecl *ClassSpec = - dyn_cast(CXXRecord)) { - llvm::PointerUnion - Result = ClassSpec->getSpecializedTemplateOrPartial(); - if (Result.is()) - Template = Result.get(); - else - Template = Result.get(); - - } else - Template = CXXRecord->getInstantiatedFromMemberClass(); - } else if (const FunctionDecl *Function = dyn_cast(D)) { - Template = Function->getPrimaryTemplate(); - if (!Template) - Template = Function->getInstantiatedFromMemberFunction(); - } else if (const VarDecl *Var = dyn_cast(D)) { - if (Var->isStaticDataMember()) - Template = Var->getInstantiatedFromStaticDataMember(); - } else if (const RedeclarableTemplateDecl *Tmpl = - dyn_cast(D)) - Template = Tmpl->getInstantiatedFromMemberTemplate(); - else - return nullptr; - return Template; -} - bool ValidateRecord(const RecordDecl *RD) { for (const auto *I : RD->fields()) { QualType FQT = I->getType(); @@ -778,33 +743,51 @@ class IndexDataConsumer : public index::IndexDataConsumer { var->def.type = usr1; db->ToType(usr1).instances.push_back(usr); } else { - for (const Decl *D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) { + for (const Decl *D1 = GetTypeDecl(T); D1; ) { + if (auto *R1 = dyn_cast(D1)) { + if (auto *S1 = dyn_cast(D1)) { + if (!S1->getTypeAsWritten()) { + llvm::PointerUnion + Result = S1->getSpecializedTemplateOrPartial(); + if (Result.is()) + D1 = Result.get(); + else + D1 = Result.get(); + continue; + } + } else if (auto *D2 = R1->getInstantiatedFromMemberClass()) { + D1 = D2; + continue; + } + } else if (auto *TP1 = dyn_cast(D1)) { + // e.g. TemplateTypeParmDecl is not handled by + // handleDeclOccurence. + SourceRange R1 = D1->getSourceRange(); + if (SM.getFileID(R1.getBegin()) == LocFID) { + IndexParam::DeclInfo *info1; + Usr usr1 = GetUsr(D1, &info1); + IndexType &type1 = db->ToType(usr1); + SourceLocation L1 = D1->getLocation(); + type1.def.spell = + GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, + Role::Definition); + type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), + LexDC, Role::None); + type1.def.detailed_name = Intern(info1->short_name); + type1.def.short_name_size = int16_t(info1->short_name.size()); + type1.def.kind = lsSymbolKind::TypeParameter; + var->def.type = usr1; + type1.instances.push_back(usr); + break; + } + } + IndexParam::DeclInfo *info1; Usr usr1 = GetUsr(D1, &info1); - auto it = db->usr2type.find(usr1); - if (it != db->usr2type.end()) { - var->def.type = usr1; - it->second.instances.push_back(usr); - break; - } - // e.g. TemplateTypeParmDecl is not handled by - // handleDeclOccurence. - SourceRange R1 = D1->getSourceRange(); - if (SM.getFileID(R1.getBegin()) == LocFID) { - IndexType &type1 = db->ToType(usr1); - SourceLocation L1 = D1->getLocation(); - type1.def.spell = - GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, - Role::Definition); - type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), - LexDC, Role::None); - type1.def.detailed_name = Intern(info1->short_name); - type1.def.short_name_size = int16_t(info1->short_name.size()); - type1.def.kind = lsSymbolKind::TypeParameter; - var->def.type = usr1; - type1.instances.push_back(usr); - break; - } + var->def.type = usr1; + db->ToType(usr1).instances.push_back(usr); + break; } } } From f9bd84a97583a4299b4a8768dcb37fa1c71ff0ca Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Sep 2018 00:31:23 -0700 Subject: [PATCH 220/378] Clean up FileConsumer and improve pipeline --- src/file_consumer.cc | 88 ++++++++++---------------------------------- src/file_consumer.h | 39 +++++++------------- src/indexer.cc | 35 ++++++++++-------- src/pipeline.cc | 27 ++++++-------- src/pipeline.hh | 1 - src/utils.cc | 12 +++++- src/utils.h | 1 + 7 files changed, 76 insertions(+), 127 deletions(-) diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 7f8cca71a..1859e0238 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -21,62 +21,17 @@ limitations under the License. #include "platform.h" #include "utils.h" -namespace { - -std::optional -GetFileContents(const std::string &path, - std::unordered_map *file_contents) { - auto it = file_contents->find(path); - if (it == file_contents->end()) { - std::optional content = ReadContent(path); - if (content) - (*file_contents)[path] = FileContents(path, *content); - return content; - } - return it->second.content; -} - -} // namespace - -FileContents::FileContents(const std::string &path, const std::string &content) - : path(path), content(content) { - line_offsets_.push_back(0); - for (size_t i = 0; i < content.size(); i++) { - if (content[i] == '\n') - line_offsets_.push_back(i + 1); - } -} - -std::optional FileContents::ToOffset(Position p) const { - if (0 <= p.line && size_t(p.line) < line_offsets_.size()) { - int ret = line_offsets_[p.line] + p.column; - if (size_t(ret) < content.size()) - return ret; - } - return std::nullopt; +bool VFS::Loaded(const std::string &path) { + std::lock_guard lock(mutex); + return state[path].loaded; } -std::optional FileContents::ContentsInRange(Range range) const { - std::optional start_offset = ToOffset(range.start), - end_offset = ToOffset(range.end); - if (start_offset && end_offset && *start_offset < *end_offset) - return content.substr(*start_offset, *end_offset - *start_offset); - return std::nullopt; -} - -VFS::State VFS::Get(const std::string &file) { - std::lock_guard lock(mutex); - auto it = state.find(file); - if (it != state.end()) - return it->second; - return {0, 0}; -} - -bool VFS::Stamp(const std::string &file, int64_t ts, int64_t offset) { +bool VFS::Stamp(const std::string &path, int64_t ts, int step) { std::lock_guard lock(mutex); - State &st = state[file]; - if (st.timestamp < ts) { - st.timestamp = ts + offset; + State &st = state[path]; + if (st.timestamp < ts || (st.timestamp == ts && st.step < step)) { + st.timestamp = ts; + st.step = step; return true; } else return false; @@ -87,29 +42,26 @@ FileConsumer::FileConsumer(VFS *vfs, const std::string &parse_file) IndexFile *FileConsumer::TryConsumeFile( const clang::FileEntry &File, - std::unordered_map *file_contents_map) { + const std::unordered_map + &UID2File) { auto UniqueID = File.getUniqueID(); - auto it = local_.find(UniqueID); - if (it != local_.end()) - return it->second.get(); + { + auto it = local_.find(UniqueID); + if (it != local_.end()) + return it->second.get(); + } - std::string file_name = FileName(File); - int64_t tim = File.getModificationTime(); - assert(tim); - if (!vfs_->Stamp(file_name, tim, 0)) { + auto it = UID2File.find(UniqueID); + assert(it != UID2File.end()); + assert(it->second.mtime); + if (!vfs_->Stamp(it->second.path, it->second.mtime, 1)) { local_[UniqueID] = nullptr; return nullptr; } - // Read the file contents, if we fail then we cannot index the file. - std::optional contents = - GetFileContents(file_name, file_contents_map); - if (!contents) - return nullptr; - // Build IndexFile instance. local_[UniqueID] = - std::make_unique(UniqueID, file_name, *contents); + std::make_unique(UniqueID, it->second.path, it->second.content); return local_[UniqueID].get(); } diff --git a/src/file_consumer.h b/src/file_consumer.h index ab2bebcca..4722ec8b1 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -27,29 +27,17 @@ limitations under the License. struct IndexFile; -struct FileContents { - FileContents() = default; - FileContents(const std::string &path, const std::string &content); - - std::optional ToOffset(Position p) const; - std::optional ContentsInRange(Range range) const; - - std::string path; - std::string content; - // {0, 1 + position of first newline, 1 + position of second newline, ...} - std::vector line_offsets_; -}; - struct VFS { struct State { int64_t timestamp; - bool loaded = false; + int step; + bool loaded; }; mutable std::unordered_map state; mutable std::mutex mutex; - State Get(const std::string &file); - bool Stamp(const std::string &file, int64_t ts, int64_t offset); + bool Loaded(const std::string &path); + bool Stamp(const std::string &path, int64_t ts, int step); }; namespace std { @@ -70,17 +58,18 @@ template <> struct hash { // The indexer does this because header files do not have their own translation // units but we still want to index them. struct FileConsumer { + struct File { + std::string path; + int64_t mtime; + std::string content; + }; + FileConsumer(VFS *vfs, const std::string &parse_file); - // Returns IndexFile for the file or nullptr. |is_first_ownership| is set - // to true iff the function just took ownership over the file. Otherwise it - // is set to false. - // - // note: file_contents is passed as a parameter instead of as a member - // variable since it is large and we do not want to copy it. - IndexFile * - TryConsumeFile(const clang::FileEntry &file, - std::unordered_map *file_contents); + // Returns IndexFile or nullptr for the file or nullptr. + IndexFile *TryConsumeFile( + const clang::FileEntry &file, + const std::unordered_map &); // Returns and passes ownership of all local state. std::vector> TakeLocalState(); diff --git a/src/indexer.cc b/src/indexer.cc index 27607db57..686768c2f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -49,10 +49,8 @@ constexpr int kInitializerMaxLines = 3; GroupMatch *multiVersionMatcher; struct IndexParam { - std::unordered_map SeenUniqueID; + std::unordered_map UID2File; std::unordered_map UID2multi; - std::unordered_map file_contents; - std::unordered_map file2mtime; struct DeclInfo { Usr usr; std::string short_name; @@ -68,17 +66,22 @@ struct IndexParam { void SeenFile(const FileEntry &File) { // If this is the first time we have seen the file (ignoring if we are // generating an index for it): - auto [it, inserted] = SeenUniqueID.try_emplace(File.getUniqueID()); + auto [it, inserted] = UID2File.try_emplace(File.getUniqueID()); if (inserted) { - std::string file_name = FileName(File); - it->second = file_name; - file2mtime[file_name] = File.getModificationTime(); + std::string path = FileName(File); + it->second.path = path; + it->second.mtime = File.getModificationTime(); + if (!it->second.mtime) + if (auto tim = LastWriteTime(path)) + it->second.mtime = *tim; + if (std::optional content = ReadContent(path)) + it->second.content = *content; } } IndexFile *ConsumeFile(const FileEntry &FE) { SeenFile(FE); - return file_consumer->TryConsumeFile(FE, &file_contents); + return file_consumer->TryConsumeFile(FE, UID2File); } bool UseMultiVersion(const FileEntry &FE) { @@ -1344,15 +1347,15 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, for (auto &it : entry->usr2var) Uniquify(it.second.uses); - // Update file contents and modification time. - entry->mtime = param.file2mtime[entry->path]; - - // Update dependencies for the file. Do not include the file in its own - // dependency set. - for (auto &[_, path] : param.SeenUniqueID) - if (path != entry->path && path != entry->import_file) + // Update dependencies for the file. + for (auto &[_, file] : param.UID2File) { + const std::string &path = file.path; + if (path == entry->path) + entry->mtime = file.mtime; + else if (path != entry->import_file) entry->dependencies[llvm::CachedHashStringRef(Intern(path))] = - param.file2mtime[path]; + file.mtime; + } } return result; diff --git a/src/pipeline.cc b/src/pipeline.cc index 0b5a0f6fb..c748b96b9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -206,16 +206,21 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, std::optional write_time = LastWriteTime(path_to_index); if (!write_time) return true; - int reparse = vfs->Stamp(path_to_index, *write_time, -1); + int reparse = vfs->Stamp(path_to_index, *write_time, 0); if (request.path != path_to_index) { std::optional mtime1 = LastWriteTime(request.path); if (!mtime1) return true; - if (vfs->Stamp(request.path, *mtime1, -1)) + if (vfs->Stamp(request.path, *mtime1, 0)) reparse = 1; } - if (g_config->index.onChange) + if (g_config->index.onChange) { reparse = 2; + std::lock_guard lock(vfs->mutex); + vfs->state[path_to_index].step = 0; + if (request.path != path_to_index) + vfs->state[request.path].step = 0; + } if (!reparse) return true; @@ -242,6 +247,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, LOG_S(INFO) << "load cache for " << path_to_index; auto dependencies = prev->dependencies; if (reparse) { + if (vfs->Loaded(path_to_index)) + return true; IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); @@ -309,12 +316,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, << ")"; { std::lock_guard lock(mutexes[std::hash()(path) % N_MUTEXES]); - bool loaded; - { - std::lock_guard lock1(vfs->mutex); - loaded = vfs->state[path].loaded; - } - if (loaded) + if (vfs->Loaded(path)) prev = RawCacheLoad(path); else prev.reset(); @@ -543,13 +545,6 @@ void Index(const std::string &path, const std::vector &args, index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } -std::optional LastWriteTime(const std::string &path) { - sys::fs::file_status Status; - if (sys::fs::status(path, Status)) - return {}; - return sys::toTimeT(Status.getLastModificationTime()); -} - std::optional LoadIndexedContent(const std::string &path) { if (g_config->cacheDirectory.empty()) { std::shared_lock lock(g_index_mutex); diff --git a/src/pipeline.hh b/src/pipeline.hh index 0cbabffc3..285dfb802 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -46,7 +46,6 @@ void MainLoop(); void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {}); -std::optional LastWriteTime(const std::string &path); std::optional LoadIndexedContent(const std::string& path); void WriteStdout(MethodType method, lsBaseOutMessage &response); } // namespace pipeline diff --git a/src/utils.cc b/src/utils.cc index df5b98c8f..f9e3dcdad 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -20,7 +20,10 @@ limitations under the License. #include -#include "llvm/ADT/StringRef.h" +#include +#include +#include +using namespace llvm; #include #include @@ -124,6 +127,13 @@ std::string EscapeFileName(std::string path) { return path; } +std::optional LastWriteTime(const std::string &path) { + sys::fs::file_status Status; + if (sys::fs::status(path, Status)) + return {}; + return sys::toTimeT(Status.getLastModificationTime()); +} + std::optional ReadContent(const std::string &filename) { char buf[4096]; std::string ret; diff --git a/src/utils.h b/src/utils.h index 40352e1af..113a21475 100644 --- a/src/utils.h +++ b/src/utils.h @@ -73,6 +73,7 @@ void EnsureEndsInSlash(std::string &path); // e.g. foo/bar.c => foo_bar.c std::string EscapeFileName(std::string path); +std::optional LastWriteTime(const std::string &path); std::optional ReadContent(const std::string &filename); void WriteToFile(const std::string &filename, const std::string &content); From 41756297ef35ffdcb2774aea596243c5b85281c5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Sep 2018 17:20:09 -0700 Subject: [PATCH 221/378] Simplify semantic highlighting --- src/config.h | 2 +- src/message_handler.cc | 83 +++++++--------------------- src/message_handler.h | 37 +++---------- src/messages/initialize.cc | 2 +- src/messages/textDocument_didOpen.cc | 2 +- src/pipeline.cc | 13 +++-- src/test.cc | 13 ++++- src/utils.cc | 10 ---- src/utils.h | 3 - 9 files changed, 47 insertions(+), 118 deletions(-) diff --git a/src/config.h b/src/config.h index 816c024ca..f9194c082 100644 --- a/src/config.h +++ b/src/config.h @@ -146,7 +146,7 @@ struct Config { // auto-completion. An example value is { ".h", ".hpp" } // // This is significantly faster than using a regex. - std::vector includeSuffixWhitelist = {".h", ".hpp", ".hh"}; + std::vector includeSuffixWhitelist = {".h", ".hpp", ".hh", ".inc"}; std::vector includeWhitelist; } completion; diff --git a/src/message_handler.cc b/src/message_handler.cc index ab6d937b6..aa2924a3d 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -16,6 +16,7 @@ limitations under the License. #include "message_handler.h" #include "log.hh" +#include "match.h" #include "pipeline.hh" #include "project.h" #include "query_utils.h" @@ -59,74 +60,34 @@ struct ScanLineEvent { }; } // namespace -SemanticHighlightSymbolCache::Entry::Entry( - SemanticHighlightSymbolCache *all_caches, const std::string &path) - : all_caches_(all_caches), path(path) {} - -std::optional SemanticHighlightSymbolCache::Entry::TryGetStableId( - SymbolKind kind, const std::string &detailed_name) { - TNameToId *map = GetMapForSymbol_(kind); - auto it = map->find(detailed_name); - if (it != map->end()) - return it->second; - - return std::nullopt; -} - -int SemanticHighlightSymbolCache::Entry::GetStableId( - SymbolKind kind, const std::string &detailed_name) { - std::optional id = TryGetStableId(kind, detailed_name); - if (id) - return *id; - - // Create a new id. First try to find a key in another map. - all_caches_->cache_.IterateValues([&](const std::shared_ptr &entry) { - std::optional other_id = entry->TryGetStableId(kind, detailed_name); - if (other_id) { - id = other_id; - return false; - } - return true; - }); - - // Create a new id. - TNameToId *map = GetMapForSymbol_(kind); - if (!id) - id = all_caches_->next_stable_id_++; - return (*map)[detailed_name] = *id; -} - -SemanticHighlightSymbolCache::Entry::TNameToId * -SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) { +int SemanticHighlight::GetStableId(SymbolKind kind, Usr usr) { + decltype(func2id) *map; switch (kind) { - case SymbolKind::Type: - return &detailed_type_name_to_stable_id; case SymbolKind::Func: - return &detailed_func_name_to_stable_id; + map = &func2id; + break; + case SymbolKind::Type: + map = &type2id; + break; case SymbolKind::Var: - return &detailed_var_name_to_stable_id; + map = &var2id; + break; case SymbolKind::File: case SymbolKind::Invalid: - break; + llvm_unreachable(""); } - assert(false); - return nullptr; -} -SemanticHighlightSymbolCache::SemanticHighlightSymbolCache() - : cache_(kCacheSize) {} + auto it = map->try_emplace(usr, next_id); + if (it.second) + next_id++; + return it.first->second; +} -void SemanticHighlightSymbolCache::Init() { +void SemanticHighlight::Init() { match_ = std::make_unique(g_config->highlight.whitelist, g_config->highlight.blacklist); } -std::shared_ptr -SemanticHighlightSymbolCache::GetCacheForFile(const std::string &path) { - return cache_.Get( - path, [&, this]() { return std::make_shared(this, path); }); -} - MessageHandler::MessageHandler() { // Dynamically allocate |message_handlers|, otherwise there will be static // initialization order races. @@ -196,15 +157,12 @@ void EmitSkippedRanges(WorkingFile *working_file, pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out); } -void EmitSemanticHighlighting(DB *db, - SemanticHighlightSymbolCache *semantic_cache, +void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, WorkingFile *wfile, QueryFile *file) { assert(file->def); if (wfile->buffer_content.size() > g_config->largeFileSize || - !semantic_cache->match_->IsMatch(file->def->path)) + !highlight->match_->IsMatch(file->def->path)) return; - auto semantic_cache_for_file = - semantic_cache->GetCacheForFile(file->def->path); // Group symbols together. std::unordered_map @@ -300,8 +258,7 @@ void EmitSemanticHighlighting(DB *db, it->second.lsRanges.push_back(*loc); } else { Out_CclsPublishSemanticHighlighting::Symbol symbol; - symbol.stableId = semantic_cache_for_file->GetStableId( - sym.kind, std::string(detailed_name)); + symbol.stableId = highlight->GetStableId(sym.kind, sym.usr); symbol.parentKind = parent_kind; symbol.kind = kind; symbol.storage = storage; diff --git a/src/message_handler.h b/src/message_handler.h index ac1c80217..b71102956 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -17,7 +17,6 @@ limitations under the License. #include "lru_cache.h" #include "lsp.h" -#include "match.h" #include "method.h" #include "query.h" @@ -29,6 +28,7 @@ limitations under the License. struct CompletionManager; struct Config; class DiagnosticsPublisher; +struct GroupMatch; struct VFS; struct IncludeComplete; struct MultiQueueWaiter; @@ -39,35 +39,13 @@ struct WorkingFiles; // Caches symbols for a single file for semantic highlighting to provide // relatively stable ids. Only supports xxx files at a time. -struct SemanticHighlightSymbolCache { - struct Entry { - SemanticHighlightSymbolCache *all_caches_ = nullptr; - - // The path this cache belongs to. - std::string path; - // Detailed symbol name to stable id. - using TNameToId = std::unordered_map; - TNameToId detailed_type_name_to_stable_id; - TNameToId detailed_func_name_to_stable_id; - TNameToId detailed_var_name_to_stable_id; - - Entry(SemanticHighlightSymbolCache *all_caches, const std::string &path); - - std::optional TryGetStableId(SymbolKind kind, - const std::string &detailed_name); - int GetStableId(SymbolKind kind, const std::string &detailed_name); - - TNameToId *GetMapForSymbol_(SymbolKind kind); - }; - - constexpr static int kCacheSize = 10; - LruCache cache_; - uint32_t next_stable_id_ = 0; +struct SemanticHighlight { + llvm::DenseMap func2id, type2id, var2id; + uint32_t next_id = 0; std::unique_ptr match_; - SemanticHighlightSymbolCache(); void Init(); - std::shared_ptr GetCacheForFile(const std::string &path); + int GetStableId(SymbolKind kind, Usr usr); }; struct Out_CclsPublishSemanticHighlighting @@ -114,7 +92,7 @@ struct MessageHandler { Project *project = nullptr; DiagnosticsPublisher *diag_pub = nullptr; VFS *vfs = nullptr; - SemanticHighlightSymbolCache *semantic_cache = nullptr; + SemanticHighlight *highlight = nullptr; WorkingFiles *working_files = nullptr; CompletionManager *clang_complete = nullptr; IncludeComplete *include_complete = nullptr; @@ -144,6 +122,5 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, void EmitSkippedRanges(WorkingFile *working_file, const std::vector &skipped_ranges); -void EmitSemanticHighlighting(DB *db, - SemanticHighlightSymbolCache *semantic_cache, +void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, WorkingFile *working_file, QueryFile *file); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 07a5e90d9..2e5e52133 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -488,7 +488,7 @@ struct Handler_Initialize : BaseMessageHandler { diag_pub->Init(); idx::Init(); - semantic_cache->Init(); + highlight->Init(); // Open up / load the project. project->Load(project_path); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 4e76e8e9f..4911a3384 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -60,7 +60,7 @@ struct Handler_TextDocumentDidOpen FindFileOrFail(db, project, std::nullopt, path, &file); if (file && file->def) { EmitSkippedRanges(working_file, file->def->skipped_ranges); - EmitSemanticHighlighting(db, semantic_cache, working_file, file); + EmitSemanticHighlighting(db, highlight, working_file, file); } include_complete->AddFile(working_file->filename); diff --git a/src/pipeline.cc b/src/pipeline.cc index c748b96b9..99b4784ce 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -20,6 +20,7 @@ limitations under the License. #include "include_complete.h" #include "log.hh" #include "lsp.h" +#include "match.h" #include "message_handler.h" #include "pipeline.hh" #include "platform.h" @@ -370,7 +371,7 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, indexer_waiter->Wait(index_request); } -void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, +void Main_OnIndexed(DB *db, SemanticHighlight *highlight, WorkingFiles *working_files, IndexUpdate *update) { if (update->refresh) { LOG_S(INFO) @@ -381,7 +382,7 @@ void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, if (db->name2file_id.find(filename) == db->name2file_id.end()) continue; QueryFile *file = &db->files[db->name2file_id[filename]]; - EmitSemanticHighlighting(db, semantic_cache, f.get(), file); + EmitSemanticHighlighting(db, highlight, f.get(), file); } return; } @@ -401,7 +402,7 @@ void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache, wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content : def_u.second); EmitSkippedRanges(wfile, def_u.first.skipped_ranges); - EmitSemanticHighlighting(db, semantic_cache, wfile, + EmitSemanticHighlighting(db, highlight, wfile, &db->files[update->file_id]); } } @@ -472,7 +473,7 @@ void LaunchStdout() { void MainLoop() { Project project; - SemanticHighlightSymbolCache semantic_cache; + SemanticHighlight highlight; WorkingFiles working_files; VFS vfs; DiagnosticsPublisher diag_pub; @@ -503,7 +504,7 @@ void MainLoop() { handler->project = &project; handler->diag_pub = &diag_pub; handler->vfs = &vfs; - handler->semantic_cache = &semantic_cache; + handler->highlight = &highlight; handler->working_files = &working_files; handler->clang_complete = &clang_complete; handler->include_complete = &include_complete; @@ -530,7 +531,7 @@ void MainLoop() { if (!update) break; did_work = true; - Main_OnIndexed(&db, &semantic_cache, &working_files, &*update); + Main_OnIndexed(&db, &highlight, &working_files, &*update); } if (!did_work) { diff --git a/src/test.cc b/src/test.cc index 52bd35062..6c595200e 100644 --- a/src/test.cc +++ b/src/test.cc @@ -23,6 +23,8 @@ limitations under the License. #include "utils.h" #include +#include +using namespace llvm; #include #include @@ -80,6 +82,12 @@ struct TextReplacer { } }; +void TrimInPlace(std::string &s) { + auto f = [](char c) { return !isspace(c); }; + s.erase(s.begin(), std::find_if(s.begin(), s.end(), f)); + s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end()); +} + void ParseTestExpectation( const std::string &filename, const std::vector &lines_with_endings, TextReplacer *replacer, @@ -89,7 +97,7 @@ void ParseTestExpectation( { bool in_output = false; for (std::string line : lines_with_endings) { - TrimInPlace(line); + line = StringRef(line).trim().str(); if (StartsWith(line, "EXTRA_FLAGS:")) { assert(!in_output && "multiple EXTRA_FLAGS sections"); @@ -125,8 +133,7 @@ void ParseTestExpectation( // one token assume it is a filename. std::vector tokens = SplitString(line_with_ending, " "); if (tokens.size() > 1) { - active_output_filename = tokens[1]; - TrimInPlace(active_output_filename); + active_output_filename = StringRef(tokens[1]).trim().str(); } else { active_output_filename = filename; } diff --git a/src/utils.cc b/src/utils.cc index f9e3dcdad..6d3e06af3 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -33,16 +33,6 @@ using namespace llvm; #include #include -void TrimInPlace(std::string &s) { - auto f = [](char c) { return !isspace(c); }; - s.erase(s.begin(), std::find_if(s.begin(), s.end(), f)); - s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end()); -} -std::string Trim(std::string s) { - TrimInPlace(s); - return s; -} - uint64_t HashUsr(std::string_view s) { union { uint64_t ret; diff --git a/src/utils.h b/src/utils.h index 113a21475..d34187bc9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -28,9 +28,6 @@ namespace llvm { class StringRef; } -void TrimInPlace(std::string &s); -std::string Trim(std::string s); - uint64_t HashUsr(std::string_view s); uint64_t HashUsr(llvm::StringRef s); From 4d76108d6b4e7a048ca6baee567fe1659ac40c08 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Sep 2018 18:04:55 -0700 Subject: [PATCH 222/378] Delete file_consumer.* --- CMakeLists.txt | 1 - src/file_consumer.cc | 75 --------------------------------- src/file_consumer.h | 82 ------------------------------------- src/indexer.cc | 33 +++++++++++---- src/indexer.h | 12 +++++- src/messages/ccls_reload.cc | 5 +-- src/pipeline.cc | 21 ++++++++++ src/pipeline.hh | 15 +++++++ src/test.cc | 1 + 9 files changed, 73 insertions(+), 172 deletions(-) delete mode 100644 src/file_consumer.cc delete mode 100644 src/file_consumer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 20a4bd918..3985e1290 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,7 +183,6 @@ target_sources(ccls PRIVATE src/clang_tu.cc src/clang_utils.cc src/config.cc - src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc src/main.cc diff --git a/src/file_consumer.cc b/src/file_consumer.cc deleted file mode 100644 index 1859e0238..000000000 --- a/src/file_consumer.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "file_consumer.h" - -#include "clang_utils.h" -#include "indexer.h" -#include "log.hh" -#include "platform.h" -#include "utils.h" - -bool VFS::Loaded(const std::string &path) { - std::lock_guard lock(mutex); - return state[path].loaded; -} - -bool VFS::Stamp(const std::string &path, int64_t ts, int step) { - std::lock_guard lock(mutex); - State &st = state[path]; - if (st.timestamp < ts || (st.timestamp == ts && st.step < step)) { - st.timestamp = ts; - st.step = step; - return true; - } else - return false; -} - -FileConsumer::FileConsumer(VFS *vfs, const std::string &parse_file) - : vfs_(vfs), parse_file_(parse_file) {} - -IndexFile *FileConsumer::TryConsumeFile( - const clang::FileEntry &File, - const std::unordered_map - &UID2File) { - auto UniqueID = File.getUniqueID(); - { - auto it = local_.find(UniqueID); - if (it != local_.end()) - return it->second.get(); - } - - auto it = UID2File.find(UniqueID); - assert(it != UID2File.end()); - assert(it->second.mtime); - if (!vfs_->Stamp(it->second.path, it->second.mtime, 1)) { - local_[UniqueID] = nullptr; - return nullptr; - } - - // Build IndexFile instance. - local_[UniqueID] = - std::make_unique(UniqueID, it->second.path, it->second.content); - return local_[UniqueID].get(); -} - -std::vector> FileConsumer::TakeLocalState() { - std::vector> result; - for (auto &entry : local_) { - if (entry.second) - result.push_back(std::move(entry.second)); - } - return result; -} diff --git a/src/file_consumer.h b/src/file_consumer.h deleted file mode 100644 index 4722ec8b1..000000000 --- a/src/file_consumer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "position.h" -#include "serializer.h" -#include "utils.h" - -#include - -#include -#include -#include - -struct IndexFile; - -struct VFS { - struct State { - int64_t timestamp; - int step; - bool loaded; - }; - mutable std::unordered_map state; - mutable std::mutex mutex; - - bool Loaded(const std::string &path); - bool Stamp(const std::string &path, int64_t ts, int step); -}; - -namespace std { -template <> struct hash { - std::size_t operator()(llvm::sys::fs::UniqueID ID) const { - size_t ret = ID.getDevice(); - hash_combine(ret, ID.getFile()); - return ret; - } -}; -} // namespace std - -// FileConsumer is used by the indexer. When it encouters a file, it tries to -// take ownership over it. If the indexer has ownership over a file, it will -// produce an index, otherwise, it will emit nothing for that declarations -// and references coming from that file. -// -// The indexer does this because header files do not have their own translation -// units but we still want to index them. -struct FileConsumer { - struct File { - std::string path; - int64_t mtime; - std::string content; - }; - - FileConsumer(VFS *vfs, const std::string &parse_file); - - // Returns IndexFile or nullptr for the file or nullptr. - IndexFile *TryConsumeFile( - const clang::FileEntry &file, - const std::unordered_map &); - - // Returns and passes ownership of all local state. - std::vector> TakeLocalState(); - -private: - std::unordered_map> - local_; - VFS *vfs_; - std::string parse_file_; -}; diff --git a/src/indexer.cc b/src/indexer.cc index 686768c2f..080511b7a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -19,6 +19,7 @@ limitations under the License. #include "clang_tu.h" #include "log.hh" #include "match.h" +#include "pipeline.hh" #include "platform.h" #include "serializer.h" using namespace ccls; @@ -48,8 +49,15 @@ constexpr int kInitializerMaxLines = 3; GroupMatch *multiVersionMatcher; +struct File { + std::string path; + int64_t mtime; + std::string content; + std::unique_ptr db; +}; + struct IndexParam { - std::unordered_map UID2File; + std::unordered_map UID2File; std::unordered_map UID2multi; struct DeclInfo { Usr usr; @@ -58,10 +66,9 @@ struct IndexParam { }; std::unordered_map Decl2Info; + VFS &vfs; ASTContext *Ctx; - FileConsumer *file_consumer = nullptr; - - IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {} + IndexParam(VFS &vfs) : vfs(vfs) {} void SeenFile(const FileEntry &File) { // If this is the first time we have seen the file (ignoring if we are @@ -76,12 +83,17 @@ struct IndexParam { it->second.mtime = *tim; if (std::optional content = ReadContent(path)) it->second.content = *content; + + if (!vfs.Stamp(path, it->second.mtime, 1)) + return; + it->second.db = std::make_unique(File.getUniqueID(), path, + it->second.content); } } IndexFile *ConsumeFile(const FileEntry &FE) { SeenFile(FE); - return file_consumer->TryConsumeFile(FE, UID2File); + return UID2File[FE.getUniqueID()].db.get(); } bool UseMultiVersion(const FileEntry &FE) { @@ -1287,8 +1299,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, if (!Clang->hasTarget()) return {}; - FileConsumer file_consumer(vfs, file); - IndexParam param(&file_consumer); + IndexParam param(*vfs); auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; @@ -1325,8 +1336,11 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, for (auto &Buf : Bufs) Buf.release(); - auto result = param.file_consumer->TakeLocalState(); - for (std::unique_ptr &entry : result) { + std::vector> result; + for (auto &it : param.UID2File) { + if (!it.second.db) + continue; + std::unique_ptr &entry = it.second.db; entry->import_file = file; entry->args = args; for (auto &[_, it] : entry->uid2lid_and_path) @@ -1356,6 +1370,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, entry->dependencies[llvm::CachedHashStringRef(Intern(path))] = file.mtime; } + result.push_back(std::move(entry)); } return result; diff --git a/src/indexer.h b/src/indexer.h index 173065522..2dbe6d6f8 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -16,7 +16,6 @@ limitations under the License. #pragma once #include "clang_utils.h" -#include "file_consumer.h" #include "language.h" #include "lsp.h" #include "lsp_diagnostic.h" @@ -236,6 +235,16 @@ struct IndexInclude { const char *resolved_path; }; +namespace std { +template <> struct hash { + std::size_t operator()(llvm::sys::fs::UniqueID ID) const { + size_t ret = ID.getDevice(); + hash_combine(ret, ID.getFile()); + return ret; + } +}; +} // namespace std + struct IndexFile { // For both JSON and MessagePack cache files. static const int kMajorVersion; @@ -287,6 +296,7 @@ struct IndexFile { struct CompletionManager; struct WorkingFiles; +struct VFS; namespace ccls::idx { void Init(); diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index bc67cc26f..0368d486c 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -47,10 +47,7 @@ struct Handler_CclsReload : BaseMessageHandler { const auto ¶ms = request->params; // Send index requests for every file. if (params.whitelist.empty() && params.blacklist.empty()) { - { - std::lock_guard lock(vfs->mutex); - vfs->state.clear(); - } + vfs->Clear(); db->clear(); project->Index(working_files, lsRequestId()); return; diff --git a/src/pipeline.cc b/src/pipeline.cc index 99b4784ce..99ca5a1b4 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -74,6 +74,27 @@ void DiagnosticsPublisher::Publish(WorkingFiles *working_files, } } +void VFS::Clear() { + std::lock_guard lock(mutex); + state.clear(); +} + +bool VFS::Loaded(const std::string &path) { + std::lock_guard lock(mutex); + return state[path].loaded; +} + +bool VFS::Stamp(const std::string &path, int64_t ts, int step) { + std::lock_guard lock(mutex); + State &st = state[path]; + if (st.timestamp < ts || (st.timestamp == ts && st.step < step)) { + st.timestamp = ts; + st.step = step; + return true; + } else + return false; +} + namespace ccls::pipeline { int64_t loaded_ts = 0, tick = 0; diff --git a/src/pipeline.hh b/src/pipeline.hh index 285dfb802..1fb3bac3c 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -4,6 +4,7 @@ #include "method.h" #include "query.h" +#include #include #include #include @@ -27,6 +28,20 @@ class DiagnosticsPublisher { std::vector diagnostics); }; +struct VFS { + struct State { + int64_t timestamp; + int step; + bool loaded; + }; + std::unordered_map state; + std::mutex mutex; + + void Clear(); + bool Loaded(const std::string &path); + bool Stamp(const std::string &path, int64_t ts, int step); +}; + namespace ccls { enum class IndexMode { NonInteractive, diff --git a/src/test.cc b/src/test.cc index 6c595200e..69cf85364 100644 --- a/src/test.cc +++ b/src/test.cc @@ -18,6 +18,7 @@ limitations under the License. #include "clang_complete.hh" #include "filesystem.hh" #include "indexer.h" +#include "pipeline.hh" #include "platform.h" #include "serializer.h" #include "utils.h" From 1a519163da8fcba302d0223b3a20468c538db352 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Sat, 22 Sep 2018 23:57:36 +0800 Subject: [PATCH 223/378] Remove chunks with CK_Information kind from insertText. (#78) Without this ccls inserts "size() const" in the following scenario: std::string text; text.si| <-- Trigger completion here and pick "size" --- src/messages/textDocument_completion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 545490da0..e4bc36dc6 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -426,7 +426,7 @@ void BuildItem(std::vector &out, out[i].insertText += "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; out[i].insertTextFormat = lsInsertTextFormat::Snippet; - } else { + } else if (Kind != CodeCompletionString::CK_Informative) { out[i].insertText += text; } } From 28d33324b13a548465144dfd49755220a18c9811 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Sep 2018 01:37:00 -0700 Subject: [PATCH 224/378] Publish diagnostics of inferred files and change diagnostics.{onChange,onOpen,onSave} from bool to debounce time --- src/clang_complete.cc | 260 +++++++++--------- src/clang_complete.hh | 31 +-- src/config.h | 26 +- src/message_handler.h | 2 - src/messages/ccls_reload.cc | 2 + src/messages/initialize.cc | 1 - src/messages/textDocument_didChange.cc | 5 +- src/messages/textDocument_didClose.cc | 2 +- src/messages/textDocument_didOpen.cc | 6 +- .../workspace_didChangeWatchedFiles.cc | 4 +- src/pipeline.cc | 43 +-- src/pipeline.hh | 12 - src/project.cc | 9 - src/utils.cc | 9 + src/utils.h | 3 + 15 files changed, 186 insertions(+), 229 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 078da29de..ab90d6b81 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -18,6 +18,7 @@ limitations under the License. #include "clang_utils.h" #include "filesystem.hh" #include "log.hh" +#include "match.h" #include "platform.h" #include @@ -32,7 +33,10 @@ using namespace clang; using namespace llvm; #include +#include +#include #include +namespace chrono = std::chrono; namespace ccls { namespace { @@ -80,22 +84,34 @@ class StoreDiags : public DiagnosticConsumer { const LangOptions *LangOpts; std::optional last; std::vector output; + std::string path; + std::unordered_map FID2concerned; void Flush() { if (!last) return; - bool mentions = last->inside_main || last->edits.size(); + bool mentions = last->concerned || last->edits.size(); if (!mentions) for (auto &N : last->notes) - if (N.inside_main) + if (N.concerned) mentions = true; if (mentions) output.push_back(std::move(*last)); last.reset(); } public: + StoreDiags(std::string path) : path(path) {} std::vector Take() { return std::move(output); } + bool IsConcerned(const SourceManager &SM, SourceLocation L) { + FileID FID = SM.getFileID(L); + auto it = FID2concerned.try_emplace(FID.getHashValue()); + if (it.second) { + const FileEntry *FE = SM.getFileEntryForID(FID); + it.first->second = FE && FileName(*FE) == path; + } + return it.first->second; + } void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override { LangOpts = &Opts; } @@ -108,24 +124,25 @@ class StoreDiags : public DiagnosticConsumer { SourceLocation L = Info.getLocation(); if (!L.isValid()) return; const SourceManager &SM = Info.getSourceManager(); - bool inside_main = SM.isInMainFile(L); + StringRef Filename = SM.getFilename(Info.getLocation()); + bool concerned = IsConcerned(SM, Info.getLocation()); auto fillDiagBase = [&](DiagBase &d) { llvm::SmallString<64> Message; Info.FormatDiagnostic(Message); d.range = FromCharSourceRange(SM, *LangOpts, DiagnosticRange(Info, *LangOpts)); d.message = Message.str(); - d.inside_main = inside_main; - d.file = SM.getFilename(Info.getLocation()); + d.concerned = concerned; + d.file = Filename; d.level = Level; d.category = DiagnosticIDs::getCategoryNumberForDiag(Info.getID()); }; auto addFix = [&](bool SyntheticMessage) -> bool { - if (!inside_main) + if (!concerned) return false; for (const FixItHint &FixIt : Info.getFixItHints()) { - if (!SM.isInMainFile(FixIt.RemoveRange.getBegin())) + if (!IsConcerned(SM, FixIt.RemoveRange.getBegin())) return false; lsTextEdit edit; edit.newText = FixIt.CodeToInsert; @@ -158,9 +175,10 @@ std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, std::vector> &Bufs) { + std::string main = ResolveIfRelative(session.file.directory, CI->getFrontendOpts().Inputs[0].getFile()); for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); - if (file.filename == session.file.filename) { + if (file.filename == main) if (auto Preamble = session.GetPreamble()) { #if LLVM_VERSION_MAJOR >= 7 Preamble->Preamble.OverridePreamble(*CI, session.FS, @@ -169,14 +187,10 @@ std::unique_ptr BuildCompilerInstance( Preamble->Preamble.AddImplicitPreamble(*CI, session.FS, Bufs.back().get()); #endif - } else { - CI->getPreprocessorOpts().addRemappedFile( - CI->getFrontendOpts().Inputs[0].getFile(), Bufs.back().get()); + continue; } - } else { - CI->getPreprocessorOpts().addRemappedFile(file.filename, - Bufs.back().get()); - } + CI->getPreprocessorOpts().addRemappedFile(file.filename, + Bufs.back().get()); } auto Clang = std::make_unique(session.PCH); @@ -202,52 +216,53 @@ bool Parse(CompilerInstance &Clang) { void CompletionPreloadMain(CompletionManager *manager) { while (true) { - // Fetching the completion request blocks until we have a request. auto request = manager->preload_requests_.Dequeue(); - // If we don't get a session then that means we don't care about the file - // anymore - abandon the request. - std::shared_ptr session = manager->TryGetSession( - request.path, false /*mark_as_completion*/, false /*create_if_needed*/); + bool is_open = false; + std::shared_ptr session = + manager->TryGetSession(request.path, true, &is_open); if (!session) continue; - const auto &args = session->file.args; - WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( - {StripFileType(session->file.filename)}); - - LOG_S(INFO) << "create completion session for " << session->file.filename; - if (std::unique_ptr CI = - BuildCompilerInvocation(args, session->FS)) - session->BuildPreamble(*CI); - if (g_config->diagnostics.onSave) { + // For inferred session, don't build preamble because changes in a.h will + // invalidate it. + if (!session->inferred) { + const auto &args = session->file.args; + WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( + {StripFileType(session->file.filename)}); + if (std::unique_ptr CI = + BuildCompilerInvocation(args, session->FS)) + session->BuildPreamble(*CI, request.path); + } + int debounce = + is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; + if (debounce >= 0) { lsTextDocumentIdentifier document; document.uri = lsDocumentUri::FromPath(request.path); - manager->diagnostic_request_.PushBack({document}, true); + manager->DiagnosticsUpdate(request.path, debounce); } } } -void CompletionMain(CompletionManager *completion_manager) { +void CompletionMain(CompletionManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. std::unique_ptr request = - completion_manager->completion_request_.Dequeue(); + manager->completion_request_.Dequeue(); // Drop older requests if we're not buffering. while (g_config->completion.dropOldRequests && - !completion_manager->completion_request_.IsEmpty()) { - completion_manager->on_dropped_(request->id); + !manager->completion_request_.IsEmpty()) { + manager->on_dropped_(request->id); request->Consumer.reset(); request->on_complete(nullptr); - request = completion_manager->completion_request_.Dequeue(); + request = manager->completion_request_.Dequeue(); } std::string path = request->document.uri.GetPath(); std::shared_ptr session = - completion_manager->TryGetSession(path, true /*mark_as_completion*/, - true /*create_if_needed*/); + manager->TryGetSession(path, false); std::unique_ptr CI = BuildCompilerInvocation(session->file.args, session->FS); @@ -263,7 +278,7 @@ void CompletionMain(CompletionManager *completion_manager) { DiagnosticConsumer DC; WorkingFiles::Snapshot snapshot = - completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; auto Clang = BuildCompilerInstance(*session, std::move(CI), DC, snapshot, Bufs); if (!Clang) @@ -297,25 +312,31 @@ llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) { } void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { - if (d.inside_main) + if (d.concerned) OS << llvm::sys::path::filename(d.file); else OS << d.file; auto pos = d.range.start; OS << ":" << (pos.line + 1) << ":" << (pos.column + 1) << ":" - << (d.inside_main ? " " : "\n"); + << (d.concerned ? " " : "\n"); OS << diagLeveltoString(d.level) << ": " << d.message; } void DiagnosticMain(CompletionManager *manager) { while (true) { - // Fetching the completion request blocks until we have a request. CompletionManager::DiagnosticRequest request = manager->diagnostic_request_.Dequeue(); - std::string path = request.document.uri.GetPath(); + const std::string &path = request.path; + int64_t wait = request.wait_until - + chrono::duration_cast( + chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + if (wait > 0) + std::this_thread::sleep_for(chrono::duration( + std::min(wait, request.debounce))); - std::shared_ptr session = manager->TryGetSession( - path, true /*mark_as_completion*/, true /*create_if_needed*/); + std::shared_ptr session = + manager->TryGetSession(path, false); std::unique_ptr CI = BuildCompilerInvocation(session->file.args, session->FS); @@ -323,7 +344,7 @@ void DiagnosticMain(CompletionManager *manager) { continue; CI->getDiagnosticOpts().IgnoreWarnings = false; CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; - StoreDiags DC; + StoreDiags DC(path); WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; @@ -359,9 +380,12 @@ void DiagnosticMain(CompletionManager *manager) { return ret; }; + std::vector diags = DC.Take(); + if (std::shared_ptr preamble = session->GetPreamble()) + diags.insert(diags.end(), preamble->diags.begin(), preamble->diags.end()); std::vector ls_diags; - for (auto &d : DC.Take()) { - if (!d.inside_main) + for (auto &d : diags) { + if (!d.concerned) continue; std::string buf; llvm::raw_string_ostream OS(buf); @@ -376,7 +400,7 @@ void DiagnosticMain(CompletionManager *manager) { OS.flush(); ls_diag.message = std::move(buf); for (auto &n : d.notes) { - if (!n.inside_main) + if (!n.concerned) continue; lsDiagnostic &ls_diag1 = ls_diags.emplace_back(); Fill(n, ls_diag1); @@ -386,6 +410,12 @@ void DiagnosticMain(CompletionManager *manager) { ls_diag1.message = std::move(buf); } } + + { + std::lock_guard lock(session->wfiles->files_mutex); + if (WorkingFile *wfile = session->wfiles->GetFileByFilenameNoLock(path)) + wfile->diagnostics_ = ls_diags; + } manager->on_diagnostic_(path, ls_diags); } } @@ -397,9 +427,10 @@ std::shared_ptr CompletionSession::GetPreamble() { return preamble; } -void CompletionSession::BuildPreamble(CompilerInvocation &CI) { +void CompletionSession::BuildPreamble(CompilerInvocation &CI, + const std::string &main) { std::shared_ptr OldP = GetPreamble(); - std::string content = wfiles->GetContent(file.filename); + std::string content = wfiles->GetContent(main); std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(content); auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); @@ -412,7 +443,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { CI.getPreprocessorOpts().WriteCommentListToPCH = false; #endif - StoreDiags DC; + StoreDiags DC(main); IntrusiveRefCntPtr DE = CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &DC, false); PreambleCallbacks PP; @@ -432,8 +463,8 @@ CompletionManager::CompletionManager(Project *project, OnDropped on_dropped) : project_(project), working_files_(working_files), on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), - preloaded_sessions_(kMaxPreloadedSessions), - completion_sessions_(kMaxCompletionSessions), + preloads(kMaxPreloadedSessions), + sessions(kMaxCompletionSessions), PCH(std::make_shared()) { std::thread([&]() { set_thread_name("comp"); @@ -452,22 +483,28 @@ CompletionManager::CompletionManager(Project *project, .detach(); } -void CompletionManager::CodeComplete( - const lsRequestId &id, - const lsTextDocumentPositionParams &completion_location, - const OnComplete &on_complete) { -} - -void CompletionManager::DiagnosticsUpdate( - const lsTextDocumentIdentifier &document) { - bool has = false; - diagnostic_request_.Iterate([&](const DiagnosticRequest &request) { - if (request.document.uri == document.uri) - has = true; - }); - if (!has) - diagnostic_request_.PushBack(DiagnosticRequest{document}, - true /*priority*/); +void CompletionManager::DiagnosticsUpdate(const std::string &path, + int debounce) { + static GroupMatch match(g_config->diagnostics.whitelist, + g_config->diagnostics.blacklist); + if (!match.IsMatch(path)) + return; + int64_t now = chrono::duration_cast( + chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + bool flag = false; + { + std::lock_guard lock(diag_mutex); + int64_t &next = next_diag[path]; + auto &d = g_config->diagnostics; + if (next <= now || + now - next > std::max(d.onChange, std::max(d.onChange, d.onSave))) { + next = now + debounce; + flag = true; + } + } + if (flag) + diagnostic_request_.PushBack({path, now + debounce, debounce}, false); } void CompletionManager::NotifyView(const std::string &path) { @@ -477,94 +514,67 @@ void CompletionManager::NotifyView(const std::string &path) { } void CompletionManager::NotifySave(const std::string &filename) { - // - // On save, always reparse. - // - EnsureCompletionOrCreatePreloadSession(filename); preload_requests_.PushBack(PreloadRequest{filename}, true); } -void CompletionManager::NotifyClose(const std::string &filename) { - // - // On close, we clear any existing CompletionSession instance. - // - +void CompletionManager::OnClose(const std::string &filename) { std::lock_guard lock(sessions_lock_); - - // Take and drop. It's okay if we don't actually drop the file, it'll - // eventually get pushed out of the caches as the user opens other files. - auto preloaded_ptr = preloaded_sessions_.TryTake(filename); - LOG_IF_S(INFO, !!preloaded_ptr) - << "Dropped preloaded-based code completion session for " << filename; - auto completion_ptr = completion_sessions_.TryTake(filename); - LOG_IF_S(INFO, !!completion_ptr) - << "Dropped completion-based code completion session for " << filename; - - // We should never have both a preloaded and completion session. - assert((preloaded_ptr && completion_ptr) == false); + preloads.TryTake(filename); + sessions.TryTake(filename); } bool CompletionManager::EnsureCompletionOrCreatePreloadSession( const std::string &path) { std::lock_guard lock(sessions_lock_); - - // Check for an existing CompletionSession. - if (preloaded_sessions_.TryGet(path) || - completion_sessions_.TryGet(path)) { + if (preloads.TryGet(path) || sessions.TryGet(path)) return false; - } // No CompletionSession, create new one. auto session = std::make_shared( project_->FindCompilationEntryForFile(path), working_files_, PCH); - preloaded_sessions_.Insert(session->file.filename, session); + if (session->file.filename != path) { + session->inferred = true; + session->file.filename = path; + } + preloads.Insert(path, session); + LOG_S(INFO) << "create preload session for " << path; return true; } std::shared_ptr -CompletionManager::TryGetSession(const std::string &path, - bool mark_as_completion, - bool create_if_needed) { +CompletionManager::TryGetSession(const std::string &path, bool preload, + bool *is_open) { std::lock_guard lock(sessions_lock_); - - // Try to find a preloaded session. - std::shared_ptr preloaded = - preloaded_sessions_.TryGet(path); - - if (preloaded) { - // If this request is for a completion, we should move it to - // |completion_sessions|. - if (mark_as_completion) { - preloaded_sessions_.TryTake(path); - completion_sessions_.Insert(path, preloaded); + std::shared_ptr session = preloads.TryGet(path); + + if (session) { + if (!preload) { + preloads.TryTake(path); + sessions.Insert(path, session); + if (is_open) + *is_open = true; } - return preloaded; + return session; } - // Try to find a completion session. If none create one. - std::shared_ptr session = - completion_sessions_.TryGet(path); - if (!session && create_if_needed) { + session = sessions.TryGet(path); + if (!session && !preload) { session = std::make_shared( project_->FindCompilationEntryForFile(path), working_files_, PCH); - completion_sessions_.Insert(path, session); + sessions.Insert(path, session); + LOG_S(INFO) << "create session for " << path; + if (is_open) + *is_open = true; } return session; } -void CompletionManager::FlushSession(const std::string &path) { - std::lock_guard lock(sessions_lock_); - - preloaded_sessions_.TryTake(path); - completion_sessions_.TryTake(path); -} - void CompletionManager::FlushAllSessions() { LOG_S(INFO) << "flush all clang complete sessions"; std::lock_guard lock(sessions_lock_); - preloaded_sessions_.Clear(); - completion_sessions_.Clear(); + preloads.Clear(); + sessions.Clear(); } diff --git a/src/clang_complete.hh b/src/clang_complete.hh index c72326922..45d16dcdd 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -39,7 +39,7 @@ struct DiagBase { std::string file; clang::DiagnosticsEngine::Level level = clang::DiagnosticsEngine::Note; unsigned category; - bool inside_main = false; + bool concerned = false; }; struct Note : DiagBase {}; struct Diag : DiagBase { @@ -58,10 +58,10 @@ struct CompletionSession : public std::enable_shared_from_this { std::mutex mutex; std::shared_ptr preamble; - std::vector diags; Project::Entry file; WorkingFiles *wfiles; + bool inferred = false; // TODO share llvm::IntrusiveRefCntPtr FS = @@ -73,7 +73,7 @@ struct CompletionSession : file(file), wfiles(wfiles), PCH(PCH) {} std::shared_ptr GetPreamble(); - void BuildPreamble(clang::CompilerInvocation &CI); + void BuildPreamble(clang::CompilerInvocation &CI, const std::string &main); }; } @@ -107,19 +107,16 @@ struct CompletionManager { OnComplete on_complete; }; struct DiagnosticRequest { - lsTextDocumentIdentifier document; + std::string path; + int64_t wait_until; + int64_t debounce; }; CompletionManager(Project *project, WorkingFiles *working_files, OnDiagnostic on_diagnostic, OnDropped on_dropped); - // Start a code completion at the given location. |on_complete| will run when - // completion results are available. |on_complete| may run on any thread. - void CodeComplete(const lsRequestId &request_id, - const lsTextDocumentPositionParams &completion_location, - const OnComplete &on_complete); // Request a diagnostics update. - void DiagnosticsUpdate(const lsTextDocumentIdentifier &document); + void DiagnosticsUpdate(const std::string &path, int debounce); // Notify the completion manager that |filename| has been viewed and we // should begin preloading completion data. @@ -129,7 +126,7 @@ struct CompletionManager { void NotifySave(const std::string &path); // Notify the completion manager that |filename| has been closed. Any existing // completion session will be dropped. - void NotifyClose(const std::string &path); + void OnClose(const std::string &path); // Ensures there is a completion or preloaded session. Returns true if a new // session was created. @@ -137,11 +134,8 @@ struct CompletionManager { // Tries to find an edit session for |filename|. This will move the session // from view to edit. std::shared_ptr - TryGetSession(const std::string &path, bool mark_as_completion, - bool create_if_needed); + TryGetSession(const std::string &path, bool preload, bool *is_open = nullptr); - // Flushes all saved sessions with the supplied filename - void FlushSession(const std::string &path); // Flushes all saved sessions void FlushAllSessions(void); @@ -159,14 +153,17 @@ struct CompletionManager { // CompletionSession instances which are preloaded, ie, files which the user // has viewed but not requested code completion for. - LruSessionCache preloaded_sessions_; + LruSessionCache preloads; // CompletionSession instances which the user has actually performed // completion on. This is more rare so these instances tend to stay alive // much longer than the ones in |preloaded_sessions_|. - LruSessionCache completion_sessions_; + LruSessionCache sessions; // Mutex which protects |view_sessions_| and |edit_sessions_|. std::mutex sessions_lock_; + std::mutex diag_mutex; + std::unordered_map next_diag; + // Request a code completion at the given location. ThreadedQueue> completion_request_; ThreadedQueue diagnostic_request_; diff --git a/src/config.h b/src/config.h index f9194c082..b8a4d05b1 100644 --- a/src/config.h +++ b/src/config.h @@ -156,20 +156,18 @@ struct Config { // blacklisted files. std::vector blacklist; - // How often should ccls publish diagnostics in completion? - // -1: never - // 0: as often as possible - // xxx: at most every xxx milliseconds - int frequencyMs = 0; + // Time to wait before computing diagnostics for textDocument/didChange. + // -1: disable diagnostics on change + // 0: immediately + // positive (e.g. 500): wait for 500 milliseconds. didChange requests in + // this period of time will only cause one computation. + int onChange = 1000; - // If true, diagnostics will be reported for textDocument/didChange. - bool onChange = true; + // Time to wait before computing diagnostics for textDocument/didOpen. + int onOpen = 0; - // If true, diagnostics will be reported for textDocument/didOpen. - bool onOpen = true; - - // If true, diagnostics will be reported for textDocument/didSave. - bool onSave = true; + // Time to wait before computing diagnostics for textDocument/didSave. + int onSave = 0; bool spellChecking = true; @@ -258,8 +256,8 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, dropOldRequests, duplicateOptional, filterAndSort, includeBlacklist, includeMaxPathSize, includeSuffixWhitelist, includeWhitelist); -MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, - onOpen, onSave, spellChecking, whitelist) +MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, + spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, diff --git a/src/message_handler.h b/src/message_handler.h index b71102956..1d7904329 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -27,7 +27,6 @@ limitations under the License. struct CompletionManager; struct Config; -class DiagnosticsPublisher; struct GroupMatch; struct VFS; struct IncludeComplete; @@ -90,7 +89,6 @@ struct MessageHandler { DB *db = nullptr; MultiQueueWaiter *waiter = nullptr; Project *project = nullptr; - DiagnosticsPublisher *diag_pub = nullptr; VFS *vfs = nullptr; SemanticHighlight *highlight = nullptr; WorkingFiles *working_files = nullptr; diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 0368d486c..6a450655d 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "clang_complete.hh" #include "match.h" #include "message_handler.h" #include "pipeline.hh" @@ -50,6 +51,7 @@ struct Handler_CclsReload : BaseMessageHandler { vfs->Clear(); db->clear(); project->Index(working_files, lsRequestId()); + clang_complete->FlushAllSessions(); return; } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 2e5e52133..bce54fb9f 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -486,7 +486,6 @@ struct Handler_Initialize : BaseMessageHandler { sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); } - diag_pub->Init(); idx::Init(); highlight->Init(); diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc index 7488ff2f5..76bdef49c 100644 --- a/src/messages/textDocument_didChange.cc +++ b/src/messages/textDocument_didChange.cc @@ -42,9 +42,8 @@ struct Handler_TextDocumentDidChange if (g_config->index.onChange) pipeline::Index(path, {}, IndexMode::OnChange); clang_complete->NotifyView(path); - if (g_config->diagnostics.onChange) - clang_complete->DiagnosticsUpdate( - params.textDocument.AsTextDocumentIdentifier()); + if (g_config->diagnostics.onChange >= 0) + clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index 8e3f504fb..c905f154a 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -47,7 +47,7 @@ struct Handler_TextDocumentDidClose // Remove internal state. working_files->OnClose(request->params.textDocument); - clang_complete->NotifyClose(path); + clang_complete->OnClose(path); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 4911a3384..27eb8f411 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -71,14 +71,10 @@ struct Handler_TextDocumentDidOpen project->SetArgsForFile(args, path); // Submit new index request if it is not a header file. - if (SourceFileLanguage(path) != LanguageId::Unknown) { + if (SourceFileLanguage(path) != LanguageId::Unknown) pipeline::Index(path, args, IndexMode::Normal); - clang_complete->FlushSession(path); - } clang_complete->NotifyView(path); - if (g_config->diagnostics.onOpen) - clang_complete->DiagnosticsUpdate({params.textDocument.uri}); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc index fd5806d16..d338cfc8f 100644 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ b/src/messages/workspace_didChangeWatchedFiles.cc @@ -64,12 +64,12 @@ struct Handler_WorkspaceDidChangeWatchedFiles if (mode == IndexMode::Normal) clang_complete->NotifySave(path); else - clang_complete->FlushSession(path); + clang_complete->OnClose(path); break; } case lsFileChangeType::Deleted: pipeline::Index(path, {}, mode); - clang_complete->FlushSession(path); + clang_complete->OnClose(path); break; } } diff --git a/src/pipeline.cc b/src/pipeline.cc index 99ca5a1b4..631ecd7b6 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -39,41 +39,6 @@ using namespace llvm; #include #endif -void DiagnosticsPublisher::Init() { - frequencyMs_ = g_config->diagnostics.frequencyMs; - match_ = std::make_unique(g_config->diagnostics.whitelist, - g_config->diagnostics.blacklist); -} - -void DiagnosticsPublisher::Publish(WorkingFiles *working_files, - std::string path, - std::vector diagnostics) { - bool good = true; - // Cache diagnostics so we can show fixits. - working_files->DoActionOnFile(path, [&](WorkingFile *working_file) { - if (working_file) { - good = working_file->diagnostics_.empty(); - working_file->diagnostics_ = diagnostics; - } - }); - - int64_t now = - std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count(); - if (frequencyMs_ >= 0 && - (nextPublish_ <= now || (!good && diagnostics.empty())) && - match_->IsMatch(path)) { - nextPublish_ = now + frequencyMs_; - - Out_TextDocumentPublishDiagnostics out; - out.params.uri = lsDocumentUri::FromPath(path); - out.params.diagnostics = diagnostics; - ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, - out); - } -} - void VFS::Clear() { std::lock_guard lock(mutex); state.clear(); @@ -497,12 +462,15 @@ void MainLoop() { SemanticHighlight highlight; WorkingFiles working_files; VFS vfs; - DiagnosticsPublisher diag_pub; CompletionManager clang_complete( &project, &working_files, [&](std::string path, std::vector diagnostics) { - diag_pub.Publish(&working_files, path, diagnostics); + Out_TextDocumentPublishDiagnostics out; + out.params.uri = lsDocumentUri::FromPath(path); + out.params.diagnostics = diagnostics; + ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, + out); }, [](lsRequestId id) { if (id.Valid()) { @@ -523,7 +491,6 @@ void MainLoop() { handler->db = &db; handler->waiter = indexer_waiter; handler->project = &project; - handler->diag_pub = &diag_pub; handler->vfs = &vfs; handler->highlight = &highlight; handler->working_files = &working_files; diff --git a/src/pipeline.hh b/src/pipeline.hh index 1fb3bac3c..920053c8b 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -16,18 +16,6 @@ struct Project; struct WorkingFiles; struct lsBaseOutMessage; -class DiagnosticsPublisher { - std::unique_ptr match_; - int64_t nextPublish_ = 0; - int frequencyMs_; - - public: - void Init(); - void Publish(WorkingFiles* working_files, - std::string path, - std::vector diagnostics); -}; - struct VFS { struct State { int64_t timestamp; diff --git a/src/project.cc b/src/project.cc index 98f840832..f4beb6c0b 100644 --- a/src/project.cc +++ b/src/project.cc @@ -66,15 +66,6 @@ enum OptionClass { Separate, }; -std::string ResolveIfRelative(const std::string &directory, - const std::string &path) { - if (sys::path::is_absolute(path)) - return path; - SmallString<256> Ret; - sys::path::append(Ret, directory, path); - return NormalizePath(Ret.str()); -} - struct ProjectProcessor { ProjectConfig *config; std::unordered_set command_set; diff --git a/src/utils.cc b/src/utils.cc index 6d3e06af3..6a2f9e50c 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -117,6 +117,15 @@ std::string EscapeFileName(std::string path) { return path; } +std::string ResolveIfRelative(const std::string &directory, + const std::string &path) { + if (sys::path::is_absolute(path)) + return path; + SmallString<256> Ret; + sys::path::append(Ret, directory, path); + return NormalizePath(Ret.str()); +} + std::optional LastWriteTime(const std::string &path) { sys::fs::file_status Status; if (sys::fs::status(path, Status)) diff --git a/src/utils.h b/src/utils.h index d34187bc9..7b4087cec 100644 --- a/src/utils.h +++ b/src/utils.h @@ -70,6 +70,9 @@ void EnsureEndsInSlash(std::string &path); // e.g. foo/bar.c => foo_bar.c std::string EscapeFileName(std::string path); +std::string ResolveIfRelative(const std::string &directory, + const std::string &path); + std::optional LastWriteTime(const std::string &path); std::optional ReadContent(const std::string &filename); void WriteToFile(const std::string &filename, const std::string &content); From 6ea399559deaad8beef05a34af8653f8cda8a85d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Sep 2018 18:00:50 -0700 Subject: [PATCH 225/378] Fix spurious "Failed to index" errors --- src/indexer.cc | 6 ++++-- src/indexer.h | 5 +++-- src/pipeline.cc | 5 +++-- src/test.cc | 3 ++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 080511b7a..45af8e7eb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1235,15 +1235,18 @@ std::vector> Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector> &remapped) { + const std::vector> &remapped, bool &ok) { + ok = true; if (!g_config->index.enabled) return {}; auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); std::shared_ptr CI = BuildCompilerInvocation(args, FS); + // e.g. .s if (!CI) return {}; + ok = false; // -fparse-all-comments enables documentation in the indexer and in // code completion. if (g_config->index.comments > 1) @@ -1313,7 +1316,6 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); - bool ok = false; { llvm::CrashRecoveryContext CRC; auto parse = [&]() { diff --git a/src/indexer.h b/src/indexer.h index 2dbe6d6f8..553ee640b 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -304,5 +304,6 @@ std::vector> Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector> &remapped); -} + const std::vector> &remapped, + bool &ok); +} // namespace ccls::idx diff --git a/src/pipeline.cc b/src/pipeline.cc index 631ecd7b6..9864a09b6 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -278,10 +278,11 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (content.size()) remapped.emplace_back(path_to_index, content); } + bool ok; auto indexes = idx::Index(completion, wfiles, vfs, entry.directory, - path_to_index, entry.args, remapped); + path_to_index, entry.args, remapped, ok); - if (indexes.empty()) { + if (!ok) { if (g_config->index.enabled && request.id.Valid()) { Out_Error out; out.id = request.id; diff --git a/src/test.cc b/src/test.cc index 69cf85364..57af162c7 100644 --- a/src/test.cc +++ b/src/test.cc @@ -317,7 +317,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { std::vector cargs; for (auto &arg : flags) cargs.push_back(arg.c_str()); - auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, cargs, {}); + bool ok; + auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, cargs, {}, ok); for (const auto &entry : all_expected_output) { const std::string &expected_path = entry.first; From 7eb58bb5e13d7c5f99e2bae5d197bed3d868de7c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Sep 2018 22:05:24 -0700 Subject: [PATCH 226/378] Misc --- src/indexer.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/indexer.cc b/src/indexer.cc index 45af8e7eb..069f4e419 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -660,6 +660,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::CXXConversion: // *operator* int => *operator int* case Decl::CXXDestructor: // *~*A => *~A* case Decl::CXXMethod: // *operator*= => *operator=* + case Decl::Function: // operator delete if (Loc.isFileID()) { SourceRange R = cast(OrigD)->getNameInfo().getSourceRange(); From 22daed7001db3331d795617d0356a5b78bcf6e21 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Sep 2018 22:55:17 -0700 Subject: [PATCH 227/378] Add kind to $ccls/member and iterate all QueryType::def kind:2 => member functions kind:3 => nested classes / namespace members --- README.md | 6 +- src/messages/ccls_member.cc | 155 ++++++++++++++++++++++++------------ 2 files changed, 106 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 1f85d442d..e3349def2 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,14 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery), * code completion (with both signature help and snippets) * [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDcument_references.cc), and other cross references - * hierarchies: [call (caller/callee) hierarchy](src/messages/ccls_callHierarchy.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritanceHierarchy.cc), [member hierarchy](src/messages/ccls_memberHierarchy.cc) - * [symbol rename](src/messages/text_documentRename.cc) + * cross reference extensions: `$ccls/call` `$ccls/inheritance` `$ccls/member` `$ccls/vars` ... + * hierarchies: [call (caller/callee) hierarchy](src/messages/ccls_call.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance.cc), [member hierarchy](src/messages/ccls_member.cc) + * [symbol rename](src/messages/textDocument_rename.cc) * [document symbols](src/messages/textDocument_documentSymbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) * [hover information](src/messages/textDocument_hover.cc) * diagnostics and code actions (clang FixIts) * semantic highlighting and preprocessor skipped regions + * semantic navigation: `$ccls/navigate` It has a global view of the code base and support a lot of cross reference features, see [wiki/FAQ](../../wiki/FAQ). It starts indexing the whole project (including subprojects if exist) parallelly when you open the first file, while the main thread can serve requests before the indexing is complete. diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index d70add570..e95c70659 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -20,6 +20,7 @@ limitations under the License. using namespace ccls; #include +#include using namespace clang; #include @@ -42,12 +43,15 @@ struct In_CclsMember : public RequestInMessage { bool qualified = false; int levels = 1; + // If SymbolKind::Func and the point is at a type, list member functions + // instead of member variables. + SymbolKind kind = SymbolKind::Var; bool hierarchy = false; } params; }; MAKE_REFLECT_STRUCT(In_CclsMember::Params, textDocument, position, id, - qualified, levels, hierarchy); + qualified, levels, kind, hierarchy); MAKE_REFLECT_STRUCT(In_CclsMember, id, params); REGISTER_IN_MESSAGE(In_CclsMember); @@ -73,7 +77,7 @@ MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMember, jsonrpc, id, result); bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, - bool qualified, int levels); + bool qualified, int levels, SymbolKind memberKind); // Add a field to |entry| which is a Func/Type. void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, @@ -108,7 +112,7 @@ void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, if (def1->type) { entry1.id = std::to_string(def1->type); entry1.usr = def1->type; - if (Expand(m, &entry1, qualified, levels)) + if (Expand(m, &entry1, qualified, levels, SymbolKind::Var)) entry->children.push_back(std::move(entry1)); } else { entry1.id = "0"; @@ -119,13 +123,13 @@ void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, // Expand a type node by adding members recursively to it. bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, - bool qualified, int levels) { + bool qualified, int levels, SymbolKind memberKind) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(int(entry->usr)); return true; } - const QueryType &type = m->db->Type(entry->usr); - const QueryType::Def *def = type.AnyDef(); + const QueryType *type = &m->db->Type(entry->usr); + const QueryType::Def *def = type->AnyDef(); // builtin types have no declaration and empty |qualified|. if (!def) return false; @@ -133,51 +137,96 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, std::unordered_set seen; if (levels > 0) { std::vector stack; - seen.insert(type.usr); - stack.push_back(&type); + seen.insert(type->usr); + stack.push_back(type); while (stack.size()) { - const auto *def = stack.back()->AnyDef(); + type = stack.back(); stack.pop_back(); - if (def) { - for (Usr usr : def->bases) { - auto &type1 = m->db->Type(usr); - if (type1.def.size()) { - seen.insert(type1.usr); - stack.push_back(&type1); - } + const auto *def = type->AnyDef(); + if (!def) continue; + for (Usr usr : def->bases) { + auto &type1 = m->db->Type(usr); + if (type1.def.size()) { + seen.insert(type1.usr); + stack.push_back(&type1); } - if (def->alias_of) { - const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); - Out_CclsMember::Entry entry1; - entry1.id = std::to_string(def->alias_of); - entry1.usr = def->alias_of; - if (def1 && def1->spell) { - // The declaration of target type. - if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) - entry1.location = *loc; - } else if (def->spell) { - // Builtin types have no declaration but the typedef declaration - // itself is useful. - if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def->spell)) - entry1.location = *loc; - } - if (def1 && qualified) - entry1.fieldName = def1->detailed_name; - if (Expand(m, &entry1, qualified, levels - 1)) { - // For builtin types |name| is set. - if (entry1.fieldName.empty()) - entry1.fieldName = std::string(entry1.name); - entry->children.push_back(std::move(entry1)); - } - } else { - for (auto it : def->vars) { - QueryVar &var = m->db->Var(it.first); - if (!var.def.empty()) - DoField(m, entry, var, it.second, qualified, levels - 1); - } + } + if (def->alias_of) { + const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); + Out_CclsMember::Entry entry1; + entry1.id = std::to_string(def->alias_of); + entry1.usr = def->alias_of; + if (def1 && def1->spell) { + // The declaration of target type. + if (std::optional loc = + GetLsLocation(m->db, m->working_files, *def1->spell)) + entry1.location = *loc; + } else if (def->spell) { + // Builtin types have no declaration but the typedef declaration + // itself is useful. + if (std::optional loc = + GetLsLocation(m->db, m->working_files, *def->spell)) + entry1.location = *loc; } + if (def1 && qualified) + entry1.fieldName = def1->detailed_name; + if (Expand(m, &entry1, qualified, levels - 1, memberKind)) { + // For builtin types |name| is set. + if (entry1.fieldName.empty()) + entry1.fieldName = std::string(entry1.name); + entry->children.push_back(std::move(entry1)); + } + } else if (memberKind == SymbolKind::Func) { + llvm::DenseSet seen1; + for (auto &def : type->def) + for (Usr usr : def.funcs) + if (seen1.insert(usr).second) { + QueryFunc &func1 = m->db->Func(usr); + if (const QueryFunc::Def *def1 = func1.AnyDef()) { + Out_CclsMember::Entry entry1; + entry1.fieldName = def1->Name(false); + if (def1->spell) { + if (auto loc = + GetLsLocation(m->db, m->working_files, *def1->spell)) + entry1.location = *loc; + } else if (func1.declarations.size()) { + if (auto loc = GetLsLocation(m->db, m->working_files, + func1.declarations[0])) + entry1.location = *loc; + } + entry->children.push_back(std::move(entry1)); + } + } + } else if (memberKind == SymbolKind::Type) { + llvm::DenseSet seen1; + for (auto &def : type->def) + for (Usr usr : def.types) + if (seen1.insert(usr).second) { + QueryType &type1 = m->db->Type(usr); + if (const QueryType::Def *def1 = type1.AnyDef()) { + Out_CclsMember::Entry entry1; + entry1.fieldName = def1->Name(false); + if (def1->spell) { + if (auto loc = + GetLsLocation(m->db, m->working_files, *def1->spell)) + entry1.location = *loc; + } else if (type1.declarations.size()) { + if (auto loc = GetLsLocation(m->db, m->working_files, + type1.declarations[0])) + entry1.location = *loc; + } + entry->children.push_back(std::move(entry1)); + } + } + } else { + llvm::DenseSet seen1; + for (auto &def : type->def) + for (auto it : def.vars) + if (seen1.insert(it.first).second) { + QueryVar &var = m->db->Var(it.first); + if (!var.def.empty()) + DoField(m, entry, var, it.second, qualified, levels - 1); + } } } entry->numChildren = int(entry->children.size()); @@ -191,7 +240,7 @@ struct Handler_CclsMember MethodType GetMethodType() const override { return kMethodType; } std::optional - BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) { + BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels, SymbolKind memberKind) { switch (kind) { default: return {}; @@ -228,7 +277,7 @@ struct Handler_CclsMember GetLsLocation(db, working_files, *def->spell)) entry.location = *loc; } - Expand(this, &entry, qualified, levels); + Expand(this, &entry, qualified, levels, memberKind); return entry; } } @@ -250,7 +299,7 @@ struct Handler_CclsMember entry.usr = params.usr; // entry.name is empty as it is known by the client. if (db->HasType(entry.usr) && - Expand(this, &entry, params.qualified, params.levels)) + Expand(this, &entry, params.qualified, params.levels, params.kind)) out.result = std::move(entry); } else { QueryFile *file; @@ -263,14 +312,14 @@ struct Handler_CclsMember switch (sym.kind) { case SymbolKind::Func: case SymbolKind::Type: - out.result = - BuildInitial(sym.kind, sym.usr, params.qualified, params.levels); + out.result = BuildInitial(sym.kind, sym.usr, params.qualified, + params.levels, params.kind); break; case SymbolKind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); if (def && def->type) out.result = BuildInitial(SymbolKind::Type, def->type, - params.qualified, params.levels); + params.qualified, params.levels, params.kind); break; } default: From e320ce42ab40bea65de350b8114ef25c5f7d4f64 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Sun, 23 Sep 2018 06:10:03 +0800 Subject: [PATCH 228/378] Include macros in completion result --- src/messages/textDocument_completion.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index e4bc36dc6..474d1df89 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -634,6 +634,7 @@ struct Handler_TextDocumentCompletion #if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; #endif + CCOpts.IncludeMacros = true; if (cache.IsCacheValid(params)) { CompletionConsumer Consumer(CCOpts, true); cache.WithLock([&]() { Consumer.ls_items = cache.result; }); From 71e9835b8c29f567d1f4e49545e390ec72bf65f4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 10:20:05 -0700 Subject: [PATCH 229/378] documentSymbol: ignore TypeParameter Reported by Riatre --- src/messages/textDocument_documentSymbol.cc | 27 ++++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index f6064d196..bda4a2709 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -76,6 +76,14 @@ struct Out_HierarchicalDocumentSymbol }; MAKE_REFLECT_STRUCT(Out_HierarchicalDocumentSymbol, jsonrpc, id, result); +bool IgnoreType(const QueryType::Def *def) { + return !def || def->kind == lsSymbolKind::TypeParameter; +} + +bool IgnoreVar(const QueryVar::Def *def) { + return !def || def->is_local(); +} + struct Handler_TextDocumentDocumentSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -140,9 +148,11 @@ struct Handler_TextDocumentDocumentSymbol kv.first = static_cast(&def); } }); - if (kv.first && sym.kind == SymbolKind::Var) - if (static_cast(kv.first)->is_local()) - kv.first = nullptr; + if (kv.first && ((sym.kind == SymbolKind::Type && + IgnoreType((const QueryType::Def *)kv.first)) || + (sym.kind == SymbolKind::Var && + IgnoreVar((const QueryVar::Def *)kv.first)))) + kv.first = nullptr; if (!kv.first) { kv.second.reset(); continue; @@ -198,12 +208,11 @@ struct Handler_TextDocumentDocumentSymbol if (refcnt <= 0) continue; if (std::optional info = GetSymbolInfo(db, sym, false)) { - if (sym.kind == SymbolKind::Var) { - QueryVar &var = db->GetVar(sym); - auto *def = var.AnyDef(); - if (!def || !def->spell || def->is_local()) - continue; - } + if ((sym.kind == SymbolKind::Type && + IgnoreType(db->GetType(sym).AnyDef())) || + (sym.kind == SymbolKind::Var && + IgnoreVar(db->GetVar(sym).AnyDef()))) + continue; if (std::optional location = GetLsLocation( db, working_files, Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { From 32f7d148ca70c15382651df0adc6cb23a78fe89f Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Fri, 14 Sep 2018 05:01:37 +0800 Subject: [PATCH 230/378] Allow force disabling snippet via client.snippetSupport --- src/config.h | 4 ++-- src/messages/initialize.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.h b/src/config.h index b8a4d05b1..04d10c062 100644 --- a/src/config.h +++ b/src/config.h @@ -82,9 +82,9 @@ struct Config { struct ClientCapability { // TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport - bool hierarchicalDocumentSymbolSupport = false; + bool hierarchicalDocumentSymbolSupport = true; // TextDocumentClientCapabilities.completion.completionItem.snippetSupport - bool snippetSupport = false; + bool snippetSupport = true; } client; struct CodeLens { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index bce54fb9f..cb7951488 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -453,9 +453,9 @@ struct Handler_Initialize : BaseMessageHandler { // Client capabilities const auto &capabilities = params.capabilities; - g_config->client.snippetSupport = + g_config->client.snippetSupport &= capabilities.textDocument.completion.completionItem.snippetSupport; - g_config->client.hierarchicalDocumentSymbolSupport = + g_config->client.hierarchicalDocumentSymbolSupport &= capabilities.textDocument.documentSymbol.hierarchicalDocumentSymbolSupport; // Ensure there is a resource directory. From 854225bd3090e041bb5e00a5e8da2ba81b90c516 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 12:10:40 -0700 Subject: [PATCH 231/378] Misc Move using below #include to make preamble happy textDocument/references: if no references, first line or last line => list where this file is included malloc_trim() only if files have been indexed in last cycle Intern: use CachedHashStringRef --- src/clang_complete.cc | 4 ++- src/indexer.cc | 10 +++---- src/indexer.h | 1 - src/main.cc | 7 +++-- src/message_handler.h | 1 - src/messages/ccls_call.cc | 3 +- src/messages/ccls_member.cc | 5 ++-- src/messages/ccls_reload.cc | 7 ++--- src/messages/initialize.cc | 6 ++-- src/messages/textDocument_completion.cc | 12 +++----- src/messages/textDocument_definition.cc | 5 ++-- src/messages/textDocument_didClose.cc | 3 +- src/messages/textDocument_didOpen.cc | 3 +- src/messages/textDocument_didSave.cc | 3 +- src/messages/textDocument_references.cc | 15 ++++++---- src/messages/textDocument_signatureHelp.cc | 5 ++-- src/messages/workspace_symbol.cc | 3 +- src/pipeline.cc | 10 +++++-- src/platform_posix.cc | 2 +- src/project.cc | 12 ++++---- src/serializer.cc | 33 +++++++++++++--------- src/serializer.h | 8 +++++- 22 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index ab90d6b81..ee6386ed6 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -175,7 +175,9 @@ std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, std::vector> &Bufs) { - std::string main = ResolveIfRelative(session.file.directory, CI->getFrontendOpts().Inputs[0].getFile()); + std::string main = ResolveIfRelative( + session.file.directory, + sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile())); for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); if (file.filename == main) diff --git a/src/indexer.cc b/src/indexer.cc index 069f4e419..11fb859dd 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -22,7 +22,6 @@ limitations under the License. #include "pipeline.hh" #include "platform.h" #include "serializer.h" -using namespace ccls; #include #include @@ -33,16 +32,15 @@ using namespace ccls; #include #include #include -#include -using namespace clang; -using llvm::Timer; #include #include -#include #include #include +using namespace ccls; +using namespace clang; + namespace { constexpr int kInitializerMaxLines = 3; @@ -509,7 +507,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { def.short_name_offset = Str.size() + qualified.size() - short_name.size(); def.short_name_size = short_name.size(); Str += StringRef(qualified.data(), qualified.size()); - def.detailed_name = Intern(Str.str()); + def.detailed_name = Intern(Str); } else { SetName(D, short_name, qualified, def); } diff --git a/src/indexer.h b/src/indexer.h index 553ee640b..f74e2f8c3 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -30,7 +30,6 @@ limitations under the License. #include #include -#include #include #include #include diff --git a/src/main.cc b/src/main.cc index 558803437..4d2fb6794 100644 --- a/src/main.cc +++ b/src/main.cc @@ -20,15 +20,12 @@ limitations under the License. #include "serializers/json.h" #include "test.h" #include "working_files.h" -using namespace ccls; #include #include #include #include #include -using namespace llvm; -using namespace llvm::cl; #include @@ -38,6 +35,10 @@ using namespace llvm::cl; #include #include +using namespace ccls; +using namespace llvm; +using namespace llvm::cl; + std::string g_init_options; namespace { diff --git a/src/message_handler.h b/src/message_handler.h index 1d7904329..2e420dc38 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -87,7 +87,6 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, struct MessageHandler { DB *db = nullptr; - MultiQueueWaiter *waiter = nullptr; Project *project = nullptr; VFS *vfs = nullptr; SemanticHighlight *highlight = nullptr; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 98016480b..0ec68f8b8 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -17,10 +17,11 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include +using namespace ccls; + namespace { MethodType kMethodType = "$ccls/call"; diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index e95c70659..f17699e90 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -17,14 +17,15 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include #include -using namespace clang; #include +using namespace ccls; +using namespace clang; + namespace { MethodType kMethodType = "$ccls/member"; diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 6a450655d..67b97c258 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -17,14 +17,14 @@ limitations under the License. #include "match.h" #include "message_handler.h" #include "pipeline.hh" -#include "platform.h" #include "project.h" #include "working_files.h" -using namespace ccls; #include #include +using namespace ccls; + namespace { MethodType kMethodType = "$ccls/reload"; @@ -34,8 +34,7 @@ struct In_CclsReload : public NotificationInMessage { bool dependencies = true; std::vector whitelist; std::vector blacklist; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist, blacklist); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cb7951488..d8039aeeb 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -23,16 +23,16 @@ limitations under the License. #include "project.h" #include "serializers/json.h" #include "working_files.h" -using namespace ccls; #include #include -using namespace llvm; -#include #include #include +using namespace ccls; +using namespace llvm; + // TODO Cleanup global variables extern std::string g_init_options; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 474d1df89..411e4763c 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -20,16 +20,16 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "working_files.h" -using namespace ccls; #include #include -#include -using namespace clang; -using namespace llvm; #include +using namespace ccls; +using namespace clang; +using namespace llvm; + namespace { MethodType kMethodType = "textDocument/completion"; @@ -179,10 +179,6 @@ void FilterAndSortCompletionResponse( const std::string &complete_text, bool has_open_paren) { if (!g_config->completion.filterAndSort) return; - - static Timer timer("FilterAndSortCompletionResponse", ""); - TimeRegion region(timer); - auto &items = complete_response->result.items; auto finalize = [&]() { diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 7cff442c8..df28502d5 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -16,11 +16,12 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; -#include #include #include +#include + +using namespace ccls; namespace { MethodType kMethodType = "textDocument/definition"; diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index c905f154a..a7344e5de 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -26,8 +26,7 @@ struct In_TextDocumentDidClose : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index 27eb8f411..ec1b925a6 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -24,7 +24,6 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/didOpen"; -// Open, view, change, close file struct In_TextDocumentDidOpen : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -49,7 +48,7 @@ struct Handler_TextDocumentDidOpen // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); + const std::string &path = params.textDocument.uri.GetPath(); WorkingFile *working_file = working_files->OnOpen(params.textDocument); if (std::optional cached_file_contents = diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 87b7e7930..f00ecc11a 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -16,7 +16,6 @@ limitations under the License. #include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" -#include "project.h" using namespace ccls; namespace { @@ -44,7 +43,7 @@ struct Handler_TextDocumentDidSave void Run(In_TextDocumentDidSave *request) override { const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); + const std::string &path = params.textDocument.uri.GetPath(); pipeline::Index(path, {}, IndexMode::Normal); clang_complete->NotifySave(path); } diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 0c73a405d..f09adfc89 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -16,10 +16,11 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include +using namespace ccls; + namespace { MethodType kMethodType = "textDocument/references"; @@ -66,13 +67,17 @@ struct Handler_TextDocumentReferences if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentReferences out; out.id = request->id; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!file) { + pipeline::WriteStdout(kMethodType, out); + return; + } + bool container = g_config->xref.container; std::unordered_set seen_uses; + int line = params.position.line; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { // Found symbol. Return references. @@ -127,7 +132,7 @@ struct Handler_TextDocumentReferences // = 0, // use the current filename. std::string path; - if (params.position.line == 0) + if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1) path = file->def->path; for (const IndexInclude &include : file->def->includes) if (include.line == params.position.line) { diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 007003db1..1635cb35e 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -16,12 +16,11 @@ limitations under the License. #include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" -using namespace ccls; #include -using namespace clang; -#include +using namespace ccls; +using namespace clang; namespace { MethodType kMethodType = "textDocument/signatureHelp"; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index c78e94622..4758b38e6 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -17,13 +17,14 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include #include #include #include +using namespace ccls; + namespace { MethodType kMethodType = "workspace/symbol"; diff --git a/src/pipeline.cc b/src/pipeline.cc index 9864a09b6..4810c87c1 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -490,7 +490,6 @@ void MainLoop() { // Setup shared references. for (MessageHandler *handler : *MessageHandler::message_handlers) { handler->db = &db; - handler->waiter = indexer_waiter; handler->project = &project; handler->vfs = &vfs; handler->highlight = &highlight; @@ -499,6 +498,7 @@ void MainLoop() { handler->include_complete = &include_complete; } + bool last_indexed = false; while (true) { std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); @@ -515,18 +515,22 @@ void MainLoop() { LOG_S(ERROR) << "No handler for " << message->GetMethodType(); } - for (int i = 80; i--;) { + bool indexed = false; + for (int i = 20; i--;) { std::optional update = on_indexed->TryPopFront(); if (!update) break; did_work = true; + indexed = true; Main_OnIndexed(&db, &highlight, &working_files, &*update); } if (!did_work) { - FreeUnusedMemory(); + if (last_indexed) + FreeUnusedMemory(); main_waiter->Wait(on_indexed, on_request); } + last_indexed = indexed; } } diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 4f48896c0..1d2d59a9f 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -113,7 +113,7 @@ std::string NormalizePath(const std::string &path) { void FreeUnusedMemory() { #ifdef __GLIBC__ - malloc_trim(0); + malloc_trim(4 * 1024 * 1024); #endif } diff --git a/src/project.cc b/src/project.cc index f4beb6c0b..534d08fa2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -25,18 +25,14 @@ limitations under the License. #include "serializers/json.h" #include "utils.h" #include "working_files.h" -using namespace ccls; #include #include #include #include -#include #include #include #include -using namespace clang; -using namespace llvm; #include @@ -44,10 +40,14 @@ using namespace llvm; #include #endif -#include +#include #include #include +using namespace ccls; +using namespace clang; +using namespace llvm; + namespace { enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; @@ -399,7 +399,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) { // We couldn't find the file. Try to infer it. // TODO: Cache inferred file in a separate array (using a lock or similar) Entry *best_entry = nullptr; - int best_score = std::numeric_limits::min(); + int best_score = INT_MIN; for (Entry &entry : entries) { int score = ComputeGuessScore(filename, entry.filename); if (score > best_score) { diff --git a/src/serializer.cc b/src/serializer.cc index 8faf8ebd6..68c804931 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -166,12 +166,11 @@ void Reflect(Reader &vis, DenseMap &v) { if (vis.Format() == SerializeFormat::Json) { auto &vis1 = static_cast(vis); for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it) - v[CachedHashStringRef(Intern(it->name.GetString()))] = - it->value.GetInt64(); + v[InternH(it->name.GetString())] = it->value.GetInt64(); } else { vis.IterArray([&](Reader &entry) { Reflect(entry, name); - Reflect(entry, v[CachedHashStringRef(Intern(name))]); + Reflect(entry, v[InternH(name)]); }); } } @@ -356,18 +355,26 @@ void Reflect(Writer &visitor, SerializeFormat &value) { namespace ccls { static BumpPtrAllocator Alloc; -static DenseSet Strings; +static DenseSet Strings; static std::mutex AllocMutex; -const char *Intern(const std::string &str) { - if (str.empty()) - return ""; - StringRef Str(str.data(), str.size() + 1); +CachedHashStringRef InternH(StringRef S) { + if (S.empty()) + S = ""; + CachedHashString HS(S); std::lock_guard lock(AllocMutex); - auto R = Strings.insert(Str); - if (R.second) - *R.first = Str.copy(Alloc); - return R.first->data(); + auto R = Strings.insert(HS); + if (R.second) { + char *P = Alloc.Allocate(S.size() + 1); + memcpy(P, S.data(), S.size()); + P[S.size()] = '\0'; + *R.first = CachedHashStringRef(StringRef(P, S.size()), HS.hash()); + } + return *R.first; +} + +const char *Intern(StringRef S) { + return InternH(S).val().data(); } std::string Serialize(SerializeFormat format, IndexFile &file) { @@ -482,7 +489,7 @@ Deserialize(SerializeFormat format, const std::string &path, for (auto &it : file->dependencies) { std::string path = it.first.val().str(); DoPathMapping(path); - dependencies[CachedHashStringRef(Intern(path))] = it.second; + dependencies[InternH(path)] = it.second; } file->dependencies = std::move(dependencies); } diff --git a/src/serializer.h b/src/serializer.h index 7e2487154..5e05a4756 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -30,6 +30,11 @@ limitations under the License. #include #include +namespace llvm { +class CachedHashStringRef; +class StringRef; +} + enum class SerializeFormat { Binary, Json }; struct JsonNull {}; @@ -320,7 +325,8 @@ template void ReflectMember(Writer &vis, const char *name, T &v) { // API namespace ccls { -const char *Intern(const std::string &str); +const char *Intern(llvm::StringRef str); +llvm::CachedHashStringRef InternH(llvm::StringRef str); std::string Serialize(SerializeFormat format, IndexFile &file); std::unique_ptr Deserialize(SerializeFormat format, const std::string &path, From 8f40c0c2442572e4960b267fbaa63a068c81037d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 13:31:06 -0700 Subject: [PATCH 232/378] Remove clang_utils.* --- CMakeLists.txt | 1 - src/clang_complete.cc | 5 +- src/clang_complete.hh | 2 +- src/clang_tu.cc | 171 ++++++++++++++++++++++++++++- src/{clang_tu.h => clang_tu.hh} | 6 +- src/clang_utils.cc | 187 -------------------------------- src/clang_utils.h | 25 ----- src/indexer.cc | 12 +- src/indexer.h | 2 +- src/messages/ccls_member.cc | 1 + src/project.cc | 1 - 11 files changed, 183 insertions(+), 230 deletions(-) rename src/{clang_tu.h => clang_tu.hh} (92%) delete mode 100644 src/clang_utils.cc delete mode 100644 src/clang_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3985e1290..6b447d764 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,7 +181,6 @@ target_sources(ccls PRIVATE third_party/siphash.cc) target_sources(ccls PRIVATE src/clang_complete.cc src/clang_tu.cc - src/clang_utils.cc src/config.cc src/filesystem.cc src/fuzzy_match.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index ee6386ed6..d5efae384 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -15,13 +15,12 @@ limitations under the License. #include "clang_complete.hh" -#include "clang_utils.h" +#include "clang_tu.hh" #include "filesystem.hh" #include "log.hh" #include "match.h" #include "platform.h" -#include #include #include #include @@ -108,7 +107,7 @@ class StoreDiags : public DiagnosticConsumer { auto it = FID2concerned.try_emplace(FID.getHashValue()); if (it.second) { const FileEntry *FE = SM.getFileEntryForID(FID); - it.first->second = FE && FileName(*FE) == path; + it.first->second = FE && PathFromFileEntry(*FE) == path; } return it.first->second; } diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 45d16dcdd..7020ab4d5 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "clang_tu.h" +#include "clang_tu.hh" #include "lru_cache.h" #include "lsp_completion.h" #include "lsp_diagnostic.h" diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 536454899..f147b4c23 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -13,17 +13,33 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_tu.h" +#include "clang_tu.hh" -#include "clang_utils.h" #include "config.h" +#include "platform.h" +#include #include -using namespace clang; +#include -#include #include +using namespace clang; + +std::string PathFromFileEntry(const FileEntry &file) { + StringRef Name = file.tryGetRealPathName(); + if (Name.empty()) + Name = file.getName(); + std::string ret = NormalizePath(Name); + // Resolve /usr/include/c++/7.3.0 symlink. + if (!StartsWith(ret, g_config->projectRoot)) { + SmallString<256> dest; + llvm::sys::fs::real_path(ret, dest); + ret = llvm::sys::path::convert_to_slash(dest.str()); + } + return ret; +} + Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts, CharSourceRange R, llvm::sys::fs::UniqueID *UniqueID) { @@ -81,3 +97,150 @@ BuildCompilerInvocation(std::vector args, } return CI; } + +// clang::BuiltinType::getName without PrintingPolicy +const char *ClangBuiltinTypeName(int kind) { + switch (BuiltinType::Kind(kind)) { + case BuiltinType::Void: + return "void"; + case BuiltinType::Bool: + return "bool"; + case BuiltinType::Char_S: + return "char"; + case BuiltinType::Char_U: + return "char"; + case BuiltinType::SChar: + return "signed char"; + case BuiltinType::Short: + return "short"; + case BuiltinType::Int: + return "int"; + case BuiltinType::Long: + return "long"; + case BuiltinType::LongLong: + return "long long"; + case BuiltinType::Int128: + return "__int128"; + case BuiltinType::UChar: + return "unsigned char"; + case BuiltinType::UShort: + return "unsigned short"; + case BuiltinType::UInt: + return "unsigned int"; + case BuiltinType::ULong: + return "unsigned long"; + case BuiltinType::ULongLong: + return "unsigned long long"; + case BuiltinType::UInt128: + return "unsigned __int128"; + case BuiltinType::Half: + return "__fp16"; + case BuiltinType::Float: + return "float"; + case BuiltinType::Double: + return "double"; + case BuiltinType::LongDouble: + return "long double"; +#if LLVM_VERSION_MAJOR >= 7 + case BuiltinType::ShortAccum: + return "short _Accum"; + case BuiltinType::Accum: + return "_Accum"; + case BuiltinType::LongAccum: + return "long _Accum"; + case BuiltinType::UShortAccum: + return "unsigned short _Accum"; + case BuiltinType::UAccum: + return "unsigned _Accum"; + case BuiltinType::ULongAccum: + return "unsigned long _Accum"; + case BuiltinType::BuiltinType::ShortFract: + return "short _Fract"; + case BuiltinType::BuiltinType::Fract: + return "_Fract"; + case BuiltinType::BuiltinType::LongFract: + return "long _Fract"; + case BuiltinType::BuiltinType::UShortFract: + return "unsigned short _Fract"; + case BuiltinType::BuiltinType::UFract: + return "unsigned _Fract"; + case BuiltinType::BuiltinType::ULongFract: + return "unsigned long _Fract"; + case BuiltinType::BuiltinType::SatShortAccum: + return "_Sat short _Accum"; + case BuiltinType::BuiltinType::SatAccum: + return "_Sat _Accum"; + case BuiltinType::BuiltinType::SatLongAccum: + return "_Sat long _Accum"; + case BuiltinType::BuiltinType::SatUShortAccum: + return "_Sat unsigned short _Accum"; + case BuiltinType::BuiltinType::SatUAccum: + return "_Sat unsigned _Accum"; + case BuiltinType::BuiltinType::SatULongAccum: + return "_Sat unsigned long _Accum"; + case BuiltinType::BuiltinType::SatShortFract: + return "_Sat short _Fract"; + case BuiltinType::BuiltinType::SatFract: + return "_Sat _Fract"; + case BuiltinType::BuiltinType::SatLongFract: + return "_Sat long _Fract"; + case BuiltinType::BuiltinType::SatUShortFract: + return "_Sat unsigned short _Fract"; + case BuiltinType::BuiltinType::SatUFract: + return "_Sat unsigned _Fract"; + case BuiltinType::BuiltinType::SatULongFract: + return "_Sat unsigned long _Fract"; +#endif + case BuiltinType::Float16: + return "_Float16"; + case BuiltinType::Float128: + return "__float128"; + case BuiltinType::WChar_S: + case BuiltinType::WChar_U: + return "wchar_t"; +#if LLVM_VERSION_MAJOR >= 7 + case BuiltinType::Char8: + return "char8_t"; +#endif + case BuiltinType::Char16: + return "char16_t"; + case BuiltinType::Char32: + return "char32_t"; + case BuiltinType::NullPtr: + return "nullptr_t"; + case BuiltinType::Overload: + return ""; + case BuiltinType::BoundMember: + return ""; + case BuiltinType::PseudoObject: + return ""; + case BuiltinType::Dependent: + return ""; + case BuiltinType::UnknownAny: + return ""; + case BuiltinType::ARCUnbridgedCast: + return ""; + case BuiltinType::BuiltinFn: + return ""; + case BuiltinType::ObjCId: + return "id"; + case BuiltinType::ObjCClass: + return "Class"; + case BuiltinType::ObjCSel: + return "SEL"; + case BuiltinType::OCLSampler: + return "sampler_t"; + case BuiltinType::OCLEvent: + return "event_t"; + case BuiltinType::OCLClkEvent: + return "clk_event_t"; + case BuiltinType::OCLQueue: + return "queue_t"; + case BuiltinType::OCLReserveID: + return "reserve_id_t"; + case BuiltinType::OMPArraySection: + return ""; + default: + return ""; + } +} diff --git a/src/clang_tu.h b/src/clang_tu.hh similarity index 92% rename from src/clang_tu.h rename to src/clang_tu.hh index 1edcd5ee1..96325466f 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.hh @@ -14,13 +14,15 @@ limitations under the License. ==============================================================================*/ #pragma once + #include "position.h" #include +#include #include #include -#include +std::string PathFromFileEntry(const clang::FileEntry &file); Range FromCharSourceRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, @@ -38,3 +40,5 @@ Range FromTokenRange(const clang::SourceManager &SM, std::unique_ptr BuildCompilerInvocation(std::vector args, llvm::IntrusiveRefCntPtr VFS); + +const char *ClangBuiltinTypeName(int); diff --git a/src/clang_utils.cc b/src/clang_utils.cc deleted file mode 100644 index a58237e12..000000000 --- a/src/clang_utils.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_utils.h" - -#include "config.h" -#include "filesystem.hh" -#include "platform.h" -#include "utils.h" - -#include -#include -using namespace clang; -using namespace llvm; - -std::string FileName(const FileEntry &file) { - StringRef Name = file.tryGetRealPathName(); - if (Name.empty()) - Name = file.getName(); - std::string ret = NormalizePath(Name); - // Resolve /usr/include/c++/7.3.0 symlink. - if (!StartsWith(ret, g_config->projectRoot)) { - SmallString<256> dest; - sys::fs::real_path(ret, dest); - ret = sys::path::convert_to_slash(dest.str()); - } - return ret; -} - -// clang::BuiltinType::getName without PrintingPolicy -const char *ClangBuiltinTypeName(int kind) { - switch (BuiltinType::Kind(kind)) { - case BuiltinType::Void: - return "void"; - case BuiltinType::Bool: - return "bool"; - case BuiltinType::Char_S: - return "char"; - case BuiltinType::Char_U: - return "char"; - case BuiltinType::SChar: - return "signed char"; - case BuiltinType::Short: - return "short"; - case BuiltinType::Int: - return "int"; - case BuiltinType::Long: - return "long"; - case BuiltinType::LongLong: - return "long long"; - case BuiltinType::Int128: - return "__int128"; - case BuiltinType::UChar: - return "unsigned char"; - case BuiltinType::UShort: - return "unsigned short"; - case BuiltinType::UInt: - return "unsigned int"; - case BuiltinType::ULong: - return "unsigned long"; - case BuiltinType::ULongLong: - return "unsigned long long"; - case BuiltinType::UInt128: - return "unsigned __int128"; - case BuiltinType::Half: - return "__fp16"; - case BuiltinType::Float: - return "float"; - case BuiltinType::Double: - return "double"; - case BuiltinType::LongDouble: - return "long double"; -#if LLVM_VERSION_MAJOR >= 7 - case BuiltinType::ShortAccum: - return "short _Accum"; - case BuiltinType::Accum: - return "_Accum"; - case BuiltinType::LongAccum: - return "long _Accum"; - case BuiltinType::UShortAccum: - return "unsigned short _Accum"; - case BuiltinType::UAccum: - return "unsigned _Accum"; - case BuiltinType::ULongAccum: - return "unsigned long _Accum"; - case BuiltinType::BuiltinType::ShortFract: - return "short _Fract"; - case BuiltinType::BuiltinType::Fract: - return "_Fract"; - case BuiltinType::BuiltinType::LongFract: - return "long _Fract"; - case BuiltinType::BuiltinType::UShortFract: - return "unsigned short _Fract"; - case BuiltinType::BuiltinType::UFract: - return "unsigned _Fract"; - case BuiltinType::BuiltinType::ULongFract: - return "unsigned long _Fract"; - case BuiltinType::BuiltinType::SatShortAccum: - return "_Sat short _Accum"; - case BuiltinType::BuiltinType::SatAccum: - return "_Sat _Accum"; - case BuiltinType::BuiltinType::SatLongAccum: - return "_Sat long _Accum"; - case BuiltinType::BuiltinType::SatUShortAccum: - return "_Sat unsigned short _Accum"; - case BuiltinType::BuiltinType::SatUAccum: - return "_Sat unsigned _Accum"; - case BuiltinType::BuiltinType::SatULongAccum: - return "_Sat unsigned long _Accum"; - case BuiltinType::BuiltinType::SatShortFract: - return "_Sat short _Fract"; - case BuiltinType::BuiltinType::SatFract: - return "_Sat _Fract"; - case BuiltinType::BuiltinType::SatLongFract: - return "_Sat long _Fract"; - case BuiltinType::BuiltinType::SatUShortFract: - return "_Sat unsigned short _Fract"; - case BuiltinType::BuiltinType::SatUFract: - return "_Sat unsigned _Fract"; - case BuiltinType::BuiltinType::SatULongFract: - return "_Sat unsigned long _Fract"; -#endif - case BuiltinType::Float16: - return "_Float16"; - case BuiltinType::Float128: - return "__float128"; - case BuiltinType::WChar_S: - case BuiltinType::WChar_U: - return "wchar_t"; -#if LLVM_VERSION_MAJOR >= 7 - case BuiltinType::Char8: - return "char8_t"; -#endif - case BuiltinType::Char16: - return "char16_t"; - case BuiltinType::Char32: - return "char32_t"; - case BuiltinType::NullPtr: - return "nullptr_t"; - case BuiltinType::Overload: - return ""; - case BuiltinType::BoundMember: - return ""; - case BuiltinType::PseudoObject: - return ""; - case BuiltinType::Dependent: - return ""; - case BuiltinType::UnknownAny: - return ""; - case BuiltinType::ARCUnbridgedCast: - return ""; - case BuiltinType::BuiltinFn: - return ""; - case BuiltinType::ObjCId: - return "id"; - case BuiltinType::ObjCClass: - return "Class"; - case BuiltinType::ObjCSel: - return "SEL"; - case BuiltinType::OCLSampler: - return "sampler_t"; - case BuiltinType::OCLEvent: - return "event_t"; - case BuiltinType::OCLClkEvent: - return "clk_event_t"; - case BuiltinType::OCLQueue: - return "queue_t"; - case BuiltinType::OCLReserveID: - return "reserve_id_t"; - case BuiltinType::OMPArraySection: - return ""; - default: - return ""; - } -} diff --git a/src/clang_utils.h b/src/clang_utils.h deleted file mode 100644 index 769412a97..000000000 --- a/src/clang_utils.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include - -#include - -// Returns the absolute path to |file|. -std::string FileName(const clang::FileEntry &file); - -const char *ClangBuiltinTypeName(int); diff --git a/src/indexer.cc b/src/indexer.cc index 11fb859dd..6383c3758 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -16,7 +16,7 @@ limitations under the License. #include "indexer.h" #include "clang_complete.hh" -#include "clang_tu.h" +#include "clang_tu.hh" #include "log.hh" #include "match.h" #include "pipeline.hh" @@ -73,7 +73,7 @@ struct IndexParam { // generating an index for it): auto [it, inserted] = UID2File.try_emplace(File.getUniqueID()); if (inserted) { - std::string path = FileName(File); + std::string path = PathFromFileEntry(File); it->second.path = path; it->second.mtime = File.getModificationTime(); if (!it->second.mtime) @@ -97,7 +97,7 @@ struct IndexParam { bool UseMultiVersion(const FileEntry &FE) { auto it = UID2multi.try_emplace(FE.getUniqueID()); if (it.second) - it.first->second = multiVersionMatcher->IsMatch(FileName(FE)); + it.first->second = multiVersionMatcher->IsMatch(PathFromFileEntry(FE)); return it.first->second; } }; @@ -1099,9 +1099,9 @@ class IndexPPCallbacks : public PPCallbacks { if (!FE) return; if (IndexFile *db = param.ConsumeFile(*FE)) { - std::string file_name = FileName(*File); - if (file_name.size()) - db->includes.push_back({spell.start.line, Intern(file_name)}); + std::string path = PathFromFileEntry(*File); + if (path.size()) + db->includes.push_back({spell.start.line, Intern(path)}); } } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { diff --git a/src/indexer.h b/src/indexer.h index f74e2f8c3..0e6f4e711 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -15,7 +15,6 @@ limitations under the License. #pragma once -#include "clang_utils.h" #include "language.h" #include "lsp.h" #include "lsp_diagnostic.h" @@ -25,6 +24,7 @@ limitations under the License. #include "symbol.h" #include "utils.h" +#include #include #include #include diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index f17699e90..47241aad1 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include "clang_tu.hh" #include "hierarchy.hh" #include "message_handler.h" #include "pipeline.hh" diff --git a/src/project.cc b/src/project.cc index 534d08fa2..c2c44b0cf 100644 --- a/src/project.cc +++ b/src/project.cc @@ -15,7 +15,6 @@ limitations under the License. #include "project.h" -#include "clang_utils.h" #include "filesystem.hh" #include "language.h" #include "log.hh" From ce68028caf9d358304863bab10ffd876bc7e5b04 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 16:15:10 -0700 Subject: [PATCH 233/378] Add GetAdjustedDecl to adjust Decl's that are missed by clangIndex --- index_tests/multi_file/impl.cc | 4 +- index_tests/multi_file/static.cc | 4 +- .../outline/static_function_in_type.cc | 4 +- .../func_specialized_template_param.cc | 17 +- .../templates/specialized_func_definition.cc | 4 +- ...ype_usage_as_template_parameter_complex.cc | 32 +--- .../type_usage_typedef_and_using_template.cc | 38 +---- src/indexer.cc | 154 +++++++++--------- 8 files changed, 95 insertions(+), 162 deletions(-) diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 1ef51a205..dc754b8cb 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -215,8 +215,8 @@ OUTPUT: impl.cc "callees": ["4:3-4:7|11650481237659640387|3|16420"] }, { "usr": 11650481237659640387, - "detailed_name": "template<> void Foo1()", - "qual_name_offset": 16, + "detailed_name": "void Foo1()", + "qual_name_offset": 5, "short_name": "Foo1", "kind": 12, "storage": 0, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 7f8d6c72b..50096fb2e 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -50,8 +50,8 @@ OUTPUT: static.cc "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, - "detailed_name": "void Buffer::CreateSharedBuffer()", - "qual_name_offset": 5, + "detailed_name": "static void Buffer::CreateSharedBuffer()", + "qual_name_offset": 12, "short_name": "CreateSharedBuffer", "kind": 254, "storage": 0, diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 7bf971e6e..c29aae072 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -84,8 +84,8 @@ OUTPUT: static_function_in_type.cc "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "void Foo::Register(ns::Manager *m)", - "qual_name_offset": 5, + "detailed_name": "static void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 12, "short_name": "Register", "kind": 254, "storage": 0, diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 322228113..af88d365a 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -29,21 +29,6 @@ void Foo::Bar(Template&) {} "callees": [] }], "usr2type": [{ - "usr": 2100211316767379401, - "detailed_name": "template<> class Template", - "qual_name_offset": 17, - "short_name": "Template", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] - }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, @@ -76,7 +61,7 @@ void Foo::Bar(Template&) {} "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 17dfb7836..1397ba801 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -24,8 +24,8 @@ void Template::Foo() {} "skipped_ranges": [], "usr2func": [{ "usr": 6995843774014807426, - "detailed_name": "template <> void Template::Foo()", - "qual_name_offset": 31, + "detailed_name": "void Template::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 6, "storage": 0, diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index a49ccb840..3ed6d40dc 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -159,21 +159,6 @@ unique_ptr* Foo::foo() { return nullptr; } "vars": [], "instances": [], "uses": ["15:30-15:32|0|1|4|-1", "33:23-33:25|0|1|4|-1", "33:63-33:65|0|1|4|-1", "54:25-54:27|18320186404467436976|3|4|-1", "65:14-65:16|15041163540773201510|2|4|-1", "79:12-79:14|0|1|4|-1"] - }, { - "usr": 7147635971744144194, - "detailed_name": "template<> class unique_ptr", - "qual_name_offset": 17, - "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["15:19-15:29|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", @@ -203,7 +188,7 @@ unique_ptr* Foo::foo() { return nullptr; } "funcs": [], "vars": [], "instances": [2933643612409209903, 500112618220246], - "uses": [] + "uses": ["15:8-15:18|0|1|4|-1", "15:19-15:29|0|1|4|-1", "33:1-33:11|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", @@ -221,21 +206,6 @@ unique_ptr* Foo::foo() { return nullptr; } "vars": [], "instances": [], "uses": ["79:21-79:24|0|1|4|-1"] - }, { - "usr": 18153735331422331128, - "detailed_name": "template<> class unique_ptr, S2>", - "qual_name_offset": 17, - "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"] }], "usr2var": [{ "usr": 500112618220246, diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index e70435575..3c742067b 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -19,7 +19,7 @@ typedef Foo Foo2; "declarations": [], "spell": "4:7-4:11|0|1|2|-1", "extent": "4:1-4:22|0|1|0|-1", - "alias_of": 5123806965838456033, + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], @@ -27,43 +27,13 @@ typedef Foo Foo2; "vars": [], "instances": [], "uses": ["5:13-5:17|0|1|4|-1"] - }, { - "usr": 5123806965838456033, - "detailed_name": "template<> struct Foo", - "qual_name_offset": 18, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["4:14-4:17|0|1|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] - }, { - "usr": 14491685842684954828, - "detailed_name": "template<> struct Foo>", - "qual_name_offset": 18, - "short_name": "Foo", "kind": 5, - "declarations": [], + "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], "alias_of": 0, "bases": [], "derived": [], @@ -71,7 +41,7 @@ typedef Foo Foo2; "funcs": [], "vars": [], "instances": [], - "uses": ["5:9-5:12|0|1|4|-1"] + "uses": ["4:14-4:17|0|1|4|-1", "5:9-5:12|0|1|4|-1"] }, { "usr": 15933698173231330933, "detailed_name": "typedef Foo Foo2", @@ -81,7 +51,7 @@ typedef Foo Foo2; "declarations": [], "spell": "5:19-5:23|0|1|2|-1", "extent": "5:1-5:23|0|1|0|-1", - "alias_of": 14491685842684954828, + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], diff --git a/src/indexer.cc b/src/indexer.cc index 6383c3758..14c1905aa 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -296,6 +296,35 @@ const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { return D; } +const Decl *GetAdjustedDecl(const Decl *D) { + while (D) { + if (auto *R = dyn_cast(D)) { + if (auto *S = dyn_cast(R)) { + if (!S->getTypeAsWritten()) { + llvm::PointerUnion + Result = S->getSpecializedTemplateOrPartial(); + if (Result.is()) + D = Result.get(); + else + D = Result.get(); + continue; + } + } else if (auto *D1 = R->getInstantiatedFromMemberClass()) { + D = D1; + continue; + } + } else if (auto *ED = dyn_cast(D)) { + if (auto *D1 = ED->getInstantiatedFromMemberEnum()) { + D = D1; + continue; + } + } + break; + } + return D; +} + bool ValidateRecord(const RecordDecl *RD) { for (const auto *I : RD->fields()) { QualType FQT = I->getType(); @@ -636,11 +665,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; } + // spell, extent, comments use OrigD while most others use adjusted |D|. const Decl *OrigD = ASTNode.OrigD; const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *LexDC = ASTNode.ContainerDC; Role role = static_cast(Roles); - db->language = LanguageId((int)db->language | (int)GetDeclLanguage(OrigD)); + db->language = LanguageId((int)db->language | (int)GetDeclLanguage(D)); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); @@ -650,11 +680,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexType *type = nullptr; IndexVar *var = nullptr; SymbolKind kind = GetSymbolKind(D); - IndexParam::DeclInfo *info; - Usr usr = GetUsr(D, &info); if (is_def) - switch (OrigD->getKind()) { + switch (D->getKind()) { case Decl::CXXConversion: // *operator* int => *operator int* case Decl::CXXDestructor: // *~*A => *~A* case Decl::CXXMethod: // *operator*= => *operator=* @@ -669,6 +697,15 @@ class IndexDataConsumer : public index::IndexDataConsumer { default: break; } + else { + // e.g. typedef Foo gg; => Foo has an unadjusted `D` + const Decl *D1 = GetAdjustedDecl(D); + if (D1 && D1 != D) + D = D1; + } + + IndexParam::DeclInfo *info; + Usr usr = GetUsr(D, &info); auto do_def_decl = [&](auto *entity) { if (is_def) { @@ -708,7 +745,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); if (func->def.detailed_name[0] == '\0') - SetName(OrigD, info->short_name, info->qualified, func->def); + SetName(D, info->short_name, info->qualified, func->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -726,7 +763,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); if (type->def.detailed_name[0] == '\0' && info->short_name.size()) - SetName(OrigD, info->short_name, info->qualified, type->def); + SetName(D, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -739,7 +776,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); if (var->def.detailed_name[0] == '\0') - SetVarName(OrigD, info->short_name, info->qualified, var->def); + SetVarName(D, info->short_name, info->qualified, var->def); QualType T; if (auto *VD = dyn_cast(D)) T = VD->getType(); @@ -756,63 +793,44 @@ class IndexDataConsumer : public index::IndexDataConsumer { Usr usr1 = static_cast(BT->getKind()); var->def.type = usr1; db->ToType(usr1).instances.push_back(usr); - } else { - for (const Decl *D1 = GetTypeDecl(T); D1; ) { - if (auto *R1 = dyn_cast(D1)) { - if (auto *S1 = dyn_cast(D1)) { - if (!S1->getTypeAsWritten()) { - llvm::PointerUnion - Result = S1->getSpecializedTemplateOrPartial(); - if (Result.is()) - D1 = Result.get(); - else - D1 = Result.get(); - continue; - } - } else if (auto *D2 = R1->getInstantiatedFromMemberClass()) { - D1 = D2; - continue; - } - } else if (auto *TP1 = dyn_cast(D1)) { - // e.g. TemplateTypeParmDecl is not handled by - // handleDeclOccurence. - SourceRange R1 = D1->getSourceRange(); - if (SM.getFileID(R1.getBegin()) == LocFID) { - IndexParam::DeclInfo *info1; - Usr usr1 = GetUsr(D1, &info1); - IndexType &type1 = db->ToType(usr1); - SourceLocation L1 = D1->getLocation(); - type1.def.spell = - GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, - Role::Definition); - type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), - LexDC, Role::None); - type1.def.detailed_name = Intern(info1->short_name); - type1.def.short_name_size = int16_t(info1->short_name.size()); - type1.def.kind = lsSymbolKind::TypeParameter; - var->def.type = usr1; - type1.instances.push_back(usr); - break; - } + } else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) { + if (isa(D1)) { + // e.g. TemplateTypeParmDecl is not handled by + // handleDeclOccurence. + SourceRange R1 = D1->getSourceRange(); + if (SM.getFileID(R1.getBegin()) == LocFID) { + IndexParam::DeclInfo *info1; + Usr usr1 = GetUsr(D1, &info1); + IndexType &type1 = db->ToType(usr1); + SourceLocation L1 = D1->getLocation(); + type1.def.spell = + GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, + Role::Definition); + type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), + LexDC, Role::None); + type1.def.detailed_name = Intern(info1->short_name); + type1.def.short_name_size = int16_t(info1->short_name.size()); + type1.def.kind = lsSymbolKind::TypeParameter; + var->def.type = usr1; + type1.instances.push_back(usr); + break; } - - IndexParam::DeclInfo *info1; - Usr usr1 = GetUsr(D1, &info1); - var->def.type = usr1; - db->ToType(usr1).instances.push_back(usr); - break; } + + IndexParam::DeclInfo *info1; + Usr usr1 = GetUsr(D1, &info1); + var->def.type = usr1; + db->ToType(usr1).instances.push_back(usr); } } } else if (!var->def.spell && var->declarations.empty()) { // e.g. lambda parameter - SourceLocation L = OrigD->getLocation(); + SourceLocation L = D->getLocation(); if (SM.getFileID(L) == LocFID) { var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}), SemDC, Role::Definition); var->def.extent = - GetUse(db, lid, FromTokenRange(SM, Lang, OrigD->getSourceRange()), + GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()), LexDC, Role::None); } } @@ -822,8 +840,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { switch (D->getKind()) { case Decl::Namespace: type->def.kind = lsSymbolKind::Namespace; - if (OrigD->isFirstDecl()) { - auto *ND = cast(OrigD); + if (D->isFirstDecl()) { + auto *ND = cast(D); auto *ND1 = cast(ND->getParent()); if (isa(ND1)) { Usr usr1 = GetUsr(ND1); @@ -874,29 +892,19 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::CXXRecord: if (is_def) { - auto *RD = dyn_cast(OrigD); - if (RD && RD->hasDefinition()) { - for (const CXXBaseSpecifier &Base : RD->bases()) { - QualType T = Base.getType(); - const NamedDecl *BaseD = nullptr; - if (auto *TDT = T->getAs()) { - BaseD = TDT->getDecl(); - } else if (auto *TST = T->getAs()) { - BaseD = TST->getTemplateName().getAsTemplateDecl(); - } else if (auto *RT = T->getAs()) { - BaseD = RT->getDecl(); - } - if (BaseD) { + auto *RD = dyn_cast(D); + if (RD && RD->hasDefinition()) + for (const CXXBaseSpecifier &Base : RD->bases()) + if (const Decl *BaseD = + GetAdjustedDecl(GetTypeDecl(Base.getType()))) { Usr usr1 = GetUsr(BaseD); type->def.bases.push_back(usr1); db->ToType(usr1).derived.push_back(usr); } - } - } } [[fallthrough]]; case Decl::Record: - if (auto *RD = dyn_cast(OrigD)) { + if (auto *RD = dyn_cast(D)) { // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; @@ -979,7 +987,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (auto *TD = dyn_cast(D)) { bool specialization = false; QualType T = TD->getUnderlyingType(); - if (const Decl *D1 = GetTypeDecl(T, &specialization)) { + if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T, &specialization))) { Usr usr1 = GetUsr(D1); IndexType &type1 = db->ToType(usr1); type->def.alias_of = usr1; From eb644bb78ee38cbb2ec5032090743cf77a292760 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 18:45:41 -0700 Subject: [PATCH 234/378] Add index.initial{Blacklist,Whitelist} index.{blacklist,whitelist}: disable indexes thoroughly index.initial{Blacklist,Whitelist}: disable initial loading. will still be indexed after opening --- src/config.h | 9 ++++++++- src/project.cc | 31 ++++++++++++++----------------- src/project.h | 4 ---- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/config.h b/src/config.h index 04d10c062..2219a8a1c 100644 --- a/src/config.h +++ b/src/config.h @@ -204,6 +204,12 @@ struct Config { // If false, the indexer will be disabled. bool enabled = true; + // By default, all project entries will be indexed on initialization. Use + // these two options to exclude some. They can still be indexed after you + // open them. + std::vector initialBlacklist; + std::vector initialWhitelist; + // If not 0, a file will be indexed in each tranlation unit that includes it. int multiVersion = 0; @@ -259,7 +265,8 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) -MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, +MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, + initialBlacklist, initialWhitelist, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); diff --git a/src/project.cc b/src/project.cc index c2c44b0cf..708025382 100644 --- a/src/project.cc +++ b/src/project.cc @@ -433,28 +433,25 @@ Project::FindCompilationEntryForFile(const std::string &filename) { return result; } -void Project::ForAllFilteredFiles( - std::function action) { - GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); +void Project::Index(WorkingFiles *wfiles, lsRequestId id) { + auto &gi = g_config->index; + GroupMatch match(gi.whitelist, gi.blacklist), + match_i(gi.initialWhitelist, gi.initialBlacklist); for (int i = 0; i < entries.size(); ++i) { const Project::Entry &entry = entries[i]; - std::string failure_reason; - if (matcher.IsMatch(entry.filename, &failure_reason)) - action(i, entries[i]); - else { - LOG_V(1) << "[" << i + 1 << "/" << entries.size() << "]: Failed " - << failure_reason << "; skipping " << entry.filename; + std::string reason; + if (match.IsMatch(entry.filename, &reason) && + match_i.IsMatch(entry.filename, &reason)) { + bool interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; + pipeline::Index( + entry.filename, entry.args, + interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); + } else { + LOG_V(1) << "[" << i << "/" << entries.size() << "]: " << reason + << "; skip " << entry.filename; } } -} -void Project::Index(WorkingFiles *wfiles, lsRequestId id) { - ForAllFilteredFiles([&](int i, const Project::Entry &entry) { - bool interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - pipeline::Index(entry.filename, entry.args, - interactive ? IndexMode::Normal : IndexMode::NonInteractive, - id); - }); pipeline::loaded_ts = pipeline::tick; // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. diff --git a/src/project.h b/src/project.h index e5582a40a..125b2af03 100644 --- a/src/project.h +++ b/src/project.h @@ -67,9 +67,5 @@ struct Project { void SetArgsForFile(const std::vector &args, const std::string &path); - // Run |action| on every file in the project. - void - ForAllFilteredFiles(std::function action); - void Index(WorkingFiles *wfiles, lsRequestId id); }; From 0eb9428a321791a6eea2c078f9a52bb7f8fd7cc3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 23:02:19 -0700 Subject: [PATCH 235/378] Add index.trackDependency and improve pipeline --- src/config.h | 10 +++---- src/pipeline.cc | 72 ++++++++++++++++++++++++++++--------------------- src/pipeline.hh | 4 ++- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/config.h b/src/config.h index 2219a8a1c..4ff79a92e 100644 --- a/src/config.h +++ b/src/config.h @@ -222,13 +222,13 @@ struct Config { // May be too slow for big projects, so it is off by default. bool onChange = false; + // Number of indexer threads. If 0, 80% of cores are used. + int threads = 0; + // Whether to reparse a file if write times of its dependencies have // changed. The file will always be reparsed if its own write time changes. // 0: no, 1: only after initial load of project, 2: yes - int reparseForDependency = 2; - - // Number of indexer threads. If 0, 80% of cores are used. - int threads = 0; + int trackDependency = 2; std::vector whitelist; } index; @@ -268,7 +268,7 @@ MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, initialBlacklist, initialWhitelist, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, - reparseForDependency, threads, whitelist); + threads, trackDependency, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, diff --git a/src/pipeline.cc b/src/pipeline.cc index 4810c87c1..4fd303204 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -62,7 +62,8 @@ bool VFS::Stamp(const std::string &path, int64_t ts, int step) { namespace ccls::pipeline { -int64_t loaded_ts = 0, tick = 0; +std::atomic loaded_ts = ATOMIC_VAR_INIT(0); +int64_t tick = 0; namespace { @@ -199,7 +200,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (!mtime1) return true; if (vfs->Stamp(request.path, *mtime1, 0)) - reparse = 1; + reparse = 2; } if (g_config->index.onChange) { reparse = 2; @@ -208,45 +209,55 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (request.path != path_to_index) vfs->state[request.path].step = 0; } - if (!reparse) + bool track = g_config->index.trackDependency > 1 || + (g_config->index.trackDependency == 1 && request.ts < loaded_ts); + if (!reparse && !track) return true; - if (reparse < 2) do { - std::unique_lock lock( + if (reparse < 2) + do { + std::unique_lock lock( mutexes[std::hash()(path_to_index) % N_MUTEXES]); - prev = RawCacheLoad(path_to_index); - if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args, - std::nullopt)) - break; - bool update = false; - for (const auto &dep : prev->dependencies) - if (auto mtime1 = LastWriteTime(dep.first.val().str())) { - if (dep.second < *mtime1) - update = true; - } else { - update = true; - } - int forDep = g_config->index.reparseForDependency; - if (update && (forDep > 1 || (forDep == 1 && request.ts < loaded_ts))) - break; + prev = RawCacheLoad(path_to_index); + if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args, + std::nullopt)) + break; + if (track) + for (const auto &dep : prev->dependencies) { + if (auto mtime1 = LastWriteTime(dep.first.val().str())) { + if (dep.second < *mtime1) { + reparse = 2; + break; + } + } else { + reparse = 2; + break; + } + } + if (reparse == 0) + return true; + if (reparse == 2) + break; - if (reparse < 2) { + if (vfs->Loaded(path_to_index)) + return true; LOG_S(INFO) << "load cache for " << path_to_index; auto dependencies = prev->dependencies; - if (reparse) { - if (vfs->Loaded(path_to_index)) - return true; - IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); + IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); + on_indexed->PushBack(std::move(update), + request.mode != IndexMode::NonInteractive); + { std::lock_guard lock1(vfs->mutex); vfs->state[path_to_index].loaded = true; } lock.unlock(); + for (const auto &dep : dependencies) { std::string path = dep.first.val().str(); + if (!vfs->Stamp(path, dep.second, 1)) + continue; std::lock_guard lock1( - mutexes[std::hash()(path) % N_MUTEXES]); + mutexes[std::hash()(path) % N_MUTEXES]); prev = RawCacheLoad(path); if (!prev) continue; @@ -260,15 +271,14 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, } IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); + request.mode != IndexMode::NonInteractive); if (entry.id >= 0) { std::lock_guard lock2(project->mutex_); project->path_to_entry_index[path] = entry.id; } } return true; - } - } while (0); + } while (0); LOG_IF_S(INFO, loud) << "parse " << path_to_index; diff --git a/src/pipeline.hh b/src/pipeline.hh index 920053c8b..a232d513d 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -4,6 +4,7 @@ #include "method.h" #include "query.h" +#include #include #include #include @@ -38,7 +39,8 @@ enum class IndexMode { }; namespace pipeline { -extern int64_t loaded_ts, tick; +extern std::atomic loaded_ts; +extern int64_t tick; void Init(); void LaunchStdin(); void LaunchStdout(); From 41fcc0272c8c93fcbe52f24ef587e633a9dcc7e1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 24 Sep 2018 10:56:29 -0700 Subject: [PATCH 236/378] Simplify semantic highlighting; improve hover of auto && --- src/indexer.cc | 3 +- src/message_handler.cc | 51 ++++++++-------------------- src/message_handler.h | 16 ++------- src/messages/initialize.cc | 1 - src/messages/textDocument_didOpen.cc | 2 +- src/pipeline.cc | 23 ++++++------- 6 files changed, 31 insertions(+), 65 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 14c1905aa..9299b4aaa 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -524,7 +524,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { binding = true; } auto BT = GetBaseType(T, false); - if (!BT.isNull() && (binding || BT->getAs())) { + if (!BT.isNull() && + (binding || BT.getUnqualifiedType()->getAs())) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP = GetDefaultPolicy(); diff --git a/src/message_handler.cc b/src/message_handler.cc index aa2924a3d..e17219763 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -60,34 +60,6 @@ struct ScanLineEvent { }; } // namespace -int SemanticHighlight::GetStableId(SymbolKind kind, Usr usr) { - decltype(func2id) *map; - switch (kind) { - case SymbolKind::Func: - map = &func2id; - break; - case SymbolKind::Type: - map = &type2id; - break; - case SymbolKind::Var: - map = &var2id; - break; - case SymbolKind::File: - case SymbolKind::Invalid: - llvm_unreachable(""); - } - - auto it = map->try_emplace(usr, next_id); - if (it.second) - next_id++; - return it.first->second; -} - -void SemanticHighlight::Init() { - match_ = std::make_unique(g_config->highlight.whitelist, - g_config->highlight.blacklist); -} - MessageHandler::MessageHandler() { // Dynamically allocate |message_handlers|, otherwise there will be static // initialization order races. @@ -157,11 +129,12 @@ void EmitSkippedRanges(WorkingFile *working_file, pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out); } -void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, - WorkingFile *wfile, QueryFile *file) { +void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { + static GroupMatch match(g_config->highlight.whitelist, + g_config->highlight.blacklist); assert(file->def); if (wfile->buffer_content.size() > g_config->largeFileSize || - !highlight->match_->IsMatch(file->def->path)) + !match.IsMatch(file->def->path)) return; // Group symbols together. @@ -174,10 +147,12 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, lsSymbolKind parent_kind = lsSymbolKind::Unknown; lsSymbolKind kind = lsSymbolKind::Unknown; uint8_t storage = SC_None; + int idx; // This switch statement also filters out symbols that are not highlighted. switch (sym.kind) { case SymbolKind::Func: { - const QueryFunc &func = db->GetFunc(sym); + idx = db->func_usr[sym.usr]; + const QueryFunc &func = db->funcs[idx]; const QueryFunc::Def *def = func.AnyDef(); if (!def) continue; // applies to for loop @@ -218,8 +193,10 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, sym.range.end.column = start_col + concise_name.size(); break; } - case SymbolKind::Type: - for (auto &def : db->GetType(sym).def) { + case SymbolKind::Type: { + idx = db->type_usr[sym.usr]; + const QueryType &type = db->types[idx]; + for (auto &def : type.def) { kind = def.kind; detailed_name = def.detailed_name; if (def.spell) { @@ -228,8 +205,10 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, } } break; + } case SymbolKind::Var: { - const QueryVar &var = db->GetVar(sym); + idx = db->var_usr[sym.usr]; + const QueryVar &var = db->vars[idx]; for (auto &def : var.def) { kind = def.kind; storage = def.storage; @@ -258,7 +237,7 @@ void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, it->second.lsRanges.push_back(*loc); } else { Out_CclsPublishSemanticHighlighting::Symbol symbol; - symbol.stableId = highlight->GetStableId(sym.kind, sym.usr); + symbol.stableId = idx; symbol.parentKind = parent_kind; symbol.kind = kind; symbol.storage = storage; diff --git a/src/message_handler.h b/src/message_handler.h index 2e420dc38..38074f64d 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -36,17 +36,6 @@ struct DB; struct WorkingFile; struct WorkingFiles; -// Caches symbols for a single file for semantic highlighting to provide -// relatively stable ids. Only supports xxx files at a time. -struct SemanticHighlight { - llvm::DenseMap func2id, type2id, var2id; - uint32_t next_id = 0; - std::unique_ptr match_; - - void Init(); - int GetStableId(SymbolKind kind, Usr usr); -}; - struct Out_CclsPublishSemanticHighlighting : public lsOutMessage { struct Symbol { @@ -89,7 +78,6 @@ struct MessageHandler { DB *db = nullptr; Project *project = nullptr; VFS *vfs = nullptr; - SemanticHighlight *highlight = nullptr; WorkingFiles *working_files = nullptr; CompletionManager *clang_complete = nullptr; IncludeComplete *include_complete = nullptr; @@ -119,5 +107,5 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, void EmitSkippedRanges(WorkingFile *working_file, const std::vector &skipped_ranges); -void EmitSemanticHighlighting(DB *db, SemanticHighlight *highlight, - WorkingFile *working_file, QueryFile *file); +void EmitSemanticHighlighting(DB *db, WorkingFile *working_file, + QueryFile *file); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index d8039aeeb..182050383 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -487,7 +487,6 @@ struct Handler_Initialize : BaseMessageHandler { } idx::Init(); - highlight->Init(); // Open up / load the project. project->Load(project_path); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index ec1b925a6..4c9acd8a2 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -59,7 +59,7 @@ struct Handler_TextDocumentDidOpen FindFileOrFail(db, project, std::nullopt, path, &file); if (file && file->def) { EmitSkippedRanges(working_file, file->def->skipped_ranges); - EmitSemanticHighlighting(db, highlight, working_file, file); + EmitSemanticHighlighting(db, working_file, file); } include_complete->AddFile(working_file->filename); diff --git a/src/pipeline.cc b/src/pipeline.cc index 4fd303204..591013245 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -368,8 +368,7 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, indexer_waiter->Wait(index_request); } -void Main_OnIndexed(DB *db, SemanticHighlight *highlight, - WorkingFiles *working_files, IndexUpdate *update) { +void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { if (update->refresh) { LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; @@ -379,7 +378,7 @@ void Main_OnIndexed(DB *db, SemanticHighlight *highlight, if (db->name2file_id.find(filename) == db->name2file_id.end()) continue; QueryFile *file = &db->files[db->name2file_id[filename]]; - EmitSemanticHighlighting(db, highlight, f.get(), file); + EmitSemanticHighlighting(db, f.get(), file); } return; } @@ -399,8 +398,7 @@ void Main_OnIndexed(DB *db, SemanticHighlight *highlight, wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content : def_u.second); EmitSkippedRanges(wfile, def_u.first.skipped_ranges); - EmitSemanticHighlighting(db, highlight, wfile, - &db->files[update->file_id]); + EmitSemanticHighlighting(db, wfile, &db->files[update->file_id]); } } } @@ -470,7 +468,6 @@ void LaunchStdout() { void MainLoop() { Project project; - SemanticHighlight highlight; WorkingFiles working_files; VFS vfs; @@ -502,13 +499,12 @@ void MainLoop() { handler->db = &db; handler->project = &project; handler->vfs = &vfs; - handler->highlight = &highlight; handler->working_files = &working_files; handler->clang_complete = &clang_complete; handler->include_complete = &include_complete; } - bool last_indexed = false; + bool has_indexed = false; while (true) { std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); @@ -532,15 +528,18 @@ void MainLoop() { break; did_work = true; indexed = true; - Main_OnIndexed(&db, &highlight, &working_files, &*update); + Main_OnIndexed(&db, &working_files, &*update); } - if (!did_work) { - if (last_indexed) + if (did_work) + has_indexed |= indexed; + else { + if (has_indexed) { FreeUnusedMemory(); + has_indexed = false; + } main_waiter->Wait(on_indexed, on_request); } - last_indexed = indexed; } } From d6ad864f11e36752c47de6169f8fee4f5eef33ac Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Thu, 27 Sep 2018 08:47:03 +0800 Subject: [PATCH 237/378] Update threaded_queue.h (#82) https://en.cppreference.com/w/cpp/language/fold --- src/threaded_queue.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/threaded_queue.h b/src/threaded_queue.h index c14307a30..d72f06d7b 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -48,8 +48,7 @@ template struct MultiQueueLock { } template void unlock_impl(std::index_sequence) { - (void)std::initializer_list{ - (std::get(tuple_)->mutex_.unlock(), 0)...}; + (std::get(tuple_)->mutex_.unlock(), ...); } std::tuple tuple_; From 05109b6fa460ecf7f596fdf4a641c18433d2f5fd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 27 Sep 2018 22:16:42 -0700 Subject: [PATCH 238/378] Merge textDocument_did{Change,Close,Open,Save}.cc --- CMakeLists.txt | 5 +- src/messages/textDocument_did.cc | 165 +++++++++++++++++++++++++ src/messages/textDocument_didChange.cc | 50 -------- src/messages/textDocument_didClose.cc | 53 -------- src/messages/textDocument_didOpen.cc | 80 ------------ src/messages/textDocument_didSave.cc | 52 -------- 6 files changed, 166 insertions(+), 239 deletions(-) create mode 100644 src/messages/textDocument_did.cc delete mode 100644 src/messages/textDocument_didChange.cc delete mode 100644 src/messages/textDocument_didClose.cc delete mode 100644 src/messages/textDocument_didOpen.cc delete mode 100644 src/messages/textDocument_didSave.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b447d764..fca0ff417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,10 +221,7 @@ target_sources(ccls PRIVATE src/messages/textDocument_codeLens.cc src/messages/textDocument_completion.cc src/messages/textDocument_definition.cc - src/messages/textDocument_didChange.cc - src/messages/textDocument_didClose.cc - src/messages/textDocument_didOpen.cc - src/messages/textDocument_didSave.cc + src/messages/textDocument_did.cc src/messages/textDocument_documentHighlight.cc src/messages/textDocument_documentSymbol.cc src/messages/textDocument_hover.cc diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc new file mode 100644 index 000000000..5a069ee2e --- /dev/null +++ b/src/messages/textDocument_did.cc @@ -0,0 +1,165 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "clang_complete.hh" +#include "include_complete.h" +#include "message_handler.h" +#include "pipeline.hh" +#include "project.h" +#include "working_files.h" +using namespace ccls; + +namespace { +MethodType didChange = "textDocument/didChange"; +MethodType didClose = "textDocument/didClose"; +MethodType didOpen = "textDocument/didOpen"; +MethodType didSave = "textDocument/didSave"; + +struct In_TextDocumentDidChange : public NotificationInMessage { + MethodType GetMethodType() const override { return didChange; } + lsTextDocumentDidChangeParams params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentDidChange, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidChange); + +struct Handler_TextDocumentDidChange + : BaseMessageHandler { + MethodType GetMethodType() const override { return didChange; } + + void Run(In_TextDocumentDidChange *request) override { + const auto ¶ms = request->params; + std::string path = params.textDocument.uri.GetPath(); + working_files->OnChange(params); + if (g_config->index.onChange) + pipeline::Index(path, {}, IndexMode::OnChange); + clang_complete->NotifyView(path); + if (g_config->diagnostics.onChange >= 0) + clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); + +struct In_TextDocumentDidClose : public NotificationInMessage { + MethodType GetMethodType() const override { return didClose; } + struct Params { + lsTextDocumentIdentifier textDocument; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); +MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidClose); + +struct Handler_TextDocumentDidClose + : BaseMessageHandler { + MethodType GetMethodType() const override { return didClose; } + + void Run(In_TextDocumentDidClose *request) override { + std::string path = request->params.textDocument.uri.GetPath(); + + // Clear any diagnostics for the file. + Out_TextDocumentPublishDiagnostics out; + out.params.uri = request->params.textDocument.uri; + pipeline::WriteStdout(didClose, out); + + // Remove internal state. + working_files->OnClose(request->params.textDocument); + clang_complete->OnClose(path); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); + +struct In_TextDocumentDidOpen : public NotificationInMessage { + MethodType GetMethodType() const override { return didOpen; } + + struct Params { + lsTextDocumentItem textDocument; + + // ccls extension + // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project + // entry (e.g. loaded from compile_commands.json or .ccls). + std::vector args; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen::Params, textDocument, args); +MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidOpen); + +struct Handler_TextDocumentDidOpen + : BaseMessageHandler { + MethodType GetMethodType() const override { return didOpen; } + + void Run(In_TextDocumentDidOpen *request) override { + // NOTE: This function blocks code lens. If it starts taking a long time + // we will need to find a way to unblock the code lens request. + const auto ¶ms = request->params; + const std::string &path = params.textDocument.uri.GetPath(); + + WorkingFile *working_file = working_files->OnOpen(params.textDocument); + if (std::optional cached_file_contents = + pipeline::LoadIndexedContent(path)) + working_file->SetIndexContent(*cached_file_contents); + + QueryFile *file = nullptr; + FindFileOrFail(db, project, std::nullopt, path, &file); + if (file && file->def) { + EmitSkippedRanges(working_file, file->def->skipped_ranges); + EmitSemanticHighlighting(db, working_file, file); + } + + include_complete->AddFile(working_file->filename); + std::vector args; + for (const std::string &arg : params.args) + args.push_back(Intern(arg)); + if (args.size()) + project->SetArgsForFile(args, path); + + // Submit new index request if it is not a header file. + if (SourceFileLanguage(path) != LanguageId::Unknown) + pipeline::Index(path, args, IndexMode::Normal); + + clang_complete->NotifyView(path); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); + +struct In_TextDocumentDidSave : public NotificationInMessage { + MethodType GetMethodType() const override { return didSave; } + + struct Params { + // The document that was saved. + lsTextDocumentIdentifier textDocument; + + // Optional the content when saved. Depends on the includeText value + // when the save notifcation was requested. + // std::string text; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentDidSave::Params, textDocument); +MAKE_REFLECT_STRUCT(In_TextDocumentDidSave, params); +REGISTER_IN_MESSAGE(In_TextDocumentDidSave); + +struct Handler_TextDocumentDidSave + : BaseMessageHandler { + MethodType GetMethodType() const override { return didSave; } + + void Run(In_TextDocumentDidSave *request) override { + const auto ¶ms = request->params; + const std::string &path = params.textDocument.uri.GetPath(); + pipeline::Index(path, {}, IndexMode::Normal); + clang_complete->NotifySave(path); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); +} // namespace diff --git a/src/messages/textDocument_didChange.cc b/src/messages/textDocument_didChange.cc deleted file mode 100644 index 76bdef49c..000000000 --- a/src/messages/textDocument_didChange.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "message_handler.h" -#include "pipeline.hh" -#include "project.h" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/didChange"; - -struct In_TextDocumentDidChange : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentDidChangeParams params; -}; - -MAKE_REFLECT_STRUCT(In_TextDocumentDidChange, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidChange); - -struct Handler_TextDocumentDidChange - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentDidChange *request) override { - const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); - working_files->OnChange(params); - if (g_config->index.onChange) - pipeline::Index(path, {}, IndexMode::OnChange); - clang_complete->NotifyView(path); - if (g_config->diagnostics.onChange >= 0) - clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); -} // namespace diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc deleted file mode 100644 index a7344e5de..000000000 --- a/src/messages/textDocument_didClose.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "message_handler.h" -#include "pipeline.hh" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/didClose"; - -struct In_TextDocumentDidClose : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - lsTextDocumentIdentifier textDocument; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidClose); - -struct Handler_TextDocumentDidClose - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentDidClose *request) override { - std::string path = request->params.textDocument.uri.GetPath(); - - // Clear any diagnostics for the file. - Out_TextDocumentPublishDiagnostics out; - out.params.uri = request->params.textDocument.uri; - pipeline::WriteStdout(kMethodType, out); - - // Remove internal state. - working_files->OnClose(request->params.textDocument); - clang_complete->OnClose(path); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); -} // namespace diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc deleted file mode 100644 index 4c9acd8a2..000000000 --- a/src/messages/textDocument_didOpen.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "include_complete.h" -#include "message_handler.h" -#include "pipeline.hh" -#include "project.h" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/didOpen"; - -struct In_TextDocumentDidOpen : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - - struct Params { - lsTextDocumentItem textDocument; - - // ccls extension - // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project - // entry (e.g. loaded from compile_commands.json or .ccls). - std::vector args; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen::Params, textDocument, args); -MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidOpen); - -struct Handler_TextDocumentDidOpen - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentDidOpen *request) override { - // NOTE: This function blocks code lens. If it starts taking a long time - // we will need to find a way to unblock the code lens request. - const auto ¶ms = request->params; - const std::string &path = params.textDocument.uri.GetPath(); - - WorkingFile *working_file = working_files->OnOpen(params.textDocument); - if (std::optional cached_file_contents = - pipeline::LoadIndexedContent(path)) - working_file->SetIndexContent(*cached_file_contents); - - QueryFile *file = nullptr; - FindFileOrFail(db, project, std::nullopt, path, &file); - if (file && file->def) { - EmitSkippedRanges(working_file, file->def->skipped_ranges); - EmitSemanticHighlighting(db, working_file, file); - } - - include_complete->AddFile(working_file->filename); - std::vector args; - for (const std::string &arg : params.args) - args.push_back(Intern(arg)); - if (args.size()) - project->SetArgsForFile(args, path); - - // Submit new index request if it is not a header file. - if (SourceFileLanguage(path) != LanguageId::Unknown) - pipeline::Index(path, args, IndexMode::Normal); - - clang_complete->NotifyView(path); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); -} // namespace diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc deleted file mode 100644 index f00ecc11a..000000000 --- a/src/messages/textDocument_didSave.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "message_handler.h" -#include "pipeline.hh" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/didSave"; - -struct In_TextDocumentDidSave : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - - struct Params { - // The document that was saved. - lsTextDocumentIdentifier textDocument; - - // Optional the content when saved. Depends on the includeText value - // when the save notifcation was requested. - // std::string text; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidSave::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentDidSave, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidSave); - -struct Handler_TextDocumentDidSave - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentDidSave *request) override { - const auto ¶ms = request->params; - const std::string &path = params.textDocument.uri.GetPath(); - pipeline::Index(path, {}, IndexMode::Normal); - clang_complete->NotifySave(path); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); -} // namespace From a127ca9b0246210195a857cc790311c29d472d32 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 27 Sep 2018 22:19:26 -0700 Subject: [PATCH 239/378] Support textDocument/{formatting,onTypeFormatting,rangeFormatting} --- CMakeLists.txt | 1 + README.md | 3 +- cmake/FindClang.cmake | 10 ++ src/messages/initialize.cc | 11 +- src/messages/textDocument_formatting.cc | 204 ++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 src/messages/textDocument_formatting.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index fca0ff417..384c008f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,6 +222,7 @@ target_sources(ccls PRIVATE src/messages/textDocument_completion.cc src/messages/textDocument_definition.cc src/messages/textDocument_did.cc + src/messages/textDocument_formatting.cc src/messages/textDocument_documentHighlight.cc src/messages/textDocument_documentSymbol.cc src/messages/textDocument_hover.cc diff --git a/README.md b/README.md index e3349def2..2a0c70fa5 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery), * code completion (with both signature help and snippets) * [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDcument_references.cc), and other cross references * cross reference extensions: `$ccls/call` `$ccls/inheritance` `$ccls/member` `$ccls/vars` ... + * formatting * hierarchies: [call (caller/callee) hierarchy](src/messages/ccls_call.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance.cc), [member hierarchy](src/messages/ccls_member.cc) * [symbol rename](src/messages/textDocument_rename.cc) * [document symbols](src/messages/textDocument_documentSymbol.cc) and approximate search of [workspace symbol](src/messages/workspace_symbol.cc) @@ -22,7 +23,7 @@ Saving files will incrementally update the index. Compared with cquery, it makes use of C++17 features, has less third-party dependencies and slimmed-down code base. It leverages Clang C++ API as [clangd](https://clang.llvm.org/extra/clangd.html) does, which provides better support for code completion and diagnostics. -Refactoring and formatting are non-goals as they can be provided by clang-format, clang-include-fixer and other Clang based tools. +Refactoring is a non-goal as it can be provided by clang-include-fixer and other Clang based tools. The comparison with cquery as noted on 2018-07-15: diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index e4286d51f..e56e25dd9 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -69,7 +69,17 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) _Clang_find_library(Clang_LIBRARY clangIndex) +_Clang_find_add_library(clangFormat) _Clang_find_add_library(clangTooling) + +# TODO Remove after dropping clang 6 +_Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) +if (clangToolingInclusions_LIBRARY) + list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) +endif() + +_Clang_find_add_library(clangToolingCore) +_Clang_find_add_library(clangRewrite) _Clang_find_add_library(clangFrontend) _Clang_find_add_library(clangParse) _Clang_find_add_library(clangSerialization) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 182050383..7d9ea978b 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -66,7 +66,7 @@ MAKE_REFLECT_STRUCT(lsCompletionOptions, resolveProvider, triggerCharacters); // Format document on type options struct lsDocumentOnTypeFormattingOptions { // A character on which formatting should be triggered, like `}`. - std::string firstTriggerCharacter; + std::string firstTriggerCharacter = "}"; // More trigger characters. std::vector moreTriggerCharacter; @@ -77,7 +77,7 @@ MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter, // Document link options struct lsDocumentLinkOptions { // Document links have a resolve provider as well. - bool resolveProvider = true; + bool resolveProvider = false; }; MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider); @@ -170,12 +170,11 @@ struct lsServerCapabilities { // The server provides code lens. lsCodeLensOptions codeLensProvider; // The server provides document formatting. - bool documentFormattingProvider = false; + bool documentFormattingProvider = true; // The server provides document range formatting. - bool documentRangeFormattingProvider = false; + bool documentRangeFormattingProvider = true; // The server provides document formatting on typing. - std::optional - documentOnTypeFormattingProvider; + lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider; // The server provides rename support. bool renameProvider = true; // The server provides document link support. diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc new file mode 100644 index 000000000..1676a9b58 --- /dev/null +++ b/src/messages/textDocument_formatting.cc @@ -0,0 +1,204 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "message_handler.h" +#include "pipeline.hh" +#include "working_files.h" + +#include +#include + +using namespace ccls; +using namespace clang; + +namespace { +const MethodType formatting = "textDocument/formatting", + onTypeFormatting = "textDocument/onTypeFormatting", + rangeFormatting = "textDocument/rangeFormatting"; + +struct lsFormattingOptions { + // Size of a tab in spaces. + int tabSize; + // Prefer spaces over tabs. + bool insertSpaces; +}; +MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); + +struct Out_TextDocumentFormatting + : public lsOutMessage { + lsRequestId id; + std::vector result; +}; +MAKE_REFLECT_STRUCT(Out_TextDocumentFormatting, jsonrpc, id, result); + +llvm::Expected +FormatCode(std::string_view code, std::string_view file, tooling::Range Range) { + StringRef Code(code.data(), code.size()), File(file.data(), file.size()); + auto Style = format::getStyle("file", File, "LLVM", Code, nullptr); + if (!Style) + return Style.takeError(); + tooling::Replacements IncludeReplaces = + format::sortIncludes(*Style, Code, {Range}, File); + auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces); + if (!Changed) + return Changed.takeError(); + return IncludeReplaces.merge(format::reformat( + *Style, *Changed, + tooling::calculateRangesAfterReplacements(IncludeReplaces, {Range}), + File)); +} + +std::vector +ReplacementsToEdits(std::string_view code, const tooling::Replacements &Repls) { + std::vector ret; + int i = 0, line = 0, col = 0; + auto move = [&](int p) { + for (; i < p; i++) + if (code[i] == '\n') + line++, col = 0; + else { + if ((uint8_t)code[i] >= 128) { + while (128 <= (uint8_t)code[++i] && (uint8_t)code[i] < 192) + ; + i--; + } + col++; + } + }; + for (const auto &R : Repls) { + move(R.getOffset()); + int l = line, c = col; + move(R.getOffset() + R.getLength()); + ret.push_back({{{l, c}, {line, col}}, R.getReplacementText().str()}); + } + return ret; +} + +void Format(WorkingFile *wfile, tooling::Range range, lsRequestId id) { + std::string_view code = wfile->buffer_content; + auto ReplsOrErr = + FormatCode(code, wfile->filename, range); + if (ReplsOrErr) { + Out_TextDocumentFormatting out; + out.id = id; + out.result = ReplacementsToEdits(code, *ReplsOrErr); + pipeline::WriteStdout(formatting, out); + } else { + Out_Error err; + err.id = id; + err.error.code = lsErrorCodes::UnknownErrorCode; + err.error.message = llvm::toString(ReplsOrErr.takeError()); + pipeline::WriteStdout(kMethodType_Unknown, err); + } +} + +struct In_TextDocumentFormatting : public RequestInMessage { + MethodType GetMethodType() const override { return formatting; } + struct Params { + lsTextDocumentIdentifier textDocument; + lsFormattingOptions options; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentFormatting::Params, textDocument, options); +MAKE_REFLECT_STRUCT(In_TextDocumentFormatting, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentFormatting); + +struct Handler_TextDocumentFormatting + : BaseMessageHandler { + MethodType GetMethodType() const override { return formatting; } + void Run(In_TextDocumentFormatting *request) override { + auto ¶ms = request->params; + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + params.textDocument.uri.GetPath(), &file)) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + Format(wfile, {0, (unsigned)wfile->buffer_content.size()}, request->id); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); + +struct In_TextDocumentOnTypeFormatting : public RequestInMessage { + MethodType GetMethodType() const override { return onTypeFormatting; } + struct Params { + lsTextDocumentIdentifier textDocument; + lsPosition position; + std::string ch; + lsFormattingOptions options; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentOnTypeFormatting::Params, textDocument, + position, ch, options); +MAKE_REFLECT_STRUCT(In_TextDocumentOnTypeFormatting, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentOnTypeFormatting); + +struct Handler_TextDocumentOnTypeFormatting + : BaseMessageHandler { + MethodType GetMethodType() const override { return onTypeFormatting; } + void Run(In_TextDocumentOnTypeFormatting *request) override { + auto ¶ms = request->params; + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + params.textDocument.uri.GetPath(), &file)) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::string_view code = wfile->buffer_content; + int pos = GetOffsetForPosition(params.position, code); + auto lbrace = code.find_last_of('{', pos); + if (lbrace == std::string::npos) + lbrace = pos; + Format(wfile, {(unsigned)lbrace, unsigned(pos - lbrace)}, request->id); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentOnTypeFormatting); + +struct In_TextDocumentRangeFormatting : public RequestInMessage { + MethodType GetMethodType() const override { return rangeFormatting; } + struct Params { + lsTextDocumentIdentifier textDocument; + lsRange range; + lsFormattingOptions options; + } params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting::Params, textDocument, range, + options); +MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentRangeFormatting); + +struct Handler_TextDocumentRangeFormatting + : BaseMessageHandler { + MethodType GetMethodType() const override { return rangeFormatting; } + + void Run(In_TextDocumentRangeFormatting *request) override { + auto ¶ms = request->params; + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + params.textDocument.uri.GetPath(), &file)) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::string_view code = wfile->buffer_content; + int begin = GetOffsetForPosition(params.range.start, code), + end = GetOffsetForPosition(params.range.end, code); + Format(wfile, {(unsigned)begin, unsigned(end - begin)}, request->id); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); +} // namespace From d4871207ed44c8e5edf0961ae7736c24075486ba Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 28 Sep 2018 13:41:50 -0700 Subject: [PATCH 240/378] Construct SourceManager with UserFilesAreVolatile Prettify pipeline --- src/clang_complete.cc | 6 ++++++ src/pipeline.cc | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index d5efae384..6a785470d 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -202,6 +202,12 @@ std::unique_ptr BuildCompilerInstance( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) return nullptr; + // Construct SourceManager with UserFilesAreVolatile: true because otherwise + // RequiresNullTerminator: true may cause out-of-bounds read when a file is + // mmap'ed but is saved concurrently. + Clang->createFileManager(); + Clang->setSourceManager(new SourceManager(Clang->getDiagnostics(), + Clang->getFileManager(), true)); return Clang; } diff --git a/src/pipeline.cc b/src/pipeline.cc index 591013245..ed01feeb1 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -162,10 +162,14 @@ std::unique_ptr RawCacheLoad(const std::string &path) { IndexFile::kMajorVersion); } -bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, - Project *project, VFS *vfs, const GroupMatch &matcher) { +std::mutex &GetFileMutex(const std::string &path) { const int N_MUTEXES = 256; static std::mutex mutexes[N_MUTEXES]; + return mutexes[std::hash()(path) % N_MUTEXES]; +} + +bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, + Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -216,8 +220,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (reparse < 2) do { - std::unique_lock lock( - mutexes[std::hash()(path_to_index) % N_MUTEXES]); + std::unique_lock lock(GetFileMutex(path_to_index)); prev = RawCacheLoad(path_to_index); if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args, std::nullopt)) @@ -256,8 +259,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, std::string path = dep.first.val().str(); if (!vfs->Stamp(path, dep.second, 1)) continue; - std::lock_guard lock1( - mutexes[std::hash()(path) % N_MUTEXES]); + std::lock_guard lock1(GetFileMutex(path)); prev = RawCacheLoad(path); if (!prev) continue; @@ -313,7 +315,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev << ")"; { - std::lock_guard lock(mutexes[std::hash()(path) % N_MUTEXES]); + std::lock_guard lock(GetFileMutex(path)); if (vfs->Loaded(path)) prev = RawCacheLoad(path); else From da704521b550606ad0cf3c8dcff8ad2efb54d02e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 29 Sep 2018 01:10:56 -0700 Subject: [PATCH 241/378] Revamp codeLens & codeAction b.ref: references of bases d.ref: references of derived when b.ref > 0, don't display 0 ref or x bases --- src/lsp.h | 39 +-- src/lsp_code_action.h | 36 --- src/messages/initialize.cc | 12 +- src/messages/textDocument_codeAction.cc | 27 +- src/messages/textDocument_codeLens.cc | 348 ++++++++++++----------- src/messages/workspace_executeCommand.cc | 58 ---- 6 files changed, 199 insertions(+), 321 deletions(-) delete mode 100644 src/lsp_code_action.h delete mode 100644 src/messages/workspace_executeCommand.cc diff --git a/src/lsp.h b/src/lsp.h index ef4ada8ca..6e4c5d226 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -91,6 +91,8 @@ struct lsResponseError { void Write(Writer &visitor); }; +constexpr std::string_view ccls_xref("ccls.xref"); + ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -205,43 +207,6 @@ struct lsLocationEx : lsLocation { }; MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role); -template struct lsCommand { - // Title of the command (ie, 'save') - std::string title; - // Actual command identifier. - std::string command; - // Arguments to run the command with. - // **NOTE** This must be serialized as an array. Use - // MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY. - T arguments; -}; -template -void Reflect(TVisitor &visitor, lsCommand &value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(title); - REFLECT_MEMBER(command); - REFLECT_MEMBER(arguments); - REFLECT_MEMBER_END(); -} - -template struct lsCodeLens { - // The range in which this code lens is valid. Should only span a single line. - lsRange range; - // The command this code lens represents. - std::optional> command; - // A data entry field that is preserved on a code lens item between - // a code lens and a code lens resolve request. - TData data; -}; -template -void Reflect(TVisitor &visitor, lsCodeLens &value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(range); - REFLECT_MEMBER(command); - REFLECT_MEMBER(data); - REFLECT_MEMBER_END(); -} - struct lsTextDocumentIdentifier { lsDocumentUri uri; }; diff --git a/src/lsp_code_action.h b/src/lsp_code_action.h deleted file mode 100644 index 15ed6be4f..000000000 --- a/src/lsp_code_action.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "lsp.h" - -// codeAction -struct CommandArgs { - lsDocumentUri textDocumentUri; - std::vector edits; -}; -MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(CommandArgs, textDocumentUri, edits); - -// codeLens -struct lsCodeLensUserData {}; -MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData); - -struct lsCodeLensCommandArguments { - lsDocumentUri uri; - lsPosition position; - std::vector locations; -}; -MAKE_REFLECT_STRUCT(lsCodeLensCommandArguments, uri, position, locations) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 7d9ea978b..443bf6a61 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -81,13 +81,6 @@ struct lsDocumentLinkOptions { }; MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider); -// Execute command options. -struct lsExecuteCommandOptions { - // The commands to be executed on the server - std::vector commands; -}; -MAKE_REFLECT_STRUCT(lsExecuteCommandOptions, commands); - // Save options. struct lsSaveOptions { // The client is supposed to include the content on save. @@ -180,8 +173,11 @@ struct lsServerCapabilities { // The server provides document link support. lsDocumentLinkOptions documentLinkProvider; // The server provides execute command support. - lsExecuteCommandOptions executeCommandProvider; + struct ExecuteCommandOptions { + std::vector commands{std::string(ccls_xref)}; + } executeCommandProvider; }; +MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands); MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, completionProvider, signatureHelpProvider, definitionProvider, implementationProvider, diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc index 9ee4e5e11..ac5564b3d 100644 --- a/src/messages/textDocument_codeAction.cc +++ b/src/messages/textDocument_codeAction.cc @@ -18,12 +18,6 @@ limitations under the License. #include "working_files.h" using namespace ccls; -struct CommandArgs { - lsDocumentUri textDocumentUri; - std::vector edits; -}; -MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(CommandArgs, textDocumentUri, edits); - namespace { MethodType kMethodType = "textDocument/codeAction"; @@ -53,10 +47,17 @@ MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument, MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); +struct lsCodeAction { + std::string title; + const char *kind = "quickfix"; + lsWorkspaceEdit edit; +}; +MAKE_REFLECT_STRUCT(lsCodeAction, title, kind, edit); + struct Out_TextDocumentCodeAction : public lsOutMessage { lsRequestId id; - std::vector> result; + std::vector result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result); @@ -76,12 +77,12 @@ struct Handler_TextDocumentCodeAction working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); for (lsDiagnostic &diag : diagnostics) if (diag.fixits_.size()) { - lsCommand command; - command.title = "FixIt: " + diag.message; - command.command = "ccls._applyFixIt"; - command.arguments.textDocumentUri = params.textDocument.uri; - command.arguments.edits = diag.fixits_; - out.result.push_back(command); + lsCodeAction &cmd = out.result.emplace_back(); + cmd.title = "FixIt: " + diag.message; + auto &edit = cmd.edit.documentChanges.emplace_back(); + edit.textDocument.uri = params.textDocument.uri; + edit.textDocument.version = wfile->version; + edit.edits = diag.fixits_; } pipeline::WriteStdout(kMethodType, out); } diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index ccf235fda..da64859ef 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -13,21 +13,64 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" -#include "lsp_code_action.h" #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; +#include "serializers/json.h" + +#include #include +using namespace ccls; + namespace { -MethodType kMethodType = "textDocument/codeLens"; +const MethodType codeLens = "textDocument/codeLens", + executeCommand = "workspace/executeCommand"; + +struct lsCommand { + std::string title; + std::string command; + std::vector arguments; +}; +MAKE_REFLECT_STRUCT(lsCommand, title, command, arguments); + +struct lsCodeLens { + lsRange range; + std::optional command; +}; +MAKE_REFLECT_STRUCT(lsCodeLens, range, command); + +struct Cmd_xref { + Usr usr; + SymbolKind kind; + std::string field; +}; +MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); + +struct Out_xref : public lsOutMessage { + lsRequestId id; + std::vector result; +}; +MAKE_REFLECT_STRUCT(Out_xref, jsonrpc, id, result); + +template +std::string ToString(T &v) { + rapidjson::StringBuffer output; + rapidjson::Writer writer(output); + JsonWriter json_writer(&writer); + Reflect(json_writer, v); + return output.GetString(); +} + +struct CommonCodeLensParams { + std::vector *result; + DB *db; + WorkingFile *wfile; +}; -using TCodeLens = lsCodeLens; struct In_TextDocumentCodeLens : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } + MethodType GetMethodType() const override { return codeLens; } struct Params { lsTextDocumentIdentifier textDocument; } params; @@ -39,179 +82,85 @@ REGISTER_IN_MESSAGE(In_TextDocumentCodeLens); struct Out_TextDocumentCodeLens : public lsOutMessage { lsRequestId id; - std::vector> - result; + std::vector result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result); -struct CommonCodeLensParams { - std::vector *result; - DB *db; - WorkingFiles *working_files; - WorkingFile *working_file; -}; - -Use OffsetStartColumn(Use use, int16_t offset) { - use.range.start.column += offset; - return use; -} - -void AddCodeLens(const char *singular, const char *plural, - CommonCodeLensParams *common, Use use, - const std::vector &uses, bool force_display) { - TCodeLens code_lens; - std::optional range = GetLsRange(common->working_file, use.range); - if (!range) - return; - if (use.file_id < 0) - return; - code_lens.range = *range; - code_lens.command = lsCommand(); - code_lens.command->command = "ccls.showReferences"; - code_lens.command->arguments.uri = GetLsDocumentUri(common->db, use.file_id); - code_lens.command->arguments.position = code_lens.range.start; - - // Add unique uses. - std::vector unique_uses; - for (Use use1 : uses) { - if (auto ls_loc = GetLsLocation(common->db, common->working_files, use1)) - unique_uses.push_back(*ls_loc); - } - code_lens.command->arguments.locations.assign(unique_uses.begin(), - unique_uses.end()); - - // User visible label - size_t num_usages = unique_uses.size(); - code_lens.command->title = std::to_string(num_usages) + " "; - if (num_usages == 1) - code_lens.command->title += singular; - else - code_lens.command->title += plural; - - if (force_display || unique_uses.size() > 0) - common->result->push_back(code_lens); -} - struct Handler_TextDocumentCodeLens : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } + MethodType GetMethodType() const override { return codeLens; } void Run(In_TextDocumentCodeLens *request) override { auto ¶ms = request->params; Out_TextDocumentCodeLens out; out.id = request->id; - std::string path = params.textDocument.uri.GetPath(); - clang_complete->NotifyView(path); QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) + if (!FindFileOrFail(db, project, request->id, path, &file)) return; - - CommonCodeLensParams common; - common.result = &out.result; - common.db = db; - common.working_files = working_files; - common.working_file = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + + auto Add = [&](const char *singular, Cmd_xref show, Use use, int num, + bool force_display = false) { + if (!num && !force_display) + return; + std::optional range = GetLsRange(wfile, use.range); + if (!range) + return; + lsCodeLens &code_lens = out.result.emplace_back(); + code_lens.range = *range; + code_lens.command = lsCommand(); + code_lens.command->command = std::string(ccls_xref); + bool plural = num > 1 && singular[strlen(singular) - 1] != 'd'; + code_lens.command->title = + llvm::formatv("{0} {1}{2}", num, singular, plural ? "s" : "").str(); + code_lens.command->arguments.push_back(ToString(show)); + }; + + auto ToSpell = [&](Use use) { + Maybe def = GetDefinitionSpell(db, use); + if (def && def->file_id == use.file_id && + def->range.start.line == use.range.start.line) + return *def; + return use; + }; std::unordered_set seen; for (auto [sym, refcnt] : file->outline2refcnt) { if (refcnt <= 0 || !seen.insert(sym.range).second) continue; - // NOTE: We OffsetColumn so that the code lens always show up in a - // predictable order. Otherwise, the client may randomize it. - Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id}; - + Use use = ToSpell({{sym.range, sym.usr, sym.kind, sym.role}, file->id}); switch (sym.kind) { - case SymbolKind::Type: { - QueryType &type = db->GetType(sym); - const QueryType::Def *def = type.AnyDef(); - if (!def || def->kind == lsSymbolKind::Namespace) - continue; - AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), - type.uses, true /*force_display*/); - AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1), - GetTypeDeclarations(db, type.derived), - false /*force_display*/); - AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetVarDeclarations(db, type.instances, true), - false /*force_display*/); - break; - } case SymbolKind::Func: { QueryFunc &func = db->GetFunc(sym); const QueryFunc::Def *def = func.AnyDef(); if (!def) continue; - - int16_t offset = 0; - - // For functions, the outline will report a location that is using the - // extent since that is better for outline. This tries to convert the - // extent location to the spelling location. - auto try_ensure_spelling = [&](Use use) { - Maybe def = GetDefinitionSpell(db, use); - if (!def || def->range.start.line != use.range.start.line) { - return use; - } - return *def; - }; - - std::vector base_callers = GetUsesForAllBases(db, func); - std::vector derived_callers = GetUsesForAllDerived(db, func); - if (base_callers.empty() && derived_callers.empty()) { - Use loc = try_ensure_spelling(use); - AddCodeLens("call", "calls", &common, - OffsetStartColumn(loc, offset++), func.uses, - true /*force_display*/); - } else { - Use loc = try_ensure_spelling(use); - AddCodeLens("direct call", "direct calls", &common, - OffsetStartColumn(loc, offset++), func.uses, - false /*force_display*/); - if (!base_callers.empty()) - AddCodeLens("base call", "base calls", &common, - OffsetStartColumn(loc, offset++), base_callers, - false /*force_display*/); - if (!derived_callers.empty()) - AddCodeLens("derived call", "derived calls", &common, - OffsetStartColumn(loc, offset++), derived_callers, - false /*force_display*/); - } - - AddCodeLens( - "derived", "derived", &common, OffsetStartColumn(use, offset++), - GetFuncDeclarations(db, func.derived), false /*force_display*/); - - // "Base" - if (def->bases.size() == 1) { - Maybe base_loc = GetDefinitionSpell( - db, SymbolIdx{def->bases[0], SymbolKind::Func}); - if (base_loc) { - std::optional ls_base = - GetLsLocation(db, working_files, *base_loc); - if (ls_base) { - std::optional range = - GetLsRange(common.working_file, sym.range); - if (range) { - TCodeLens code_lens; - code_lens.range = *range; - code_lens.range.start.character += offset++; - code_lens.command = lsCommand(); - code_lens.command->title = "Base"; - code_lens.command->command = "ccls.goto"; - code_lens.command->arguments.uri = ls_base->uri; - code_lens.command->arguments.position = ls_base->range.start; - out.result.push_back(code_lens); - } - } - } - } else { - AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1), - GetTypeDeclarations(db, def->bases), - false /*force_display*/); - } - + std::vector base_uses = GetUsesForAllBases(db, func); + std::vector derived_uses = GetUsesForAllDerived(db, func); + Add("ref", {sym.usr, SymbolKind::Func, "uses"}, use, func.uses.size(), + base_uses.empty()); + if (base_uses.size()) + Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, use, + base_uses.size()); + if (derived_uses.size()) + Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, use, + derived_uses.size()); + if (base_uses.empty()) + Add("base", {sym.usr, SymbolKind::Func, "bases"}, use, + def->bases.size()); + Add("derived", {sym.usr, SymbolKind::Func, "derived"}, use, + func.derived.size()); + break; + } + case SymbolKind::Type: { + QueryType &type = db->GetType(sym); + Add("ref", {sym.usr, SymbolKind::Type, "uses"}, use, type.uses.size(), + true); + Add("derived", {sym.usr, SymbolKind::Type, "derived"}, use, + type.derived.size()); + Add("var", {sym.usr, SymbolKind::Type, "instances"}, use, + type.instances.size()); break; } case SymbolKind::Var: { @@ -219,27 +168,88 @@ struct Handler_TextDocumentCodeLens const QueryVar::Def *def = var.AnyDef(); if (!def || (def->is_local() && !g_config->codeLens.localVariables)) continue; - - bool force_display = true; - // Do not show 0 refs on macro with no uses, as it is most likely - // a header guard. - if (def->kind == lsSymbolKind::Macro) - force_display = false; - - AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), var.uses, - force_display); + Add("ref", {sym.usr, SymbolKind::Var, "uses"}, use, var.uses.size(), + def->kind != lsSymbolKind::Macro); break; } case SymbolKind::File: - case SymbolKind::Invalid: { - assert(false && "unexpected"); - break; - } + case SymbolKind::Invalid: + llvm_unreachable(""); }; } - pipeline::WriteStdout(kMethodType, out); + pipeline::WriteStdout(codeLens, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); + +struct In_WorkspaceExecuteCommand : public RequestInMessage { + MethodType GetMethodType() const override { return executeCommand; } + lsCommand params; +}; +MAKE_REFLECT_STRUCT(In_WorkspaceExecuteCommand, id, params); +REGISTER_IN_MESSAGE(In_WorkspaceExecuteCommand); + +struct Handler_WorkspaceExecuteCommand + : BaseMessageHandler { + MethodType GetMethodType() const override { return executeCommand; } + void Run(In_WorkspaceExecuteCommand *request) override { + const auto ¶ms = request->params; + if (params.arguments.empty()) + return; + rapidjson::Document reader; + reader.Parse(params.arguments[0].c_str()); + JsonReader json_reader{&reader}; + if (params.command == ccls_xref) { + Cmd_xref cmd; + Reflect(json_reader, cmd); + Out_xref out; + out.id = request->id; + auto Map = [&](auto &&uses) { + for (auto &use : uses) + if (auto loc = GetLsLocation(db, working_files, use)) + out.result.push_back(std::move(*loc)); + }; + switch (cmd.kind) { + case SymbolKind::Func: { + QueryFunc &func = db->Func(cmd.usr); + if (cmd.field == "bases") { + if (auto *def = func.AnyDef()) + Map(GetFuncDeclarations(db, def->bases)); + } else if (cmd.field == "bases uses") { + Map(GetUsesForAllBases(db, func)); + } else if (cmd.field == "derived") { + Map(GetFuncDeclarations(db, func.derived)); + } else if (cmd.field == "derived uses") { + Map(GetUsesForAllDerived(db, func)); + } else if (cmd.field == "uses") { + Map(func.uses); + } + break; + } + case SymbolKind::Type: { + QueryType &type = db->Type(cmd.usr); + if (cmd.field == "derived") { + Map(GetTypeDeclarations(db, type.derived)); + } else if (cmd.field == "instances") { + Map(GetVarDeclarations(db, type.instances, 7)); + } else if (cmd.field == "uses") { + Map(type.uses); + } + break; + } + case SymbolKind::Var: { + QueryVar &var = db->Var(cmd.usr); + if (cmd.field == "uses") + Map(var.uses); + break; + } + default: + break; + } + pipeline::WriteStdout(executeCommand, out); + } + } +}; +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); } // namespace diff --git a/src/messages/workspace_executeCommand.cc b/src/messages/workspace_executeCommand.cc deleted file mode 100644 index a7fc764de..000000000 --- a/src/messages/workspace_executeCommand.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "lsp_code_action.h" -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "workspace/executeCommand"; - -struct In_WorkspaceExecuteCommand : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsCommand params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceExecuteCommand, id, params); -REGISTER_IN_MESSAGE(In_WorkspaceExecuteCommand); - -struct Out_WorkspaceExecuteCommand - : public lsOutMessage { - lsRequestId id; - std::variant, CommandArgs> result; -}; -MAKE_REFLECT_STRUCT(Out_WorkspaceExecuteCommand, jsonrpc, id, result); - -struct Handler_WorkspaceExecuteCommand - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceExecuteCommand *request) override { - const auto ¶ms = request->params; - Out_WorkspaceExecuteCommand out; - out.id = request->id; - if (params.command == "ccls._applyFixIt") { - } else if (params.command == "ccls._autoImplement") { - } else if (params.command == "ccls._insertInclude") { - } else if (params.command == "ccls.showReferences") { - out.result = params.arguments.locations; - } - - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); - -} // namespace From 79373ba48681b31085d412b2d8d8646be605110d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 29 Sep 2018 20:26:55 -0700 Subject: [PATCH 242/378] Rename some initialization options * Delete index.enabled which can be achieved with index.blacklist: ['.'] * Move completion.include* to completion.include.* * move largeFileSize to highlight.largeFileSize --- src/config.h | 71 ++++++++++++++++++++--------------------- src/include_complete.cc | 20 ++++++------ src/indexer.cc | 3 -- src/message_handler.cc | 2 +- src/pipeline.cc | 2 +- 5 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/config.h b/src/config.h index 4ff79a92e..8889f94bd 100644 --- a/src/config.h +++ b/src/config.h @@ -130,25 +130,27 @@ struct Config { // that implement their own filtering and sorting logic. bool filterAndSort = true; - // Regex patterns to match include completion candidates against. They - // receive the absolute file path. - // - // For example, to hide all files in a /CACHE/ folder, use ".*/CACHE/.*" - std::vector includeBlacklist; - - // Maximum path length to show in completion results. Paths longer than this - // will be elided with ".." put at the front. Set to 0 or a negative number - // to disable eliding. - 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" } - // - // This is significantly faster than using a regex. - std::vector includeSuffixWhitelist = {".h", ".hpp", ".hh", ".inc"}; - - std::vector includeWhitelist; + struct Include { + // Regex patterns to match include completion candidates against. They + // receive the absolute file path. + // + // For example, to hide all files in a /CACHE/ folder, use ".*/CACHE/.*" + std::vector blacklist; + + // Maximum path length to show in completion results. Paths longer than + // this will be elided with ".." put at the front. Set to 0 or a negative + // number to disable eliding. + int maxPathSize = 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" } + // + // This is significantly faster than using a regex. + std::vector suffixWhitelist = {".h", ".hpp", ".hh", ".inc"}; + + std::vector whitelist; + } include; } completion; struct Diagnostics { @@ -176,6 +178,9 @@ struct Config { // Semantic highlighting struct Highlight { + // Disable semantic highlighting for files larger than the size. + int64_t largeFileSize = 2 * 1024 * 1024; + // true: LSP line/character; false: position bool lsRanges = false; @@ -201,9 +206,6 @@ struct Config { // - https://github.com/autozimu/LanguageClient-neovim/issues/224 int comments = 2; - // If false, the indexer will be disabled. - bool enabled = true; - // By default, all project entries will be indexed on initialization. Use // these two options to exclude some. They can still be indexed after you // open them. @@ -227,15 +229,12 @@ struct Config { // Whether to reparse a file if write times of its dependencies have // changed. The file will always be reparsed if its own write time changes. - // 0: no, 1: only after initial load of project, 2: yes + // 0: no, 1: only during initial load of project, 2: yes int trackDependency = 2; std::vector whitelist; } index; - // Disable semantic highlighting for files larger than the size. - int64_t largeFileSize = 2 * 1024 * 1024; - struct WorkspaceSymbol { int caseSensitivity = 1; // Maximum workspace search results. @@ -258,24 +257,24 @@ MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, MAKE_REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, snippetSupport); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); +MAKE_REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, + suffixWhitelist, whitelist); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, - dropOldRequests, duplicateOptional, filterAndSort, - includeBlacklist, includeMaxPathSize, - includeSuffixWhitelist, includeWhitelist); + dropOldRequests, duplicateOptional, filterAndSort, include); MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) -MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) -MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, - initialBlacklist, initialWhitelist, multiVersion, - multiVersionBlacklist, multiVersionWhitelist, onChange, - threads, trackDependency, whitelist); +MAKE_REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, + whitelist) +MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, + initialWhitelist, multiVersion, multiVersionBlacklist, + multiVersionWhitelist, onChange, threads, trackDependency, + whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat, - clang, client, codeLens, completion, diagnostics, highlight, - index, largeFileSize, workspaceSymbol, xref); + index, workspaceSymbol, xref); extern Config *g_config; diff --git a/src/include_complete.cc b/src/include_complete.cc index 779b04b01..e634e189d 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -35,13 +35,11 @@ struct CompletionCandidate { }; std::string ElideLongPath(const std::string &path) { - if (g_config->completion.includeMaxPathSize <= 0) + if (g_config->completion.include.maxPathSize <= 0 || + (int)path.size() <= g_config->completion.include.maxPathSize) return path; - if ((int)path.size() <= g_config->completion.includeMaxPathSize) - return path; - - size_t start = path.size() - g_config->completion.includeMaxPathSize; + size_t start = path.size() - g_config->completion.include.maxPathSize; return ".." + path.substr(start + 2); } @@ -113,11 +111,11 @@ void IncludeComplete::Rescan() { absolute_path_to_completion_item.clear(); inserted_paths.clear(); - if (!match_ && (g_config->completion.includeWhitelist.size() || - g_config->completion.includeBlacklist.size())) + if (!match_ && (g_config->completion.include.whitelist.size() || + g_config->completion.include.blacklist.size())) match_ = - std::make_unique(g_config->completion.includeWhitelist, - g_config->completion.includeBlacklist); + std::make_unique(g_config->completion.include.whitelist, + g_config->completion.include.blacklist); is_scanning = true; std::thread([this]() { @@ -156,7 +154,7 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, } void IncludeComplete::AddFile(const std::string &absolute_path) { - if (!EndsWithAny(absolute_path, g_config->completion.includeSuffixWhitelist)) + if (!EndsWithAny(absolute_path, g_config->completion.include.suffixWhitelist)) return; if (match_ && !match_->IsMatch(absolute_path)) return; @@ -186,7 +184,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, directory, true /*recursive*/, false /*add_folder_to_path*/, [&](const std::string &path) { if (!include_cpp && - !EndsWithAny(path, g_config->completion.includeSuffixWhitelist)) + !EndsWithAny(path, g_config->completion.include.suffixWhitelist)) return; if (match_ && !match_->IsMatch(directory + path)) return; diff --git a/src/indexer.cc b/src/indexer.cc index 9299b4aaa..ccc5b64fa 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1245,9 +1245,6 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, const std::vector &args, const std::vector> &remapped, bool &ok) { ok = true; - if (!g_config->index.enabled) - return {}; - auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); std::shared_ptr CI = BuildCompilerInvocation(args, FS); diff --git a/src/message_handler.cc b/src/message_handler.cc index e17219763..98ef5dde6 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -133,7 +133,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { static GroupMatch match(g_config->highlight.whitelist, g_config->highlight.blacklist); assert(file->def); - if (wfile->buffer_content.size() > g_config->largeFileSize || + if (wfile->buffer_content.size() > g_config->highlight.largeFileSize || !match.IsMatch(file->def->path)) return; diff --git a/src/pipeline.cc b/src/pipeline.cc index ed01feeb1..f4e5cc1f3 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -295,7 +295,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, path_to_index, entry.args, remapped, ok); if (!ok) { - if (g_config->index.enabled && request.id.Valid()) { + if (request.id.Valid()) { Out_Error out; out.id = request.id; out.error.code = lsErrorCodes::InternalError; From 84984c6c2720df8454b4c0bfec296db792253792 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 30 Sep 2018 22:54:48 -0700 Subject: [PATCH 243/378] Use non-inferred entries and build preamble for .h; index on didOpen if no pending requests; documentHighlight --- src/clang_complete.cc | 21 +++--- src/indexer.h | 1 - src/messages/textDocument_definition.cc | 13 +--- src/messages/textDocument_did.cc | 6 +- .../textDocument_documentHighlight.cc | 69 ++++++++++++------- src/pipeline.cc | 9 ++- src/pipeline.hh | 2 +- src/project.cc | 21 +++--- src/project.h | 2 +- src/query_utils.cc | 11 ++- src/query_utils.h | 3 +- src/symbol.h | 26 ------- src/utils.h | 1 - 13 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 6a785470d..b66a01f8e 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -231,16 +231,13 @@ void CompletionPreloadMain(CompletionManager *manager) { if (!session) continue; - // For inferred session, don't build preamble because changes in a.h will - // invalidate it. - if (!session->inferred) { - const auto &args = session->file.args; - WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot( - {StripFileType(session->file.filename)}); - if (std::unique_ptr CI = - BuildCompilerInvocation(args, session->FS)) - session->BuildPreamble(*CI, request.path); - } + const auto &args = session->file.args; + WorkingFiles::Snapshot snapshot = + session->wfiles->AsSnapshot({StripFileType(session->file.filename)}); + if (std::unique_ptr CI = + BuildCompilerInvocation(args, session->FS)) + session->BuildPreamble(*CI, request.path); + int debounce = is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; if (debounce >= 0) { @@ -539,7 +536,7 @@ bool CompletionManager::EnsureCompletionOrCreatePreloadSession( // No CompletionSession, create new one. auto session = std::make_shared( - project_->FindCompilationEntryForFile(path), working_files_, PCH); + project_->FindEntry(path, false), working_files_, PCH); if (session->file.filename != path) { session->inferred = true; session->file.filename = path; @@ -568,7 +565,7 @@ CompletionManager::TryGetSession(const std::string &path, bool preload, session = sessions.TryGet(path); if (!session && !preload) { session = std::make_shared( - project_->FindCompilationEntryForFile(path), working_files_, PCH); + project_->FindEntry(path, false), working_files_, PCH); sessions.Insert(path, session); LOG_S(INFO) << "create session for " << path; if (is_open) diff --git a/src/indexer.h b/src/indexer.h index 0e6f4e711..2a9110677 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -29,7 +29,6 @@ limitations under the License. #include #include -#include #include #include #include diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index df28502d5..2718abd7a 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -76,21 +76,11 @@ struct Handler_TextDocumentDefinition Out_TextDocumentDefinition out; out.id = request->id; - Maybe range; - SymbolKind kind; Maybe on_def; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); lsPosition &ls_pos = params.position; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { - if (!range) { - range = sym.range; - kind = sym.kind; - } else if (!(sym.range == *range && sym.kind == kind)) { - break; - } - // Found symbol. Return definition. - + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { // Special cases which are handled: // - symbol has declaration but no definition (ie, pure virtual) // - goto declaration while in definition of recursive type @@ -129,6 +119,7 @@ struct Handler_TextDocumentDefinition out.result.erase(std::unique(out.result.begin(), out.result.end()), out.result.end()); } else { + Maybe range; // Check #include for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 5a069ee2e..30bf2acdb 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -125,8 +125,10 @@ struct Handler_TextDocumentDidOpen if (args.size()) project->SetArgsForFile(args, path); - // Submit new index request if it is not a header file. - if (SourceFileLanguage(path) != LanguageId::Unknown) + // Submit new index request if it is not a header file or there is no + // pending index request. + if (SourceFileLanguage(path) != LanguageId::Unknown || + !pipeline::pending_index_requests) pipeline::Index(path, args, IndexMode::Normal); clang_complete->NotifyView(path); diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index 871f617b3..e3d6e35db 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -17,11 +17,28 @@ limitations under the License. #include "pipeline.hh" #include "query_utils.h" #include "symbol.h" + +#include using namespace ccls; namespace { MethodType kMethodType = "textDocument/documentHighlight"; +struct lsDocumentHighlight { + enum Kind { Text = 1, Read = 2, Write = 3 }; + + lsRange range; + int kind = 1; + + // ccls extension + Role role = Role::None; + + bool operator<(const lsDocumentHighlight &o) const { + return !(range == o.range) ? range < o.range : kind < o.kind; + } +}; +MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); + struct In_TextDocumentDocumentHighlight : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; @@ -44,39 +61,41 @@ struct Handler_TextDocumentDocumentHighlight QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, - &file_id)) { + &file_id)) return; - } - WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); Out_TextDocumentDocumentHighlight out; out.id = request->id; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - // Found symbol. Return references to highlight. - EachOccurrence(db, sym, true, [&](Use use) { - if (use.file_id != file_id) - return; - if (std::optional ls_loc = - GetLsLocation(db, working_files, use)) { - lsDocumentHighlight highlight; - highlight.range = ls_loc->range; - if (use.role & Role::Write) - highlight.kind = lsDocumentHighlightKind::Write; - else if (use.role & Role::Read) - highlight.kind = lsDocumentHighlightKind::Read; - else - highlight.kind = lsDocumentHighlightKind::Text; - highlight.role = use.role; - out.result.push_back(highlight); - } - }); - break; + std::vector syms = FindSymbolsAtLocation( + working_file, file, request->params.position, true); + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0) + continue; + Usr usr = sym.usr; + SymbolKind kind = sym.kind; + if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { + return usr == sym1.usr && kind == sym1.kind; + })) + continue; + if (auto ls_loc = + GetLsLocation(db, working_files, + Use{{sym.range, usr, kind, sym.role}, file_id})) { + lsDocumentHighlight highlight; + highlight.range = ls_loc->range; + if (sym.role & Role::Write) + highlight.kind = lsDocumentHighlight::Write; + else if (sym.role & Role::Read) + highlight.kind = lsDocumentHighlight::Read; + else + highlight.kind = lsDocumentHighlight::Text; + highlight.role = sym.role; + out.result.push_back(highlight); + } } - + std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); } }; diff --git a/src/pipeline.cc b/src/pipeline.cc index f4e5cc1f3..c61469c04 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -62,7 +62,8 @@ bool VFS::Stamp(const std::string &path, int64_t ts, int step) { namespace ccls::pipeline { -std::atomic loaded_ts = ATOMIC_VAR_INIT(0); +std::atomic loaded_ts = ATOMIC_VAR_INIT(0), + pending_index_requests = ATOMIC_VAR_INIT(0); int64_t tick = 0; namespace { @@ -175,6 +176,9 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, return false; auto &request = *opt_request; bool loud = request.mode != IndexMode::OnChange; + struct RAII { + ~RAII() { pending_index_requests--; } + } raii; // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { @@ -189,7 +193,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, return false; } - Project::Entry entry = project->FindCompilationEntryForFile(request.path); + Project::Entry entry = project->FindEntry(request.path, true); if (request.args.size()) entry.args = request.args; std::string path_to_index = entry.filename; @@ -547,6 +551,7 @@ void MainLoop() { void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id) { + pending_index_requests++; index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } diff --git a/src/pipeline.hh b/src/pipeline.hh index a232d513d..b4cc514b6 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -39,7 +39,7 @@ enum class IndexMode { }; namespace pipeline { -extern std::atomic loaded_ts; +extern std::atomic loaded_ts, pending_index_requests; extern int64_t tick; void Init(); void LaunchStdin(); diff --git a/src/project.cc b/src/project.cc index 708025382..ca1a0f385 100644 --- a/src/project.cc +++ b/src/project.cc @@ -386,13 +386,16 @@ void Project::SetArgsForFile(const std::vector &args, } } -Project::Entry -Project::FindCompilationEntryForFile(const std::string &filename) { +Project::Entry Project::FindEntry(const std::string &path, + bool can_be_inferred) { { std::lock_guard lock(mutex_); - auto it = path_to_entry_index.find(filename); - if (it != path_to_entry_index.end()) - return entries[it->second]; + auto it = path_to_entry_index.find(path); + if (it != path_to_entry_index.end()) { + Project::Entry &entry = entries[it->second]; + if (can_be_inferred || entry.filename == path) + return entry; + } } // We couldn't find the file. Try to infer it. @@ -400,7 +403,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) { Entry *best_entry = nullptr; int best_score = INT_MIN; for (Entry &entry : entries) { - int score = ComputeGuessScore(filename, entry.filename); + int score = ComputeGuessScore(path, entry.filename); if (score > best_score) { best_score = score; best_entry = &entry; @@ -409,10 +412,10 @@ Project::FindCompilationEntryForFile(const std::string &filename) { Project::Entry result; result.is_inferred = true; - result.filename = filename; + result.filename = path; if (!best_entry) { result.args.push_back("%clang"); - result.args.push_back(Intern(filename)); + result.args.push_back(Intern(path)); } else { result.args = best_entry->args; @@ -424,7 +427,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) { try { if (arg == best_entry->filename || sys::path::filename(arg) == best_entry_base_name) - arg = Intern(filename); + arg = Intern(path); } catch (...) { } } diff --git a/src/project.h b/src/project.h index 125b2af03..59a898556 100644 --- a/src/project.h +++ b/src/project.h @@ -59,7 +59,7 @@ struct Project { // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure. - Entry FindCompilationEntryForFile(const std::string &filename); + Entry FindEntry(const std::string &path, bool can_be_inferred); // If the client has overridden the flags, or specified them for a file // that is not in the compilation_database.json make sure those changes diff --git a/src/query_utils.cc b/src/query_utils.cc index c2e0f0b76..27ce5f717 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -308,7 +308,8 @@ std::optional GetSymbolInfo(DB *db, SymbolIdx sym, std::vector FindSymbolsAtLocation(WorkingFile *wfile, QueryFile *file, - lsPosition &ls_pos) { + lsPosition &ls_pos, + bool smallest) { std::vector symbols; // If multiVersion > 0, index may not exist and thus index_lines is empty. if (wfile && wfile->index_lines.size()) { @@ -353,6 +354,14 @@ std::vector FindSymbolsAtLocation(WorkingFile *wfile, return t > 0; return a.usr < b.usr; }); + if (symbols.size() && smallest) { + SymbolRef sym = symbols[0]; + for (size_t i = 1; i < symbols.size(); i++) + if (!(sym.range == symbols[i].range && sym.kind == symbols[i].kind)) { + symbols.resize(i); + break; + } + } return symbols; } diff --git a/src/query_utils.h b/src/query_utils.h index 0ec2501c5..642a6ba11 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -51,7 +51,8 @@ std::optional GetSymbolInfo(DB *db, SymbolIdx sym, std::vector FindSymbolsAtLocation(WorkingFile *working_file, QueryFile *file, - lsPosition &ls_pos); + lsPosition &ls_pos, + bool smallest = false); template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { switch (sym.kind) { diff --git a/src/symbol.h b/src/symbol.h index 16e4de11d..beec82b8b 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -46,32 +46,6 @@ inline Role operator|(Role lhs, Role rhs) { return Role(uint16_t(lhs) | uint16_t(rhs)); } -// A document highlight kind. -enum class lsDocumentHighlightKind { - // A textual occurrence. - Text = 1, - // Read-access of a symbol, like reading a variable. - Read = 2, - // Write-access of a symbol, like writing to a variable. - Write = 3 -}; -MAKE_REFLECT_TYPE_PROXY(lsDocumentHighlightKind); - -// A document highlight is a range inside a text document which deserves -// special attention. Usually a document highlight is visualized by changing -// the background color of its range. -struct lsDocumentHighlight { - // The range this highlight applies to. - lsRange range; - - // The highlight kind, default is DocumentHighlightKind.Text. - lsDocumentHighlightKind kind = lsDocumentHighlightKind::Text; - - // ccls extension - Role role = Role::None; -}; -MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); - struct lsSymbolInformation { std::string_view name; lsSymbolKind kind; diff --git a/src/utils.h b/src/utils.h index 7b4087cec..2e5560740 100644 --- a/src/utils.h +++ b/src/utils.h @@ -18,7 +18,6 @@ limitations under the License. #include #include -#include #include #include #include From f2227cbaa21866e238708e56563fdd48919ed5ff Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 1 Oct 2018 00:39:44 -0700 Subject: [PATCH 244/378] Clean --- src/main.cc | 2 +- src/message_handler.h | 1 - src/project.cc | 20 +++++++++++--------- src/utils.h | 21 --------------------- 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/main.cc b/src/main.cc index 4d2fb6794..66e76f866 100644 --- a/src/main.cc +++ b/src/main.cc @@ -102,7 +102,7 @@ int main(int argc, char **argv) { if (!opt_init.empty()) { // We check syntax error here but override client-side // initializationOptions in messages/initialize.cc - g_init_options = opt_init; + g_init_options = opt_init.getValue(); rapidjson::Document reader; rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); if (!ok) { diff --git a/src/message_handler.h b/src/message_handler.h index 38074f64d..33bbb6f3e 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -15,7 +15,6 @@ limitations under the License. #pragma once -#include "lru_cache.h" #include "lsp.h" #include "method.h" #include "query.h" diff --git a/src/project.cc b/src/project.cc index ca1a0f385..1278e1e48 100644 --- a/src/project.cc +++ b/src/project.cc @@ -191,24 +191,26 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { std::unordered_map> folder_args; std::vector files; + const std::string &project_dir = config->project_dir; - GetFilesInFolder(config->project_dir, true /*recursive*/, + GetFilesInFolder(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 (sys::path::filename(path) == ".ccls") { - LOG_S(INFO) << "Using .ccls arguments from " << path; - folder_args.emplace(sys::path::parent_path(path), - ReadCompilerArgumentsFromFile(path)); + std::vector args = ReadCompilerArgumentsFromFile(path); + folder_args.emplace(sys::path::parent_path(path), args); + std::string l; + for (size_t i = 0; i < args.size(); i++) { + if (i) + l += ' '; + l += args[i]; + } + LOG_S(INFO) << "use " << path << ": " << l; } }); - const std::string &project_dir = config->project_dir; - const auto &project_dir_args = folder_args[project_dir]; - LOG_IF_S(INFO, !project_dir_args.empty()) - << "Using .ccls arguments " << StringJoin(project_dir_args); - auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) { while (!(cur = sys::path::parent_path(cur)).empty()) { diff --git a/src/utils.h b/src/utils.h index 2e5560740..85e74c1d0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -19,7 +19,6 @@ limitations under the License. #include #include -#include #include #include @@ -42,26 +41,6 @@ std::vector SplitString(const std::string &str, std::string LowerPathIfInsensitive(const std::string &path); -template -std::string StringJoinMap(const TValues &values, const TMap &map, - const std::string &sep = ", ") { - std::string result; - bool first = true; - for (auto &entry : values) { - if (!first) - result += sep; - first = false; - result += map(entry); - } - return result; -} - -template -std::string StringJoin(const TValues &values, const std::string &sep = ", ") { - return StringJoinMap(values, [](const std::string &entry) { return entry; }, - sep); -} - // Ensures that |path| ends in a slash. void EnsureEndsInSlash(std::string &path); From da07cb2da41376be488849a106271aa477c8a3e0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 1 Oct 2018 00:57:24 -0700 Subject: [PATCH 245/378] Add $ccls/info --- CMakeLists.txt | 2 +- src/messages/ccls_fileInfo.cc | 66 --------------------- src/messages/ccls_info.cc | 106 ++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 67 deletions(-) delete mode 100644 src/messages/ccls_fileInfo.cc create mode 100644 src/messages/ccls_info.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 384c008f6..47af70f04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,7 +208,7 @@ target_sources(ccls PRIVATE target_sources(ccls PRIVATE src/messages/ccls_call.cc - src/messages/ccls_fileInfo.cc + src/messages/ccls_info.cc src/messages/ccls_inheritance.cc src/messages/ccls_member.cc src/messages/ccls_navigate.cc diff --git a/src/messages/ccls_fileInfo.cc b/src/messages/ccls_fileInfo.cc deleted file mode 100644 index 5e4f546ac..000000000 --- a/src/messages/ccls_fileInfo.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, - dependencies); - -namespace { -MethodType kMethodType = "$ccls/fileInfo"; - -struct lsDocumentSymbolParams { - lsTextDocumentIdentifier textDocument; -}; -MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); - -struct In_CclsFileInfo : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsDocumentSymbolParams params; -}; -MAKE_REFLECT_STRUCT(In_CclsFileInfo, id, params); -REGISTER_IN_MESSAGE(In_CclsFileInfo); - -struct Out_CclsFileInfo : public lsOutMessage { - lsRequestId id; - QueryFile::Def result; -}; -MAKE_REFLECT_STRUCT(Out_CclsFileInfo, jsonrpc, id, result); - -struct Handler_CclsFileInfo : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsFileInfo *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - Out_CclsFileInfo out; - out.id = request->id; - // Expose some fields of |QueryFile::Def|. - out.result.path = file->def->path; - out.result.args = file->def->args; - out.result.language = file->def->language; - out.result.includes = file->def->includes; - out.result.skipped_ranges = file->def->skipped_ranges; - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsFileInfo); -} // namespace diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc new file mode 100644 index 000000000..3efcae500 --- /dev/null +++ b/src/messages/ccls_info.cc @@ -0,0 +1,106 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "message_handler.h" +#include "pipeline.hh" +#include "project.h" +#include "query_utils.h" +using namespace ccls; + +MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, + dependencies); + +namespace { +MethodType cclsInfo = "$ccls/info", fileInfo = "$ccls/fileInfo"; + +struct In_cclsInfo : public RequestInMessage { + MethodType GetMethodType() const override { return cclsInfo; } +}; +MAKE_REFLECT_STRUCT(In_cclsInfo, id); +REGISTER_IN_MESSAGE(In_cclsInfo); + +struct Out_cclsInfo : public lsOutMessage { + lsRequestId id; + struct Result { + struct DB { + int files, funcs, types, vars; + } db; + struct Pipeline { + int pendingIndexRequests; + } pipeline; + struct Project { + int entries; + } project; + } result; +}; +MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::DB, files, funcs, types, vars); +MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::Pipeline, pendingIndexRequests); +MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::Project, entries); +MAKE_REFLECT_STRUCT(Out_cclsInfo::Result, db, pipeline, project); +MAKE_REFLECT_STRUCT(Out_cclsInfo, jsonrpc, id, result); + +struct Handler_cclsInfo : BaseMessageHandler { + MethodType GetMethodType() const override { return cclsInfo; } + void Run(In_cclsInfo *request) override { + Out_cclsInfo out; + out.id = request->id; + out.result.db.files = db->files.size(); + out.result.db.funcs = db->funcs.size(); + out.result.db.types = db->types.size(); + out.result.db.vars = db->vars.size(); + out.result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; + out.result.project.entries = project->entries.size(); + pipeline::WriteStdout(cclsInfo, out); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_cclsInfo); + +struct In_cclsFileInfo : public RequestInMessage { + MethodType GetMethodType() const override { return fileInfo; } + struct Params { + lsTextDocumentIdentifier textDocument; + } params; +}; +MAKE_REFLECT_STRUCT(In_cclsFileInfo::Params, textDocument); +MAKE_REFLECT_STRUCT(In_cclsFileInfo, id, params); +REGISTER_IN_MESSAGE(In_cclsFileInfo); + +struct Out_cclsFileInfo : public lsOutMessage { + lsRequestId id; + QueryFile::Def result; +}; +MAKE_REFLECT_STRUCT(Out_cclsFileInfo, jsonrpc, id, result); + +struct Handler_cclsFileInfo : BaseMessageHandler { + MethodType GetMethodType() const override { return fileInfo; } + void Run(In_cclsFileInfo *request) override { + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + request->params.textDocument.uri.GetPath(), &file)) + return; + + Out_cclsFileInfo out; + out.id = request->id; + // Expose some fields of |QueryFile::Def|. + out.result.path = file->def->path; + out.result.args = file->def->args; + out.result.language = file->def->language; + out.result.includes = file->def->includes; + out.result.skipped_ranges = file->def->skipped_ranges; + pipeline::WriteStdout(fileInfo, out); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_cclsFileInfo); +} // namespace From 8d49b44154428c05150ad93a2dcb5d2e4914866e Mon Sep 17 00:00:00 2001 From: firstlove Date: Tue, 2 Oct 2018 11:38:16 +0800 Subject: [PATCH 246/378] regard conversion as method instead of constructor --- src/indexer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/indexer.cc b/src/indexer.cc index ccc5b64fa..f157986bb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1033,9 +1033,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; } case Decl::CXXConstructor: - case Decl::CXXConversion: func->def.kind = lsSymbolKind::Constructor; break; + case Decl::CXXConversion: case Decl::CXXDestructor: func->def.kind = lsSymbolKind::Method; break; From 29f05d96fb7bd170e73d9868883fabad98a4a38b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 2 Oct 2018 09:34:55 -0700 Subject: [PATCH 247/378] Use pthread if defined(__unix__) || defined(__APPLE__) --- src/clang_complete.cc | 33 +++++++++++++++------------------ src/messages/initialize.cc | 24 +++++++++++++++--------- src/platform.h | 2 ++ src/platform_posix.cc | 17 +++++++++++++++++ src/platform_win.cc | 6 +++++- 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index b66a01f8e..11f5b8a7e 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -221,7 +221,9 @@ bool Parse(CompilerInstance &Clang) { return true; } -void CompletionPreloadMain(CompletionManager *manager) { +void *CompletionPreloadMain(void *manager_) { + auto *manager = static_cast(manager_); + set_thread_name("comp-preload"); while (true) { auto request = manager->preload_requests_.Dequeue(); @@ -246,9 +248,12 @@ void CompletionPreloadMain(CompletionManager *manager) { manager->DiagnosticsUpdate(request.path, debounce); } } + return nullptr; } -void CompletionMain(CompletionManager *manager) { +void *CompletionMain(void *manager_) { + auto *manager = static_cast(manager_); + set_thread_name("comp"); while (true) { // Fetching the completion request blocks until we have a request. std::unique_ptr request = @@ -296,6 +301,7 @@ void CompletionMain(CompletionManager *manager) { request->on_complete(&Clang->getCodeCompletionConsumer()); } + return nullptr; } llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) { @@ -326,7 +332,9 @@ void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { OS << diagLeveltoString(d.level) << ": " << d.message; } -void DiagnosticMain(CompletionManager *manager) { +void *DiagnosticMain(void *manager_) { + auto *manager = static_cast(manager_); + set_thread_name("diag"); while (true) { CompletionManager::DiagnosticRequest request = manager->diagnostic_request_.Dequeue(); @@ -422,6 +430,7 @@ void DiagnosticMain(CompletionManager *manager) { } manager->on_diagnostic_(path, ls_diags); } + return nullptr; } } // namespace @@ -470,21 +479,9 @@ CompletionManager::CompletionManager(Project *project, preloads(kMaxPreloadedSessions), sessions(kMaxCompletionSessions), PCH(std::make_shared()) { - std::thread([&]() { - set_thread_name("comp"); - ccls::CompletionMain(this); - }) - .detach(); - std::thread([&]() { - set_thread_name("comp-preload"); - ccls::CompletionPreloadMain(this); - }) - .detach(); - std::thread([&]() { - set_thread_name("diag"); - ccls::DiagnosticMain(this); - }) - .detach(); + SpawnThread(ccls::CompletionMain, this); + SpawnThread(ccls::CompletionPreloadMain, this); + SpawnThread(ccls::DiagnosticMain, this); } void CompletionManager::DiagnosticsUpdate(const std::string &path, diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 443bf6a61..cd9d378e0 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -406,6 +406,19 @@ struct Out_InitializeResponse : public lsOutMessage { MAKE_REFLECT_STRUCT(Out_InitializeResponse::InitializeResult, capabilities); MAKE_REFLECT_STRUCT(Out_InitializeResponse, jsonrpc, id, result); +void *Indexer(void *arg_) { + MessageHandler *h; + int idx; + auto *arg = static_cast *>(arg_); + std::tie(h, idx) = *arg; + delete arg; + std::string name = "indexer" + std::to_string(idx); + set_thread_name(name.c_str()); + pipeline::Indexer_Main(h->clang_complete, h->vfs, h->project, + h->working_files); + return nullptr; +} + struct Handler_Initialize : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -483,7 +496,6 @@ struct Handler_Initialize : BaseMessageHandler { idx::Init(); - // Open up / load the project. project->Load(project_path); // Start indexer threads. Start this after loading the project, as that @@ -493,14 +505,8 @@ struct Handler_Initialize : BaseMessageHandler { g_config->index.threads = std::thread::hardware_concurrency(); LOG_S(INFO) << "start " << g_config->index.threads << " indexers"; - for (int i = 0; i < g_config->index.threads; i++) { - std::thread([=]() { - std::string name = "indexer" + std::to_string(i); - set_thread_name(name.c_str()); - pipeline::Indexer_Main(clang_complete, vfs, project, working_files); - }) - .detach(); - } + for (int i = 0; i < g_config->index.threads; i++) + SpawnThread(Indexer, new std::pair{this, i}); // Start scanning include directories before dispatching project // files, because that takes a long time. diff --git a/src/platform.h b/src/platform.h index 46e88307d..076860f57 100644 --- a/src/platform.h +++ b/src/platform.h @@ -29,3 +29,5 @@ void TraceMe(); std::string GetExternalCommandOutput(const std::vector &command, std::string_view input); + +void SpawnThread(void *(*fn)(void *), void *arg); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 1d2d59a9f..ed2f92dfc 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -28,7 +28,9 @@ limitations under the License. #include #include #include +#include #include +#include #include #include // required for stat.h #include @@ -169,4 +171,19 @@ std::string GetExternalCommandOutput(const std::vector &command, return ret; } +void SpawnThread(void *(*fn)(void *), void *arg) { + pthread_t thd; + pthread_attr_t attr; + struct rlimit rlim; + size_t stack_size = 4 * 1024 * 1024; + if (getrlimit(RLIMIT_STACK, &rlim) == 0 && + rlim.rlim_cur != RLIM_INFINITY) + stack_size = rlim.rlim_cur; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, stack_size); + pthread_create(&thd, &attr, fn, arg); + pthread_attr_destroy(&attr); +} + #endif diff --git a/src/platform_win.cc b/src/platform_win.cc index 3acbe7e20..797644c8f 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -27,8 +27,8 @@ limitations under the License. #include #include -#include #include +#include std::string NormalizePath(const std::string &path) { DWORD retval = 0; @@ -61,4 +61,8 @@ std::string GetExternalCommandOutput(const std::vector &command, return ""; } +void SpawnThread(void *(*fn)(void *), void *arg) { + std::thread(fn, arg).detach(); +} + #endif From fc8a60c6305bd20180b648e415e6dc8352b2605e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 2 Oct 2018 17:34:02 -0700 Subject: [PATCH 248/378] Add PreambleStatCache --- src/clang_complete.cc | 192 ++++++++++++++++++++++++++++++++---------- src/clang_complete.hh | 10 +-- 2 files changed, 148 insertions(+), 54 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 11f5b8a7e..d487caa95 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -37,7 +37,99 @@ using namespace llvm; #include namespace chrono = std::chrono; +#if LLVM_VERSION_MAJOR < 8 +namespace clang::vfs { +struct ProxyFileSystem : FileSystem { + explicit ProxyFileSystem(IntrusiveRefCntPtr FS) + : FS(std::move(FS)) {} + llvm::ErrorOr status(const Twine &Path) override { + return FS->status(Path); + } + llvm::ErrorOr> + openFileForRead(const Twine &Path) override { + return FS->openFileForRead(Path); + } + directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override { + return FS->dir_begin(Dir, EC); + } + llvm::ErrorOr getCurrentWorkingDirectory() const override { + return FS->getCurrentWorkingDirectory(); + } + std::error_code setCurrentWorkingDirectory(const Twine &Path) override { + return FS->setCurrentWorkingDirectory(Path); + } +#if LLVM_VERSION_MAJOR == 7 + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl &Output) const override { + return FS->getRealPath(Path, Output); + } +#endif + FileSystem &getUnderlyingFS() { return *FS; } + IntrusiveRefCntPtr FS; +}; +} +#endif + namespace ccls { +struct PreambleStatCache { + llvm::StringMap> Cache; + + void Update(Twine Path, ErrorOr S) { + Cache.try_emplace(Path.str(), std::move(S)); + } + + IntrusiveRefCntPtr + Producer(IntrusiveRefCntPtr FS) { + struct VFS : vfs::ProxyFileSystem { + PreambleStatCache &Cache; + + VFS(IntrusiveRefCntPtr FS, PreambleStatCache &Cache) + : ProxyFileSystem(std::move(FS)), Cache(Cache) {} + llvm::ErrorOr> + openFileForRead(const Twine &Path) override { + auto File = getUnderlyingFS().openFileForRead(Path); + if (!File || !*File) + return File; + Cache.Update(Path, File->get()->status()); + return File; + } + llvm::ErrorOr status(const Twine &Path) override { + auto S = getUnderlyingFS().status(Path); + Cache.Update(Path, S); + return S; + } + }; + return new VFS(std::move(FS), *this); + } + + IntrusiveRefCntPtr + Consumer(IntrusiveRefCntPtr FS) { + struct VFS : vfs::ProxyFileSystem { + const PreambleStatCache &Cache; + VFS(IntrusiveRefCntPtr FS, + const PreambleStatCache &Cache) + : ProxyFileSystem(std::move(FS)), Cache(Cache) {} + llvm::ErrorOr status(const Twine &Path) override { + auto I = Cache.Cache.find(Path.str()); + if (I != Cache.Cache.end()) + return I->getValue(); + return getUnderlyingFS().status(Path); + } + }; + return new VFS(std::move(FS), *this); + } +}; + +struct PreambleData { + PreambleData(clang::PrecompiledPreamble P, std::vector diags, + std::unique_ptr stat_cache) + : Preamble(std::move(P)), diags(std::move(diags)), + stat_cache(std::move(stat_cache)) {} + clang::PrecompiledPreamble Preamble; + std::vector diags; + std::unique_ptr stat_cache; +}; + namespace { std::string StripFileType(const std::string &path) { @@ -172,31 +264,29 @@ class StoreDiags : public DiagnosticConsumer { std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, - DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, + IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, + const PreambleData *preamble, const WorkingFiles::Snapshot &snapshot, std::vector> &Bufs) { std::string main = ResolveIfRelative( session.file.directory, sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile())); for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); - if (file.filename == main) - if (auto Preamble = session.GetPreamble()) { + if (preamble && file.filename == main) { #if LLVM_VERSION_MAJOR >= 7 - Preamble->Preamble.OverridePreamble(*CI, session.FS, - Bufs.back().get()); + preamble->Preamble.OverridePreamble(*CI, FS, Bufs.back().get()); #else - Preamble->Preamble.AddImplicitPreamble(*CI, session.FS, - Bufs.back().get()); + preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get()); #endif - continue; - } + continue; + } CI->getPreprocessorOpts().addRemappedFile(file.filename, Bufs.back().get()); } auto Clang = std::make_unique(session.PCH); Clang->setInvocation(std::move(CI)); - Clang->setVirtualFileSystem(session.FS); + Clang->setVirtualFileSystem(FS); Clang->createDiagnostics(&DC, false); Clang->setTarget(TargetInfo::CreateTargetInfo( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); @@ -221,6 +311,36 @@ bool Parse(CompilerInstance &Clang) { return true; } +void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, + IntrusiveRefCntPtr FS, + const std::string &main, + std::unique_ptr stat_cache) { + std::shared_ptr OldP = session.GetPreamble(); + std::string content = session.wfiles->GetContent(main); + std::unique_ptr Buf = + llvm::MemoryBuffer::getMemBuffer(content); + auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); + if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) + return; + CI.getDiagnosticOpts().IgnoreWarnings = false; + CI.getFrontendOpts().SkipFunctionBodies = true; + CI.getLangOpts()->CommentOpts.ParseAllComments = true; +#if LLVM_VERSION_MAJOR >= 7 + CI.getPreprocessorOpts().WriteCommentListToPCH = false; +#endif + + StoreDiags DC(main); + IntrusiveRefCntPtr DE = + CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &DC, false); + PreambleCallbacks PP; + if (auto NewPreamble = PrecompiledPreamble::Build( + CI, Buf.get(), Bounds, *DE, FS, session.PCH, true, PP)) { + std::lock_guard lock(session.mutex); + session.preamble = std::make_shared( + std::move(*NewPreamble), DC.Take(), std::move(stat_cache)); + } +} + void *CompletionPreloadMain(void *manager_) { auto *manager = static_cast(manager_); set_thread_name("comp-preload"); @@ -236,9 +356,11 @@ void *CompletionPreloadMain(void *manager_) { const auto &args = session->file.args; WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot({StripFileType(session->file.filename)}); + auto stat_cache = std::make_unique(); + IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); if (std::unique_ptr CI = - BuildCompilerInvocation(args, session->FS)) - session->BuildPreamble(*CI, request.path); + BuildCompilerInvocation(args, FS)) + BuildPreamble(*session, *CI, FS, request.path, std::move(stat_cache)); int debounce = is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; @@ -272,9 +394,11 @@ void *CompletionMain(void *manager_) { std::shared_ptr session = manager->TryGetSession(path, false); - + std::shared_ptr preamble = session->GetPreamble(); + IntrusiveRefCntPtr FS = + preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, FS); if (!CI) continue; auto &FOpts = CI->getFrontendOpts(); @@ -289,7 +413,8 @@ void *CompletionMain(void *manager_) { WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; - auto Clang = BuildCompilerInstance(*session, std::move(CI), DC, snapshot, Bufs); + auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, + preamble.get(), snapshot, Bufs); if (!Clang) continue; @@ -349,9 +474,11 @@ void *DiagnosticMain(void *manager_) { std::shared_ptr session = manager->TryGetSession(path, false); - + std::shared_ptr preamble = session->GetPreamble(); + IntrusiveRefCntPtr FS = + preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, FS); if (!CI) continue; CI->getDiagnosticOpts().IgnoreWarnings = false; @@ -360,7 +487,8 @@ void *DiagnosticMain(void *manager_) { WorkingFiles::Snapshot snapshot = manager->working_files_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; - auto Clang = BuildCompilerInstance(*session, std::move(CI), DC, snapshot, Bufs); + auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, + preamble.get(), snapshot, Bufs); if (!Clang) continue; if (!Parse(*Clang)) @@ -440,34 +568,6 @@ std::shared_ptr CompletionSession::GetPreamble() { return preamble; } -void CompletionSession::BuildPreamble(CompilerInvocation &CI, - const std::string &main) { - std::shared_ptr OldP = GetPreamble(); - std::string content = wfiles->GetContent(main); - std::unique_ptr Buf = - llvm::MemoryBuffer::getMemBuffer(content); - auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); - if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) - return; - CI.getDiagnosticOpts().IgnoreWarnings = false; - CI.getFrontendOpts().SkipFunctionBodies = true; - CI.getLangOpts()->CommentOpts.ParseAllComments = true; -#if LLVM_VERSION_MAJOR >= 7 - CI.getPreprocessorOpts().WriteCommentListToPCH = false; -#endif - - StoreDiags DC(main); - IntrusiveRefCntPtr DE = - CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &DC, false); - PreambleCallbacks PP; - if (auto NewPreamble = PrecompiledPreamble::Build(CI, Buf.get(), Bounds, - *DE, FS, PCH, true, PP)) { - std::lock_guard lock(mutex); - preamble = - std::make_shared(std::move(*NewPreamble), DC.Take()); - } -} - } // namespace ccls CompletionManager::CompletionManager(Project *project, diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 7020ab4d5..c7c131b11 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -33,6 +33,8 @@ limitations under the License. #include namespace ccls { +struct PreambleData; + struct DiagBase { Range range; std::string message; @@ -47,13 +49,6 @@ struct Diag : DiagBase { std::vector edits; }; -struct PreambleData { - PreambleData(clang::PrecompiledPreamble P, std::vector diags) - : Preamble(std::move(P)), diags(std::move(diags)) {} - clang::PrecompiledPreamble Preamble; - std::vector diags; -}; - struct CompletionSession : public std::enable_shared_from_this { std::mutex mutex; @@ -73,7 +68,6 @@ struct CompletionSession : file(file), wfiles(wfiles), PCH(PCH) {} std::shared_ptr GetPreamble(); - void BuildPreamble(clang::CompilerInvocation &CI, const std::string &main); }; } From c7ee3d85f3fa181acb4b3f66fb9472b02b4823b6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 3 Oct 2018 00:27:45 -0700 Subject: [PATCH 249/378] For $ccls/member, use unadjusted RecordDecl (if there is forward declaration) and handle ClassTemplateSpecialization --- src/indexer.cc | 54 ++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index f157986bb..530a27675 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -606,6 +606,30 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } + void CollectRecordMembers(IndexType &type, const RecordDecl *RD) { + SmallVector, 2> Stack{{RD, 0}}; + llvm::DenseSet Seen; + Seen.insert(RD); + while (Stack.size()) { + int offset; + std::tie(RD, offset) = Stack.back(); + Stack.pop_back(); + if (!RD->isCompleteDefinition() || RD->isDependentType() || + RD->isInvalidDecl() || !ValidateRecord(RD)) + offset = -1; + for (FieldDecl *FD : RD->fields()) { + int offset1 = offset < 0 ? -1 : offset + Ctx->getFieldOffset(FD); + if (FD->getIdentifier()) + type.def.vars.emplace_back(GetUsr(FD), offset1); + else if (const auto *RT1 = FD->getType()->getAs()) { + if (const RecordDecl *RD1 = RT1->getDecl()) + if (Seen.insert(RD1).second) + Stack.push_back({RD1, offset1}); + } + } + } + } + public: IndexDataConsumer(IndexParam ¶m) : param(param) {} void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; } @@ -929,35 +953,17 @@ class IndexDataConsumer : public index::IndexDataConsumer { type->def.short_name_size = name.size(); } } - if (is_def) { - SmallVector, 2> Stack{{RD, 0}}; - llvm::DenseSet Seen; - Seen.insert(RD); - while (Stack.size()) { - int offset; - std::tie(RD, offset) = Stack.back(); - Stack.pop_back(); - if (!RD->isCompleteDefinition() || RD->isDependentType() || - RD->isInvalidDecl() || !ValidateRecord(RD)) - offset = -1; - for (FieldDecl *FD : RD->fields()) { - int offset1 = offset < 0 ? -1 : offset + Ctx->getFieldOffset(FD); - if (FD->getIdentifier()) - type->def.vars.emplace_back(GetUsr(FD), offset1); - else if (const auto *RT1 = FD->getType()->getAs()) { - if (const RecordDecl *RD1 = RT1->getDecl()) - if (Seen.insert(RD1).second) - Stack.push_back({RD1, offset1}); - } - } - } - } + if (is_def) + if (auto *ORD = dyn_cast(OrigD)) + CollectRecordMembers(*type, ORD); } break; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: type->def.kind = lsSymbolKind::Class; - if (is_def || is_decl) { + if (is_def) { + if (auto *ORD = dyn_cast(OrigD)) + CollectRecordMembers(*type, ORD); if (auto *RD = dyn_cast(D)) { Decl *D1 = nullptr; if (auto *SD = dyn_cast(RD)) From 38feb8d277c3eeaa44e5ffa314637f5c0e6c3fd2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 3 Oct 2018 09:15:09 -0700 Subject: [PATCH 250/378] Add completion.maxNum: 100 --- src/clang_tu.cc | 2 -- src/config.h | 6 +++++- src/messages/textDocument_completion.cc | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index f147b4c23..b58a69e9c 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -22,8 +22,6 @@ limitations under the License. #include #include -#include - using namespace clang; std::string PathFromFileEntry(const FileEntry &file) { diff --git a/src/config.h b/src/config.h index 8889f94bd..32d9fff67 100644 --- a/src/config.h +++ b/src/config.h @@ -130,6 +130,9 @@ struct Config { // that implement their own filtering and sorting logic. bool filterAndSort = true; + // Maxmum number of results. + int maxNum = 100; + struct Include { // Regex patterns to match include completion candidates against. They // receive the absolute file path. @@ -260,7 +263,8 @@ MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, suffixWhitelist, whitelist); MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, - dropOldRequests, duplicateOptional, filterAndSort, include); + dropOldRequests, duplicateOptional, filterAndSort, include, + maxNum); MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 411e4763c..daa6c7c3a 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -182,9 +182,9 @@ void FilterAndSortCompletionResponse( auto &items = complete_response->result.items; auto finalize = [&]() { - const size_t kMaxResultSize = 100u; - if (items.size() > kMaxResultSize) { - items.resize(kMaxResultSize); + int max_num = g_config->completion.maxNum; + if (items.size() > max_num) { + items.resize(max_num); complete_response->result.isIncomplete = true; } From 6ec032c2a0fc733713b3a605673431dff2f5e3ad Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 4 Oct 2018 16:13:30 -0700 Subject: [PATCH 251/378] Redesign SymbolRef, Ref, Use Remove lsLocationEx --- src/config.h | 4 +- src/indexer.cc | 285 ++++++++---------- src/indexer.h | 75 ++--- src/lsp.h | 11 +- src/message_handler.cc | 21 +- src/messages/ccls_call.cc | 38 ++- src/messages/ccls_navigate.cc | 2 +- src/messages/ccls_vars.cc | 2 +- src/messages/textDocument_codeLens.cc | 12 +- src/messages/textDocument_definition.cc | 21 +- .../textDocument_documentHighlight.cc | 6 +- src/messages/textDocument_documentSymbol.cc | 12 +- src/messages/textDocument_implementation.cc | 8 +- src/messages/textDocument_references.cc | 24 +- src/messages/textDocument_typeDefinition.cc | 15 +- src/query.cc | 18 +- src/query.h | 4 +- src/query_utils.cc | 34 +-- src/query_utils.h | 11 +- src/serializer.cc | 40 +-- 20 files changed, 279 insertions(+), 364 deletions(-) diff --git a/src/config.h b/src/config.h index 32d9fff67..abb31deec 100644 --- a/src/config.h +++ b/src/config.h @@ -249,8 +249,6 @@ struct Config { } workspaceSymbol; struct Xref { - // If true, |Location[]| response will include lexical container. - bool container = false; // Maximum number of definition/reference/... results. int maxNum = 2000; } xref; @@ -274,7 +272,7 @@ MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, multiVersionWhitelist, onChange, threads, trackDependency, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); -MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); +MAKE_REFLECT_STRUCT(Config::Xref, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat, clang, client, codeLens, completion, diagnostics, highlight, diff --git a/src/indexer.cc b/src/indexer.cc index 530a27675..2ebbdd34d 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -117,50 +117,109 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, BInfo.second); } -SymbolKind GetSymbolKind(const Decl *D) { +SymbolKind GetSymbolKind(const Decl *D, lsSymbolKind &kind) { switch (D->getKind()) { - case Decl::TranslationUnit: - return SymbolKind::File; - case Decl::ObjCMethod: - case Decl::FunctionTemplate: - case Decl::Function: - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXConversion: - case Decl::CXXDestructor: - return SymbolKind::Func; + case Decl::LinkageSpec: + return SymbolKind::Invalid; case Decl::Namespace: + kind = lsSymbolKind::Namespace; + return SymbolKind::Type; case Decl::NamespaceAlias: + kind = lsSymbolKind::TypeAlias; + return SymbolKind::Type; case Decl::ObjCCategory: + case Decl::ObjCImplementation: case Decl::ObjCInterface: case Decl::ObjCProtocol: + kind = lsSymbolKind::Interface; + return SymbolKind::Type; + case Decl::ObjCMethod: + kind = lsSymbolKind::Method; + return SymbolKind::Func; + case Decl::ObjCProperty: + kind = lsSymbolKind::Property; + return SymbolKind::Type; case Decl::ClassTemplate: + kind = lsSymbolKind::Class; + return SymbolKind::Type; + case Decl::FunctionTemplate: + kind = lsSymbolKind::Function; + return SymbolKind::Func; case Decl::TypeAliasTemplate: + kind = lsSymbolKind::TypeAlias; + return SymbolKind::Type; + case Decl::VarTemplate: + kind = lsSymbolKind::Variable; + return SymbolKind::Var; case Decl::TemplateTemplateParm: + kind = lsSymbolKind::TypeParameter; + return SymbolKind::Type; case Decl::Enum: - case Decl::Record: + kind = lsSymbolKind::Enum; + return SymbolKind::Type; case Decl::CXXRecord: + case Decl::Record: + kind = lsSymbolKind::Class; + // spec has no Union, use Class + if (auto *RD = dyn_cast(D)) + if (RD->getTagKind() == TTK_Struct) + kind = lsSymbolKind::Struct; + return SymbolKind::Type; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: + kind = lsSymbolKind::Class; + return SymbolKind::Type; case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: + kind = lsSymbolKind::TypeAlias; return SymbolKind::Type; - case Decl::ObjCProperty: - case Decl::VarTemplate: case Decl::Binding: + kind = lsSymbolKind::Variable; + return SymbolKind::Var; case Decl::Field: case Decl::ObjCIvar: + kind = lsSymbolKind::Field; + return SymbolKind::Var; + case Decl::Function: + kind = lsSymbolKind::Function; + return SymbolKind::Func; + case Decl::CXXMethod: { + const auto *MD = cast(D); + kind = MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method; + return SymbolKind::Func; + } + case Decl::CXXConstructor: + kind = lsSymbolKind::Constructor; + return SymbolKind::Func; + case Decl::CXXConversion: + case Decl::CXXDestructor: + kind = lsSymbolKind::Method; + return SymbolKind::Func; case Decl::Var: - case Decl::ParmVar: - case Decl::ImplicitParam: case Decl::Decomposition: + kind = lsSymbolKind::Variable; + return SymbolKind::Var; + case Decl::ImplicitParam: + case Decl::ParmVar: + // ccls extension + kind = lsSymbolKind::Parameter; + return SymbolKind::Var; case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: + kind = lsSymbolKind::Variable; + return SymbolKind::Var; case Decl::EnumConstant: + kind = lsSymbolKind::EnumMember; + return SymbolKind::Var; case Decl::UnresolvedUsingValue: + kind = lsSymbolKind::Variable; return SymbolKind::Var; + case Decl::TranslationUnit: + return SymbolKind::Invalid; + default: + LOG_S(INFO) << "unhandled " << int(D->getKind()); return SymbolKind::Invalid; } } @@ -421,23 +480,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { return it->second.usr; } - Use GetUse(IndexFile *db, int lid, Range range, const DeclContext *DC, - Role role) const { - if (!DC) - return {{range, 0, SymbolKind::File, role}, lid}; - const Decl *D = cast(DC); - switch (GetSymbolKind(D)) { - case SymbolKind::Func: - return {{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}, lid}; - case SymbolKind::Type: - return {{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}, lid}; - case SymbolKind::Var: - return {{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}, lid}; - default: - return {{range, 0, SymbolKind::File, role}, lid}; - } - } - PrintingPolicy GetDefaultPolicy() const { PrintingPolicy PP(Ctx->getLangOpts()); PP.AnonymousTagLocations = false; @@ -590,7 +632,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { return; Range spell = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); - Use use{{spell, 0, SymbolKind::File, Role::Dynamic}, lid}; + Use use{{spell, Role::Dynamic}, lid}; switch (kind) { case SymbolKind::Func: db->ToFunc(usr).uses.push_back(use); @@ -704,7 +746,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; - SymbolKind kind = GetSymbolKind(D); + lsSymbolKind ls_kind; + SymbolKind kind = GetSymbolKind(D, ls_kind); if (is_def) switch (D->getKind()) { @@ -734,19 +777,20 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto do_def_decl = [&](auto *entity) { if (is_def) { - entity->def.spell = GetUse(db, lid, loc, SemDC, role); + entity->def.spell = {{loc, role}, lid}; SourceRange R = OrigD->getSourceRange(); - entity->def.extent = - GetUse(db, lid, - R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, - LexDC, Role::None); + entity->def.extent = { + {R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, + Role::None}, + lid}; + GetSymbolKind(cast(SemDC), entity->def.parent_kind); } else if (is_decl) { DeclRef &dr = entity->declarations.emplace_back(); - static_cast(dr) = GetUse(db, lid, loc, LexDC, role); + static_cast(dr) = {{loc, role}, lid}; SourceRange R = OrigD->getSourceRange(); dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc; } else { - entity->uses.push_back(GetUse(db, lid, loc, LexDC, role)); + entity->uses.push_back({{loc, role}, lid}); return; } if (entity->def.comments[0] == '\0' && g_config->index.comments) @@ -761,6 +805,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { return true; case SymbolKind::Func: func = &db->ToFunc(usr); + func->def.kind = ls_kind; // Mark as Role::Implicit to span one more column to the left/right. if (!is_def && !is_decl && (D->getKind() == Decl::CXXConstructor || @@ -773,17 +818,18 @@ class IndexDataConsumer : public index::IndexDataConsumer { SetName(D, info->short_name, info->qualified, func->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC) == SymbolKind::Type) + if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type) db->ToType(GetUsr(DC)).def.funcs.push_back(usr); } else { const Decl *DC = cast(LexDC); - if (GetSymbolKind(DC) == SymbolKind::Func) + if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func) db->ToFunc(GetUsr(DC)) - .def.callees.push_back({{loc, usr, SymbolKind::Func, role}}); + .def.callees.push_back({loc, usr, SymbolKind::Func, role}); } break; case SymbolKind::Type: type = &db->ToType(usr); + type->def.kind = ls_kind; do_def_decl(type); if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); @@ -791,12 +837,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { SetName(D, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC) == SymbolKind::Type) + if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type) db->ToType(GetUsr(DC)).def.types.push_back(usr); } break; case SymbolKind::Var: var = &db->ToVar(usr); + var->def.kind = ls_kind; do_def_decl(var); if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); @@ -809,7 +856,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { T = FD->getType(); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC) == SymbolKind::Func) + if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func) db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); else if (auto *ND = dyn_cast(SemDC)) db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); @@ -828,14 +875,15 @@ class IndexDataConsumer : public index::IndexDataConsumer { Usr usr1 = GetUsr(D1, &info1); IndexType &type1 = db->ToType(usr1); SourceLocation L1 = D1->getLocation(); - type1.def.spell = - GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, - Role::Definition); - type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), - LexDC, Role::None); + type1.def.spell = { + {FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, + lid}; + type1.def.extent = {{FromTokenRange(SM, Lang, R1), Role::None}, + lid}; type1.def.detailed_name = Intern(info1->short_name); type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.kind = lsSymbolKind::TypeParameter; + type1.def.parent_kind = lsSymbolKind::Class; var->def.type = usr1; type1.instances.push_back(usr); break; @@ -852,11 +900,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { // e.g. lambda parameter SourceLocation L = D->getLocation(); if (SM.getFileID(L) == LocFID) { - var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}), - SemDC, Role::Definition); - var->def.extent = - GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()), - LexDC, Role::None); + var->def.spell = { + {FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}; + var->def.extent = { + {FromTokenRange(SM, Lang, D->getSourceRange()), Role::None}, lid}; + var->def.parent_kind = lsSymbolKind::Method; } } break; @@ -864,7 +912,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { switch (D->getKind()) { case Decl::Namespace: - type->def.kind = lsSymbolKind::Namespace; if (D->isFirstDecl()) { auto *ND = cast(D); auto *ND1 = cast(ND->getParent()); @@ -876,7 +923,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { } break; case Decl::NamespaceAlias: { - type->def.kind = lsSymbolKind::TypeAlias; auto *NAD = cast(D); if (const NamespaceDecl *ND = NAD->getNamespace()) { Usr usr1 = GetUsr(ND); @@ -885,36 +931,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { } break; } - case Decl::ObjCCategory: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCProtocol: - type->def.kind = lsSymbolKind::Interface; - break; - case Decl::ObjCMethod: - func->def.kind = lsSymbolKind::Method; - break; - case Decl::ObjCProperty: - var->def.kind = lsSymbolKind::Property; - break; - case Decl::ClassTemplate: - type->def.kind = lsSymbolKind::Class; - break; - case Decl::FunctionTemplate: - func->def.kind = lsSymbolKind::Function; - break; - case Decl::TypeAliasTemplate: - type->def.kind = lsSymbolKind::TypeAlias; - break; - case Decl::VarTemplate: - var->def.kind = lsSymbolKind::Variable; - break; - case Decl::TemplateTemplateParm: - type->def.kind = lsSymbolKind::TypeParameter; - break; - case Decl::Enum: - type->def.kind = lsSymbolKind::Enum; - break; case Decl::CXXRecord: if (is_def) { auto *RD = dyn_cast(D); @@ -930,9 +946,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { [[fallthrough]]; case Decl::Record: if (auto *RD = dyn_cast(D)) { - // spec has no Union, use Class - type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct - : lsSymbolKind::Class; if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) { StringRef Tag; switch (RD->getTagKind()) { @@ -990,7 +1003,6 @@ class IndexDataConsumer : public index::IndexDataConsumer { case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: - type->def.kind = lsSymbolKind::TypeAlias; if (auto *TD = dyn_cast(D)) { bool specialization = false; QualType T = TD->getUnderlyingType(); @@ -1002,29 +1014,14 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (specialization) { const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); - if (SM.getFileID(L1) == LocFID) { - Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); + if (SM.getFileID(L1) == LocFID) type1.uses.push_back( - GetUse(db, lid, loc1, LexDC, Role::Reference)); - } + {{FromTokenRange(SM, Lang, {L1, L1}), Role::Reference}, lid}); } } } break; - case Decl::Binding: - var->def.kind = lsSymbolKind::Variable; - break; - case Decl::Field: - case Decl::ObjCIvar: - var->def.kind = lsSymbolKind::Field; - break; - case Decl::Function: - func->def.kind = lsSymbolKind::Function; - break; - case Decl::CXXMethod: { - const auto *MD = cast(D); - func->def.kind = - MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method; + case Decl::CXXMethod: if (is_def || is_decl) { if (auto *ND = dyn_cast(D)) { SmallVector OverDecls; @@ -1037,29 +1034,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { } } break; - } - case Decl::CXXConstructor: - func->def.kind = lsSymbolKind::Constructor; - break; - case Decl::CXXConversion: - case Decl::CXXDestructor: - func->def.kind = lsSymbolKind::Method; - break; - case Decl::Var: - case Decl::Decomposition: - var->def.kind = lsSymbolKind::Variable; - break; - case Decl::ImplicitParam: - case Decl::ParmVar: - // ccls extension - var->def.kind = lsSymbolKind::Parameter; - break; - case Decl::VarTemplateSpecialization: - case Decl::VarTemplatePartialSpecialization: - var->def.kind = lsSymbolKind::Variable; - break; case Decl::EnumConstant: - var->def.kind = lsSymbolKind::EnumMember; if (is_def && strchr(var->def.detailed_name, '=') == nullptr) { auto *ECD = cast(D); const auto &Val = ECD->getInitVal(); @@ -1069,11 +1044,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { var->def.hover = Intern(var->def.detailed_name + init); } break; - case Decl::UnresolvedUsingValue: - var->def.kind = lsSymbolKind::Variable; - break; default: - LOG_S(INFO) << "Unhandled " << int(D->getKind()); break; } return true; @@ -1131,16 +1102,17 @@ class IndexPPCallbacks : public PPCallbacks { IndexVar &var = db->ToVar(usr); auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); var.def.kind = lsSymbolKind::Macro; + var.def.parent_kind = lsSymbolKind::File; if (var.def.spell) { DeclRef &d = var.declarations.emplace_back(); static_cast(d) = *var.def.spell; d.extent = var.def.spell->range; } - var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}}; + var.def.spell = Use{{range, Role::Definition}}; const MacroInfo *MI = MD->getMacroInfo(); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); range = FromTokenRange(SM, param.Ctx->getLangOpts(), R); - var.def.extent = Use{{range, 0, SymbolKind::File, Role::None}}; + var.def.extent = Use{{range, Role::None}}; if (var.def.detailed_name[0] == '\0') { var.def.detailed_name = Intern(Name); var.def.short_name_size = Name.size(); @@ -1162,8 +1134,8 @@ class IndexPPCallbacks : public PPCallbacks { if (IndexFile *db = param.ConsumeFile(*FE)) { IndexVar &var = db->ToVar(GetMacro(Tok).second); var.uses.push_back( - {{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), 0, - SymbolKind::File, Role::Dynamic}}); + {{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), + Role::Dynamic}}); } } void MacroUndefined(const Token &Tok, const MacroDefinition &MD, @@ -1198,7 +1170,7 @@ class IndexFrontendAction : public ASTFrontendAction { }; } // namespace -const int IndexFile::kMajorVersion = 18; +const int IndexFile::kMajorVersion = 19; const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, @@ -1390,10 +1362,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, } } // namespace ccls::idx -// |SymbolRef| is serialized this way. -// |Use| also uses this though it has an extra field |file|, -// which is not used by Index* so it does not need to be serialized. -void Reflect(Reader &vis, Reference &v) { +void Reflect(Reader &vis, SymbolRef &v) { if (vis.Format() == SerializeFormat::Json) { std::string t = vis.GetString(); char *s = const_cast(t.c_str()); @@ -1409,7 +1378,7 @@ void Reflect(Reader &vis, Reference &v) { Reflect(vis, v.role); } } -void Reflect(Writer &vis, Reference &v) { +void Reflect(Writer &vis, SymbolRef &v) { if (vis.Format() == SerializeFormat::Json) { char buf[99]; snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", @@ -1430,25 +1399,24 @@ void Reflect(Reader &vis, Use &v) { char *s = const_cast(t.c_str()); v.range = Range::FromString(s); s = strchr(s, '|'); - v.usr = strtoull(s + 1, &s, 10); - v.kind = static_cast(strtol(s + 1, &s, 10)); v.role = static_cast(strtol(s + 1, &s, 10)); v.file_id = static_cast(strtol(s + 1, &s, 10)); } else { - Reflect(vis, static_cast(v)); + Reflect(vis, v.range); + Reflect(vis, v.role); Reflect(vis, v.file_id); } } void Reflect(Writer &vis, Use &v) { if (vis.Format() == SerializeFormat::Json) { char buf[99]; - snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d|%d", - v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role), - v.file_id); + snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(), + int(v.role), v.file_id); std::string s(buf); Reflect(vis, s); } else { - Reflect(vis, static_cast(v)); + Reflect(vis, v.range); + Reflect(vis, v.role); Reflect(vis, v.file_id); } } @@ -1460,9 +1428,7 @@ void Reflect(Reader &vis, DeclRef &v) { v.range = Range::FromString(s); s = strchr(s, '|') + 1; v.extent = Range::FromString(s); - s = strchr(s, '|') + 1; - v.usr = strtoull(s, &s, 10); - v.kind = static_cast(strtol(s + 1, &s, 10)); + s = strchr(s, '|'); v.role = static_cast(strtol(s + 1, &s, 10)); v.file_id = static_cast(strtol(s + 1, &s, 10)); } else { @@ -1473,9 +1439,8 @@ void Reflect(Reader &vis, DeclRef &v) { void Reflect(Writer &vis, DeclRef &v) { if (vis.Format() == SerializeFormat::Json) { char buf[99]; - snprintf(buf, sizeof buf, "%s|%s|%" PRIu64 "|%d|%d|%d", - v.range.ToString().c_str(), v.extent.ToString().c_str(), v.usr, - int(v.kind), int(v.role), v.file_id); + snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(), + v.extent.ToString().c_str(), int(v.role), v.file_id); std::string s(buf); Reflect(vis, s); } else { diff --git a/src/indexer.h b/src/indexer.h index 2a9110677..36b9781ef 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -49,28 +49,36 @@ struct SymbolIdx { }; MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind); -struct Reference { +// |id,kind| refer to the referenced entity. +struct SymbolRef { Range range; Usr usr; SymbolKind kind; Role role; - - bool Valid() const { return range.Valid(); } operator SymbolIdx() const { return {usr, kind}; } std::tuple ToTuple() const { return std::make_tuple(range, usr, 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 SymbolRef &o) const { return ToTuple() == o.ToTuple(); } + bool Valid() const { return range.Valid(); } }; - -// |id,kind| refer to the referenced entity. -struct SymbolRef : Reference {}; MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role); +struct Ref { + Range range; + Role role; + + bool Valid() const { return range.Valid(); } + std::tuple ToTuple() const { + return std::make_tuple(range, role); + } + bool operator==(const Ref &o) const { return ToTuple() == o.ToTuple(); } + bool operator<(const Ref &o) const { return ToTuple() < o.ToTuple(); } +}; + // Represents an occurrence of a variable/type, |usr,kind| refer to the lexical // parent. -struct Use : Reference { +struct Use : Ref { // |file| is used in Query* but not in Index* int file_id = -1; bool operator==(const Use &o) const { @@ -85,8 +93,8 @@ struct DeclRef : Use { }; MAKE_HASHABLE(DeclRef, t.range, t.file_id) -void Reflect(Reader &visitor, Reference &value); -void Reflect(Writer &visitor, Reference &value); +void Reflect(Reader &visitor, SymbolRef &value); +void Reflect(Writer &visitor, SymbolRef &value); void Reflect(Reader &visitor, Use &value); void Reflect(Writer &visitor, Use &value); void Reflect(Reader &visitor, DeclRef &value); @@ -115,74 +123,71 @@ struct FuncDef : NameMixin { // Method this method overrides. std::vector bases; - // Local variables or parameters. std::vector vars; - // Functions that this function calls. std::vector callees; - int file_id = -1; + int file_id = -1; // not serialized int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; + lsSymbolKind parent_kind = lsSymbolKind::Unknown; uint8_t storage = clang::SC_None; std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(FuncDef, detailed_name, qual_name_offset, short_name_offset, - short_name_size, kind, storage, hover, comments, spell, - extent, bases, vars, callees); +MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, extent, + bases, vars, callees, qual_name_offset, short_name_offset, + short_name_size, kind, parent_kind, storage); struct IndexFunc : NameMixin { using Def = FuncDef; Usr usr; Def def; std::vector declarations; - std::vector uses; std::vector derived; + std::vector uses; }; struct TypeDef : NameMixin { const char *detailed_name = ""; const char *hover = ""; const char *comments = ""; - Maybe spell; Maybe extent; std::vector bases; - // Types, functions, and variables defined in this type. - std::vector types; std::vector funcs; + std::vector types; std::vector> vars; // If set, then this is the same underlying type as the given value (ie, this // type comes from a using or typedef statement). Usr alias_of = 0; - - int file_id = -1; + int file_id = -1; // not serialized int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; lsSymbolKind kind = lsSymbolKind::Unknown; + lsSymbolKind parent_kind = lsSymbolKind::Unknown; std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(TypeDef, detailed_name, qual_name_offset, short_name_offset, - short_name_size, kind, hover, comments, spell, extent, - alias_of, bases, types, funcs, vars); +MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, extent, + bases, funcs, types, vars, alias_of, qual_name_offset, + short_name_offset, short_name_size, kind, parent_kind); struct IndexType { using Def = TypeDef; Usr usr; Def def; std::vector declarations; - std::vector uses; std::vector derived; std::vector instances; + std::vector uses; }; struct VarDef : NameMixin { @@ -195,27 +200,29 @@ struct VarDef : NameMixin { // Type of the variable. Usr type = 0; - - int file_id = -1; + int file_id = -1; // not serialized int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; - lsSymbolKind kind = lsSymbolKind::Unknown; + lsSymbolKind parent_kind = lsSymbolKind::Unknown; // Note a variable may have instances of both |None| and |Extern| // (declaration). uint8_t storage = clang::SC_None; bool is_local() const { - return spell && spell->kind == SymbolKind::Func && + return spell && + (parent_kind == lsSymbolKind::Function || + parent_kind == lsSymbolKind::Method || + parent_kind == lsSymbolKind::StaticMethod) && storage == clang::SC_None; } std::vector GetBases() const { return {}; } }; -MAKE_REFLECT_STRUCT(VarDef, detailed_name, qual_name_offset, short_name_offset, - short_name_size, hover, comments, spell, extent, type, kind, - storage); +MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, extent, type, + qual_name_offset, short_name_offset, short_name_size, kind, + parent_kind, storage); struct IndexVar { using Def = VarDef; diff --git a/src/lsp.h b/src/lsp.h index 6e4c5d226..dbe73984b 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -198,15 +198,6 @@ enum class lsSymbolKind : uint8_t { }; MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); -// ccls extension -struct lsLocationEx : lsLocation { - std::optional containerName; - std::optional parentKind; - // Avoid circular dependency on symbol.h - std::optional role; -}; -MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role); - struct lsTextDocumentIdentifier { lsDocumentUri uri; }; @@ -346,6 +337,6 @@ void Reflect(TVisitor &visitor, Out_ShowLogMessage &value) { struct Out_LocationList : public lsOutMessage { lsRequestId id; - std::vector result; + std::vector result; }; MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result); diff --git a/src/message_handler.cc b/src/message_handler.cc index 98ef5dde6..03cf15e25 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -156,24 +156,15 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { const QueryFunc::Def *def = func.AnyDef(); if (!def) continue; // applies to for loop - if (def->spell) - parent_kind = GetSymbolKind(db, *def->spell); - if (parent_kind == lsSymbolKind::Unknown) { - for (Use use : func.declarations) { - parent_kind = GetSymbolKind(db, use); - break; - } - } // Don't highlight overloadable operators or implicit lambda -> // std::function constructor. std::string_view short_name = def->Name(false); if (short_name.compare(0, 8, "operator") == 0) continue; // applies to for loop - if (def->spell) - parent_kind = GetSymbolKind(db, *def->spell); kind = def->kind; storage = def->storage; detailed_name = short_name; + parent_kind = def->parent_kind; // Check whether the function name is actually there. // If not, do not publish the semantic highlight. @@ -200,7 +191,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { kind = def.kind; detailed_name = def.detailed_name; if (def.spell) { - parent_kind = GetSymbolKind(db, *def.spell); + parent_kind = def.parent_kind; break; } } @@ -214,13 +205,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { storage = def.storage; detailed_name = def.detailed_name; if (def.spell) { - parent_kind = GetSymbolKind(db, *def.spell); - break; - } - } - if (parent_kind == lsSymbolKind::Unknown) { - for (Use use : var.declarations) { - parent_kind = GetSymbolKind(db, use); + parent_kind = def.parent_kind; break; } } diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 0ec68f8b8..46477987d 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -77,6 +77,8 @@ struct Out_CclsCall : public lsOutMessage { int numChildren; // Empty if the |levels| limit is reached. std::vector children; + bool operator==(const Entry &o) const { return location == o.location; } + bool operator<(const Entry &o) const { return location < o.location; } }; lsRequestId id; @@ -94,13 +96,14 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, entry->numChildren = 0; if (!def) return false; - auto handle = [&](Use use, CallType call_type1) { + auto handle = [&](SymbolRef sym, int file_id, CallType call_type1) { entry->numChildren++; if (levels > 0) { Out_CclsCall::Entry entry1; - entry1.id = std::to_string(use.usr); - entry1.usr = use.usr; - if (auto loc = GetLsLocation(m->db, m->working_files, use)) + entry1.id = std::to_string(sym.usr); + entry1.usr = sym.usr; + if (auto loc = GetLsLocation(m->db, m->working_files, + Use{{sym.range, sym.role}, file_id})) entry1.location = *loc; entry1.callType = call_type1; if (Expand(m, &entry1, callee, call_type, qualified, levels - 1)) @@ -110,14 +113,22 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, auto handle_uses = [&](const QueryFunc &func, CallType call_type) { if (callee) { if (const auto *def = func.AnyDef()) - for (SymbolRef ref : def->callees) - if (ref.kind == SymbolKind::Func) - handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id}, - call_type); + for (SymbolRef sym : def->callees) + if (sym.kind == SymbolKind::Func) + handle(sym, def->file_id, call_type); } else { - for (Use use : func.uses) - if (use.kind == SymbolKind::Func) - handle(use, call_type); + for (Use use : func.uses) { + const QueryFile &file1 = m->db->files[use.file_id]; + Maybe best_sym; + for (auto [sym, refcnt] : file1.outline2refcnt) + if (refcnt > 0 && sym.kind == SymbolKind::Func && + sym.range.start <= use.range.start && + use.range.end <= sym.range.end && + (!best_sym || best_sym->range.start < sym.range.start)) + best_sym = sym; + if (best_sym) + handle(*best_sym, use.file_id, call_type); + } } }; @@ -160,6 +171,11 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, }); } } + + std::sort(entry->children.begin(), entry->children.end()); + entry->children.erase( + std::unique(entry->children.begin(), entry->children.end()), + entry->children.end()); return true; } diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 921ffae11..7a0fbb2d5 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -104,7 +104,7 @@ struct Handler_CclsNavigate : BaseMessageHandler { out.id = request->id; if (res) if (auto ls_range = GetLsRange(wfile, *res)) { - lsLocationEx &ls_loc = out.result.emplace_back(); + lsLocation &ls_loc = out.result.emplace_back(); ls_loc.uri = params.textDocument.uri; ls_loc.range = *ls_range; } diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 98dc53b89..ac2f24c78 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -63,7 +63,7 @@ struct Handler_CclsVars : BaseMessageHandler { [[fallthrough]]; } case SymbolKind::Type: - out.result = GetLsLocationExs( + out.result = GetLsLocations( db, working_files, GetVarDeclarations(db, db->Type(usr).instances, params.kind)); break; diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index da64859ef..1957fc2ab 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -117,19 +117,19 @@ struct Handler_TextDocumentCodeLens code_lens.command->arguments.push_back(ToString(show)); }; - auto ToSpell = [&](Use use) { - Maybe def = GetDefinitionSpell(db, use); - if (def && def->file_id == use.file_id && - def->range.start.line == use.range.start.line) + auto ToSpell = [&](SymbolRef sym, int file_id) -> Use { + Maybe def = GetDefinitionSpell(db, sym); + if (def && def->file_id == file_id && + def->range.start.line == sym.range.start.line) return *def; - return use; + return {{sym.range, sym.role}, file_id}; }; std::unordered_set seen; for (auto [sym, refcnt] : file->outline2refcnt) { if (refcnt <= 0 || !seen.insert(sym.range).second) continue; - Use use = ToSpell({{sym.range, sym.usr, sym.kind, sym.role}, file->id}); + Use use = ToSpell(sym, file->id); switch (sym.kind) { case SymbolKind::Func: { QueryFunc &func = db->GetFunc(sym); diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 2718abd7a..cb35008f6 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -33,13 +33,6 @@ struct In_TextDocumentDefinition : public RequestInMessage { MAKE_REFLECT_STRUCT(In_TextDocumentDefinition, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDefinition); -struct Out_TextDocumentDefinition - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); - std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { case SymbolKind::Var: { @@ -73,7 +66,7 @@ struct Handler_TextDocumentDefinition params.textDocument.uri.GetPath(), &file, &file_id)) return; - Out_TextDocumentDefinition out; + Out_LocationList out; out.id = request->id; Maybe on_def; @@ -110,7 +103,7 @@ struct Handler_TextDocumentDefinition if (uses.empty() && on_def) uses.push_back(*on_def); } - auto locs = GetLsLocationExs(db, working_files, uses); + auto locs = GetLsLocations(db, working_files, uses); out.result.insert(out.result.end(), locs.begin(), locs.end()); } @@ -123,9 +116,8 @@ struct Handler_TextDocumentDefinition // Check #include for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { - lsLocationEx result; - result.uri = lsDocumentUri::FromPath(include.resolved_path); - out.result.push_back(result); + out.result.push_back( + lsLocation{lsDocumentUri::FromPath(include.resolved_path)}); range = {{0, 0}, {0, 0}}; break; } @@ -184,9 +176,8 @@ struct Handler_TextDocumentDefinition if (best_sym.kind != SymbolKind::Invalid) { Maybe use = GetDefinitionSpell(db, best_sym); assert(use); - if (auto ls_loc = GetLsLocationEx(db, working_files, *use, - g_config->xref.container)) - out.result.push_back(*ls_loc); + if (auto loc = GetLsLocation(db, working_files, *use)) + out.result.push_back(*loc); } } } diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index e3d6e35db..337cd6b3a 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -80,11 +80,9 @@ struct Handler_TextDocumentDocumentHighlight return usr == sym1.usr && kind == sym1.kind; })) continue; - if (auto ls_loc = - GetLsLocation(db, working_files, - Use{{sym.range, usr, kind, sym.role}, file_id})) { + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { lsDocumentHighlight highlight; - highlight.range = ls_loc->range; + highlight.range = loc->range; if (sym.role & Role::Write) highlight.kind = lsDocumentHighlight::Write; else if (sym.role & Role::Read) diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index bda4a2709..0b7a9ce8a 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -107,10 +107,8 @@ struct Handler_TextDocumentDocumentSymbol for (auto [sym, refcnt] : symbol2refcnt) if (refcnt > 0 && params.startLine <= sym.range.start.line && sym.range.start.line <= params.endLine) - if (auto ls_loc = GetLsLocation( - db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) - out.result.push_back(ls_loc->range); + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) + out.result.push_back(loc->range); std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { @@ -213,10 +211,8 @@ struct Handler_TextDocumentDocumentSymbol (sym.kind == SymbolKind::Var && IgnoreVar(db->GetVar(sym).AnyDef()))) continue; - if (std::optional location = GetLsLocation( - db, working_files, - Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) { - info->location = *location; + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + info->location = *loc; out.result.push_back(*info); } } diff --git a/src/messages/textDocument_implementation.cc b/src/messages/textDocument_implementation.cc index 9059f2877..e2db7078d 100644 --- a/src/messages/textDocument_implementation.cc +++ b/src/messages/textDocument_implementation.cc @@ -47,13 +47,13 @@ struct Handler_TextDocumentImplementation FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Type) { QueryType &type = db->GetType(sym); - out.result = GetLsLocationExs(db, working_files, - GetTypeDeclarations(db, type.derived)); + out.result = GetLsLocations(db, working_files, + GetTypeDeclarations(db, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc &func = db->GetFunc(sym); - out.result = GetLsLocationExs(db, working_files, - GetFuncDeclarations(db, func.derived)); + out.result = GetLsLocations(db, working_files, + GetFuncDeclarations(db, func.derived)); break; } } diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index f09adfc89..e5f2ac5be 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -50,13 +50,6 @@ MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position, MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params); REGISTER_IN_MESSAGE(In_TextDocumentReferences); -struct Out_TextDocumentReferences - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentReferences, jsonrpc, id, result); - struct Handler_TextDocumentReferences : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -67,7 +60,7 @@ struct Handler_TextDocumentReferences if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - Out_TextDocumentReferences out; + Out_LocationList out; out.id = request->id; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); if (!file) { @@ -75,7 +68,6 @@ struct Handler_TextDocumentReferences return; } - bool container = g_config->xref.container; std::unordered_set seen_uses; int line = params.position.line; @@ -93,11 +85,8 @@ struct Handler_TextDocumentReferences if (Role(use.role & params.context.role) == params.context.role && !(use.role & params.context.excludeRole) && seen_uses.insert(use).second) - if (std::optional ls_loc = - GetLsLocationEx(db, working_files, use, container)) { - if (container) - ls_loc->parentKind = parent_kind; - out.result.push_back(*ls_loc); + if (auto loc = GetLsLocation(db, working_files, use)) { + out.result.push_back(*loc); } }; WithEntity(db, sym, [&](const auto &entity) { @@ -145,10 +134,9 @@ struct Handler_TextDocumentReferences for (const IndexInclude &include : file1.def->includes) if (include.resolved_path == path) { // Another file |file1| has the same include line. - lsLocationEx result; - result.uri = lsDocumentUri::FromPath(file1.def->path); - result.range.start.line = result.range.end.line = include.line; - out.result.push_back(std::move(result)); + lsLocation &loc = out.result.emplace_back(); + loc.uri = lsDocumentUri::FromPath(file1.def->path); + loc.range.start.line = loc.range.end.line = include.line; break; } } diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index 307868502..812bfe4af 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -28,13 +28,6 @@ struct In_TextDocumentTypeDefinition : public RequestInMessage { MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params); REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition); -struct Out_TextDocumentTypeDefinition - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentTypeDefinition, jsonrpc, id, result); - struct Handler_TextDocumentTypeDefinition : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -47,19 +40,17 @@ struct Handler_TextDocumentTypeDefinition WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentTypeDefinition out; + Out_LocationList out; out.id = request->id; auto Add = [&](const QueryType &type) { for (const auto &def : type.def) if (def.spell) { - if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell, - g_config->xref.container)) + if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) out.result.push_back(*ls_loc); } if (out.result.empty()) for (const DeclRef &dr : type.declarations) - if (auto ls_loc = GetLsLocationEx(db, working_files, dr, - g_config->xref.container)) + if (auto ls_loc = GetLsLocation(db, working_files, dr)) out.result.push_back(*ls_loc); }; for (SymbolRef sym : diff --git a/src/query.cc b/src/query.cc index f052c42c2..07f67acea 100644 --- a/src/query.cc +++ b/src/query.cc @@ -34,8 +34,6 @@ void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) { use.file_id = file_id; else use.file_id = lid2file_id.find(use.file_id)->second; - if (use.kind == SymbolKind::File) - use.usr = use.file_id; } template @@ -238,7 +236,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { SymbolKind kind, Use &use, int delta, int k = 1) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; - SymbolRef sym{{use.range, usr, kind, use.role}}; + SymbolRef sym{use.range, usr, kind, use.role}; if (k & 1) { int &v = files[use.file_id].symbol2refcnt[sym]; v += delta; @@ -258,7 +256,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { SymbolKind kind, DeclRef &dr, int delta) { Ref(lid2fid, usr, kind, dr, delta, 1); files[dr.file_id] - .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta; + .outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta; }; auto UpdateUses = @@ -401,12 +399,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Func, def.spell->role}}]++; + def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++; } if (def.extent) { AssignFileId(lid2file_id, file_id, *def.extent); files[def.extent->file_id].outline2refcnt[{ - {def.extent->range, u.first, SymbolKind::Func, def.extent->role}}]++; + def.extent->range, u.first, SymbolKind::Func, def.extent->role}]++; } auto R = func_usr.try_emplace({u.first}, func_usr.size()); @@ -428,12 +426,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Type, def.spell->role}}]++; + def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++; } if (def.extent) { AssignFileId(lid2file_id, file_id, *def.extent); files[def.extent->file_id].outline2refcnt[{ - {def.extent->range, u.first, SymbolKind::Type, def.extent->role}}]++; + def.extent->range, u.first, SymbolKind::Type, def.extent->role}]++; } auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) @@ -454,12 +452,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Var, def.spell->role}}]++; + def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++; } if (def.extent) { AssignFileId(lid2file_id, file_id, *def.extent); files[def.extent->file_id].outline2refcnt[{ - {def.extent->range, u.first, SymbolKind::Var, def.extent->role}}]++; + def.extent->range, u.first, SymbolKind::Var, def.extent->role}]++; } auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) diff --git a/src/query.h b/src/query.h index 3cc50fd6e..d968a3a6b 100644 --- a/src/query.h +++ b/src/query.h @@ -85,17 +85,17 @@ struct QueryFunc : QueryEntity { Usr usr; llvm::SmallVector def; std::vector declarations; - std::vector uses; std::vector derived; + std::vector uses; }; struct QueryType : QueryEntity { Usr usr; llvm::SmallVector def; std::vector declarations; - std::vector uses; std::vector derived; std::vector instances; + std::vector uses; }; struct QueryVar : QueryEntity { diff --git a/src/query_utils.cc b/src/query_utils.cc index 27ce5f717..db7a3be7b 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -61,8 +61,7 @@ Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { Maybe GetDefinitionExtent(DB *db, SymbolIdx sym) { // Used to jump to file. if (sym.kind == SymbolKind::File) - return Use{{Range{{0, 0}, {0, 0}}, sym.usr, sym.kind, Role::None}, - int(sym.usr)}; + return Use{{Range{{0, 0}, {0, 0}}, Role::None}, int(sym.usr)}; Maybe ret; EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); }); return ret; @@ -216,40 +215,27 @@ lsDocumentUri GetLsDocumentUri(DB *db, int file_id) { } } -std::optional GetLsLocation(DB *db, WorkingFiles *working_files, +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) { std::string path; lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); std::optional range = - GetLsRange(working_files->GetFileByFilename(path), use.range); + GetLsRange(wfiles->GetFileByFilename(path), use.range); if (!range) return std::nullopt; return lsLocation{uri, *range}; } -std::optional GetLsLocationEx(DB *db, WorkingFiles *working_files, - Use use, bool container) { - std::optional ls_loc = GetLsLocation(db, working_files, use); - if (!ls_loc) - return std::nullopt; - lsLocationEx ret; - ret.lsLocation::operator=(*ls_loc); - if (container) { - ret.role = uint16_t(use.role); - EachEntityDef(db, use, [&](const auto &def) { - ret.containerName = std::string_view(def.detailed_name); - return false; - }); - } - return ret; +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, + SymbolRef sym, int file_id) { + return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id}); } -std::vector GetLsLocationExs(DB *db, WorkingFiles *working_files, - const std::vector &uses) { - std::vector ret; +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, + const std::vector &uses) { + std::vector ret; for (Use use : uses) - if (auto loc = - GetLsLocationEx(db, working_files, use, g_config->xref.container)) + if (auto loc = GetLsLocation(db, wfiles, use)) ret.push_back(*loc); std::sort(ret.begin(), ret.end()); ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); diff --git a/src/query_utils.h b/src/query_utils.h index 642a6ba11..e5641bd93 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -39,12 +39,11 @@ std::optional GetLsRange(WorkingFile *working_file, lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); lsDocumentUri GetLsDocumentUri(DB *db, int file_id); -std::optional GetLsLocation(DB *db, WorkingFiles *working_files, - Use use); -std::optional GetLsLocationEx(DB *db, WorkingFiles *working_files, - Use use, bool container); -std::vector GetLsLocationExs(DB *db, WorkingFiles *working_files, - const std::vector &refs); +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, + SymbolRef sym, int file_id); +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, + const std::vector &uses); // Returns a symbol. The symbol will *NOT* have a location assigned. std::optional GetSymbolInfo(DB *db, SymbolIdx sym, bool detailed); diff --git a/src/serializer.cc b/src/serializer.cc index 68c804931..07e1b2f55 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -255,45 +255,49 @@ template void ReflectShortName(Writer &visitor, Def &def) { } } -template void Reflect(TVisitor &visitor, IndexType &value) { +template void Reflect(TVisitor &visitor, IndexFunc &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); - REFLECT_MEMBER2("kind", value.def.kind); - ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("extent", value.def.extent); - REFLECT_MEMBER2("alias_of", value.def.alias_of); + ReflectHoverAndComments(visitor, value.def); REFLECT_MEMBER2("bases", value.def.bases); - REFLECT_MEMBER2("derived", value.derived); - REFLECT_MEMBER2("types", value.def.types); - REFLECT_MEMBER2("funcs", value.def.funcs); REFLECT_MEMBER2("vars", value.def.vars); - REFLECT_MEMBER2("instances", value.instances); + REFLECT_MEMBER2("callees", value.def.callees); + REFLECT_MEMBER2("kind", value.def.kind); + REFLECT_MEMBER2("parent_kind", value.def.parent_kind); + REFLECT_MEMBER2("storage", value.def.storage); + + REFLECT_MEMBER2("declarations", value.declarations); + REFLECT_MEMBER2("derived", value.derived); REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER_END(); } -template void Reflect(TVisitor &visitor, IndexFunc &value) { +template void Reflect(TVisitor &visitor, IndexType &value) { REFLECT_MEMBER_START(); REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); - REFLECT_MEMBER2("kind", value.def.kind); - REFLECT_MEMBER2("storage", value.def.storage); ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("extent", value.def.extent); REFLECT_MEMBER2("bases", value.def.bases); - REFLECT_MEMBER2("derived", value.derived); + REFLECT_MEMBER2("funcs", value.def.funcs); + REFLECT_MEMBER2("types", value.def.types); REFLECT_MEMBER2("vars", value.def.vars); + REFLECT_MEMBER2("alias_of", value.def.alias_of); + REFLECT_MEMBER2("kind", value.def.kind); + REFLECT_MEMBER2("parent_kind", value.def.parent_kind); + + REFLECT_MEMBER2("declarations", value.declarations); + REFLECT_MEMBER2("derived", value.derived); + REFLECT_MEMBER2("instances", value.instances); REFLECT_MEMBER2("uses", value.uses); - REFLECT_MEMBER2("callees", value.def.callees); REFLECT_MEMBER_END(); } @@ -304,13 +308,15 @@ template void Reflect(TVisitor &visitor, IndexVar &value) { REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("extent", value.def.extent); REFLECT_MEMBER2("type", value.def.type); - REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("kind", value.def.kind); + REFLECT_MEMBER2("parent_kind", value.def.parent_kind); REFLECT_MEMBER2("storage", value.def.storage); + + REFLECT_MEMBER2("declarations", value.declarations); + REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER_END(); } From 8c2170172d2b2055d4b2fb2c0ace94760d03c807 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 4 Oct 2018 16:59:33 -0700 Subject: [PATCH 252/378] Use DeclRef spell to represent Use spell + Use extent --- src/indexer.cc | 34 +++++------ src/indexer.h | 19 +++--- src/messages/textDocument_codeLens.cc | 2 +- src/messages/textDocument_definition.cc | 14 ++--- src/messages/textDocument_documentSymbol.cc | 4 +- src/messages/workspace_symbol.cc | 4 +- src/query.cc | 65 ++++++--------------- src/query_utils.cc | 13 +---- src/query_utils.h | 3 +- src/serializer.cc | 3 - 10 files changed, 55 insertions(+), 106 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 2ebbdd34d..e4356146c 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -777,12 +777,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { auto do_def_decl = [&](auto *entity) { if (is_def) { - entity->def.spell = {{loc, role}, lid}; SourceRange R = OrigD->getSourceRange(); - entity->def.extent = { - {R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, - Role::None}, - lid}; + entity->def.spell = { + Use{{loc, role}, lid}, + R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc}; GetSymbolKind(cast(SemDC), entity->def.parent_kind); } else if (is_decl) { DeclRef &dr = entity->declarations.emplace_back(); @@ -876,10 +874,9 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexType &type1 = db->ToType(usr1); SourceLocation L1 = D1->getLocation(); type1.def.spell = { - {FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, - lid}; - type1.def.extent = {{FromTokenRange(SM, Lang, R1), Role::None}, - lid}; + Use{{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, + lid}, + FromTokenRange(SM, Lang, R1)}; type1.def.detailed_name = Intern(info1->short_name); type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.kind = lsSymbolKind::TypeParameter; @@ -901,9 +898,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceLocation L = D->getLocation(); if (SM.getFileID(L) == LocFID) { var->def.spell = { - {FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}; - var->def.extent = { - {FromTokenRange(SM, Lang, D->getSourceRange()), Role::None}, lid}; + Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}, + FromTokenRange(SM, Lang, D->getSourceRange())}; var->def.parent_kind = lsSymbolKind::Method; } } @@ -1100,19 +1096,15 @@ class IndexPPCallbacks : public PPCallbacks { if (IndexFile *db = param.ConsumeFile(*FE)) { auto [Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); - auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); + Range range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); var.def.kind = lsSymbolKind::Macro; var.def.parent_kind = lsSymbolKind::File; - if (var.def.spell) { - DeclRef &d = var.declarations.emplace_back(); - static_cast(d) = *var.def.spell; - d.extent = var.def.spell->range; - } - var.def.spell = Use{{range, Role::Definition}}; + if (var.def.spell) + var.declarations.push_back(*var.def.spell); const MacroInfo *MI = MD->getMacroInfo(); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); - range = FromTokenRange(SM, param.Ctx->getLangOpts(), R); - var.def.extent = Use{{range, Role::None}}; + Range extent = FromTokenRange(SM, param.Ctx->getLangOpts(), R); + var.def.spell = {Use{{range, Role::Definition}}, extent}; if (var.def.detailed_name[0] == '\0') { var.def.detailed_name = Intern(Name); var.def.short_name_size = Name.size(); diff --git a/src/indexer.h b/src/indexer.h index 36b9781ef..8f26822cc 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -118,8 +118,7 @@ struct FuncDef : NameMixin { const char *detailed_name = ""; const char *hover = ""; const char *comments = ""; - Maybe spell; - Maybe extent; + Maybe spell; // Method this method overrides. std::vector bases; @@ -138,8 +137,8 @@ struct FuncDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, extent, - bases, vars, callees, qual_name_offset, short_name_offset, +MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars, + callees, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind, storage); struct IndexFunc : NameMixin { @@ -155,8 +154,7 @@ struct TypeDef : NameMixin { const char *detailed_name = ""; const char *hover = ""; const char *comments = ""; - Maybe spell; - Maybe extent; + Maybe spell; std::vector bases; // Types, functions, and variables defined in this type. @@ -176,8 +174,8 @@ struct TypeDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, extent, - bases, funcs, types, vars, alias_of, qual_name_offset, +MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases, + funcs, types, vars, alias_of, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind); struct IndexType { @@ -195,8 +193,7 @@ struct VarDef : NameMixin { const char *detailed_name = ""; const char *hover = ""; const char *comments = ""; - Maybe spell; - Maybe extent; + Maybe spell; // Type of the variable. Usr type = 0; @@ -220,7 +217,7 @@ struct VarDef : NameMixin { std::vector GetBases() const { return {}; } }; -MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, extent, type, +MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind, storage); diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index 1957fc2ab..2045250a0 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -118,7 +118,7 @@ struct Handler_TextDocumentCodeLens }; auto ToSpell = [&](SymbolRef sym, int file_id) -> Use { - Maybe def = GetDefinitionSpell(db, sym); + Maybe def = GetDefinitionSpell(db, sym); if (def && def->file_id == file_id && def->range.start.line == sym.range.start.line) return *def; diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index cb35008f6..2118a64fc 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -41,7 +41,7 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { if (ret.empty()) { for (auto &def : db->GetVar(sym).def) if (def.type) { - if (Maybe use = GetDefinitionSpell( + if (Maybe use = GetDefinitionSpell( db, SymbolIdx{def.type, SymbolKind::Type})) { ret.push_back(*use); break; @@ -147,11 +147,11 @@ struct Handler_TextDocumentDefinition : short_name; if (short_name != short_query) return; - if (Maybe use = GetDefinitionSpell(db, sym)) { + if (Maybe dr = GetDefinitionSpell(db, sym)) { std::tuple score{ int(name.size() - short_query.size()), 0, - use->file_id != file_id, - std::abs(use->range.start.line - position.line)}; + dr->file_id != file_id, + std::abs(dr->range.start.line - position.line)}; // Update the score with qualified name if the qualified name // occurs in |name|. auto pos = name.rfind(query); @@ -174,9 +174,9 @@ struct Handler_TextDocumentDefinition fn({var.usr, SymbolKind::Var}); if (best_sym.kind != SymbolKind::Invalid) { - Maybe use = GetDefinitionSpell(db, best_sym); - assert(use); - if (auto loc = GetLsLocation(db, working_files, *use)) + Maybe dr = GetDefinitionSpell(db, best_sym); + assert(dr); + if (auto loc = GetLsLocation(db, working_files, *dr)) out.result.push_back(*loc); } } diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 0b7a9ce8a..ec9fed12e 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -132,10 +132,10 @@ struct Handler_TextDocumentDocumentSymbol ds.detail = def->Name(true); for (auto &def : entity.def) if (def.file_id == file_id) { - if (!def.spell || !def.extent) + if (!def.spell) break; ds.kind = def.kind; - if (auto ls_range = GetLsRange(wfile, def.extent->range)) + if (auto ls_range = GetLsRange(wfile, def.spell->extent)) ds.range = *ls_range; else break; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 4758b38e6..c9bb43d86 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -37,8 +37,8 @@ bool AddSymbol( return false; Use loc; - if (Maybe location = GetDefinitionExtent(db, sym)) - loc = *location; + if (Maybe dr = GetDefinitionSpell(db, sym)) + loc = *dr; else { auto decls = GetNonDefDeclarations(db, sym); if (decls.empty()) diff --git a/src/query.cc b/src/query.cc index 07f67acea..c81b8827e 100644 --- a/src/query.cc +++ b/src/query.cc @@ -233,28 +233,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { // References (Use &use) in this function are important to update file_id. auto Ref = [&](std::unordered_map &lid2fid, Usr usr, - SymbolKind kind, Use &use, int delta, int k = 1) { + SymbolKind kind, Use &use, int delta) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; SymbolRef sym{use.range, usr, kind, use.role}; - if (k & 1) { - int &v = files[use.file_id].symbol2refcnt[sym]; - v += delta; - assert(v >= 0); - if (!v) - files[use.file_id].symbol2refcnt.erase(sym); - } - if (k & 2) { - int &v = files[use.file_id].outline2refcnt[sym]; - v += delta; - assert(v >= 0); - if (!v) - files[use.file_id].outline2refcnt.erase(sym); - } + int &v = files[use.file_id].symbol2refcnt[sym]; + v += delta; + assert(v >= 0); + if (!v) + files[use.file_id].symbol2refcnt.erase(sym); }; auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, SymbolKind kind, DeclRef &dr, int delta) { - Ref(lid2fid, usr, kind, dr, delta, 1); + Ref(lid2fid, usr, kind, dr, delta); files[dr.file_id] .outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta; }; @@ -305,12 +296,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { funcs.reserve(t); func_usr.reserve(t); } - for (auto &[usr, def] : u->funcs_removed) { + for (auto &[usr, def] : u->funcs_removed) if (def.spell) - Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); - if (def.extent) - Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1, 2); - } + RefDecl(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); for (auto &[usr, del_add]: u->funcs_declarations) { @@ -329,12 +317,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { types.reserve(t); type_usr.reserve(t); } - for (auto &[usr, def] : u->types_removed) { + for (auto &[usr, def] : u->types_removed) if (def.spell) - Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); - if (def.extent) - Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1, 2); - } + RefDecl(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); Update(lid2file_id, u->file_id, std::move(u->types_def_update)); for (auto &[usr, del_add]: u->types_declarations) { @@ -354,12 +339,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { vars.reserve(t); var_usr.reserve(t); } - for (auto &[usr, def] : u->vars_removed) { + for (auto &[usr, def] : u->vars_removed) if (def.spell) - Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); - if (def.extent) - Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1, 2); - } + RefDecl(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); for (auto &[usr, del_add]: u->vars_declarations) { @@ -400,11 +382,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++; - } - if (def.extent) { - AssignFileId(lid2file_id, file_id, *def.extent); - files[def.extent->file_id].outline2refcnt[{ - def.extent->range, u.first, SymbolKind::Func, def.extent->role}]++; + files[def.spell->file_id].outline2refcnt[{ + def.spell->extent, u.first, SymbolKind::Func, def.spell->role}]++; } auto R = func_usr.try_emplace({u.first}, func_usr.size()); @@ -427,11 +406,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++; - } - if (def.extent) { - AssignFileId(lid2file_id, file_id, *def.extent); - files[def.extent->file_id].outline2refcnt[{ - def.extent->range, u.first, SymbolKind::Type, def.extent->role}]++; + files[def.spell->file_id].outline2refcnt[{ + def.spell->extent, u.first, SymbolKind::Type, def.spell->role}]++; } auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) @@ -453,11 +429,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++; - } - if (def.extent) { - AssignFileId(lid2file_id, file_id, *def.extent); - files[def.extent->file_id].outline2refcnt[{ - def.extent->range, u.first, SymbolKind::Var, def.extent->role}]++; + files[def.spell->file_id].outline2refcnt[{ + def.spell->extent, u.first, SymbolKind::Var, def.spell->role}]++; } auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) diff --git a/src/query_utils.cc b/src/query_utils.cc index db7a3be7b..3da47b352 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -52,21 +52,12 @@ GetDeclarations(llvm::DenseMap &entity_usr, } // namespace -Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { - Maybe ret; +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { + Maybe ret; EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); return ret; } -Maybe GetDefinitionExtent(DB *db, SymbolIdx sym) { - // Used to jump to file. - if (sym.kind == SymbolKind::File) - return Use{{Range{{0, 0}, {0, 0}}, Role::None}, int(sym.usr)}; - Maybe ret; - EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); }); - return ret; -} - std::vector GetFuncDeclarations(DB *db, const std::vector &usrs) { return GetDeclarations(db->func_usr, db->funcs, usrs); } diff --git a/src/query_utils.h b/src/query_utils.h index e5641bd93..55baa6a47 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -20,8 +20,7 @@ limitations under the License. #include -Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); -Maybe GetDefinitionExtent(DB *db, SymbolIdx sym); +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) // for each id. diff --git a/src/serializer.cc b/src/serializer.cc index 07e1b2f55..5c9730ea4 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -262,7 +262,6 @@ template void Reflect(TVisitor &visitor, IndexFunc &value) { REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); ReflectShortName(visitor, value.def); REFLECT_MEMBER2("spell", value.def.spell); - REFLECT_MEMBER2("extent", value.def.extent); ReflectHoverAndComments(visitor, value.def); REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("vars", value.def.vars); @@ -285,7 +284,6 @@ template void Reflect(TVisitor &visitor, IndexType &value) { ReflectShortName(visitor, value.def); ReflectHoverAndComments(visitor, value.def); REFLECT_MEMBER2("spell", value.def.spell); - REFLECT_MEMBER2("extent", value.def.extent); REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("funcs", value.def.funcs); REFLECT_MEMBER2("types", value.def.types); @@ -309,7 +307,6 @@ template void Reflect(TVisitor &visitor, IndexVar &value) { ReflectShortName(visitor, value.def); ReflectHoverAndComments(visitor, value.def); REFLECT_MEMBER2("spell", value.def.spell); - REFLECT_MEMBER2("extent", value.def.extent); REFLECT_MEMBER2("type", value.def.type); REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("parent_kind", value.def.parent_kind); From 10c1c28dd1d480645512c01217fbb80d4c7fbefd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 4 Oct 2018 23:31:59 -0700 Subject: [PATCH 253/378] Clean and update tests after Index* refactoring --- index_tests/class_forward_declaration.cc | 14 +- index_tests/constructors/constructor.cc | 60 ++-- index_tests/constructors/destructor.cc | 62 ++-- .../constructors/implicit_constructor.cc | 60 ++-- index_tests/constructors/invalid_reference.cc | 28 +- index_tests/constructors/make_functions.cc | 241 +++++++------- .../declaration_vs_definition/class.cc | 14 +- .../declaration_vs_definition/class_member.cc | 35 +- .../class_member_static.cc | 37 ++- index_tests/declaration_vs_definition/func.cc | 14 +- .../func_associated_function_params.cc | 45 +-- .../declaration_vs_definition/method.cc | 52 +-- index_tests/enums/enum_class_decl.cc | 48 +-- index_tests/enums/enum_decl.cc | 34 +- index_tests/enums/enum_inherit.cc | 82 ++--- index_tests/enums/enum_usage.cc | 46 +-- index_tests/foobar.cc | 84 ++--- index_tests/function_declaration.cc | 11 +- .../function_declaration_definition.cc | 14 +- index_tests/function_definition.cc | 12 +- index_tests/inheritance/class_inherit.cc | 30 +- .../class_inherit_templated_parent.cc | 80 ++--- .../inheritance/class_multiple_inherit.cc | 62 ++-- index_tests/inheritance/function_override.cc | 53 +-- .../inheritance/interface_pure_virtual.cc | 25 +- .../inheritance/multiple_base_functions.cc | 84 ++--- index_tests/lambdas/lambda.cc | 73 +++-- index_tests/macros/complex.cc | 57 ++-- index_tests/macros/foo.cc | 69 ++-- index_tests/method_declaration.cc | 25 +- index_tests/method_definition.cc | 30 +- index_tests/method_inline_declaration.cc | 26 +- index_tests/multi_file/funky_enum.cc | 61 ++-- index_tests/multi_file/impl.cc | 168 +++++----- index_tests/multi_file/simple_impl.cc | 32 +- index_tests/multi_file/static.cc | 50 +-- index_tests/namespaces/anonymous_function.cc | 22 +- .../namespaces/function_declaration.cc | 22 +- index_tests/namespaces/function_definition.cc | 23 +- index_tests/namespaces/method_declaration.cc | 36 +- index_tests/namespaces/method_definition.cc | 41 +-- .../namespaces/method_inline_declaration.cc | 37 ++- index_tests/namespaces/namespace_alias.cc | 105 +++--- index_tests/namespaces/namespace_reference.cc | 68 ++-- index_tests/operators/operator.cc | 61 ++-- .../outline/static_function_in_type.cc | 110 ++++--- index_tests/preprocessor/include_guard.cc | 10 +- .../func_specialized_template_param.cc | 46 +-- .../implicit_variable_instantiation.cc | 84 ++--- .../templates/member_ref_in_template.cc | 61 ++-- ...ass_template_func_usage_folded_into_one.cc | 70 ++-- ...ace_template_type_usage_folded_into_one.cc | 47 +-- index_tests/templates/specialization.cc | 307 +++++++++--------- .../templates/specialized_func_definition.cc | 53 +-- ...mplate_class_func_usage_folded_into_one.cc | 59 ++-- ...ass_template_func_usage_folded_into_one.cc | 59 ++-- ...mplate_class_type_usage_folded_into_one.cc | 84 ++--- ...emplate_class_var_usage_folded_into_one.cc | 54 +-- .../template_func_usage_folded_into_one.cc | 43 +-- .../template_type_usage_folded_into_one.cc | 36 +- .../template_var_usage_folded_into_one.cc | 76 ++--- index_tests/types/anonymous_struct.cc | 79 ++--- index_tests/types/typedefs.cc | 27 +- index_tests/unions/union_decl.cc | 56 ++-- index_tests/unions/union_usage.cc | 80 ++--- .../usage/func_called_from_constructor.cc | 42 +-- .../usage/func_called_from_macro_argument.cc | 33 +- .../usage/func_called_from_template.cc | 44 +-- .../usage/func_called_implicit_ctor.cc | 51 +-- index_tests/usage/func_usage_addr_func.cc | 46 +-- index_tests/usage/func_usage_addr_method.cc | 49 +-- index_tests/usage/func_usage_call_func.cc | 24 +- index_tests/usage/func_usage_call_method.cc | 49 +-- .../usage/func_usage_class_inline_var_def.cc | 47 +-- .../usage/func_usage_forward_decl_func.cc | 23 +- .../usage/func_usage_forward_decl_method.cc | 49 +-- index_tests/usage/func_usage_template_func.cc | 23 +- .../usage/type_usage_as_template_parameter.cc | 74 ++--- ...ype_usage_as_template_parameter_complex.cc | 122 +++---- ...type_usage_as_template_parameter_simple.cc | 39 +-- .../usage/type_usage_declare_extern.cc | 23 +- index_tests/usage/type_usage_declare_field.cc | 63 ++-- index_tests/usage/type_usage_declare_local.cc | 61 ++-- index_tests/usage/type_usage_declare_param.cc | 61 ++-- .../type_usage_declare_param_prototype.cc | 37 ++- .../usage/type_usage_declare_param_unnamed.cc | 25 +- .../usage/type_usage_declare_qualifiers.cc | 88 ++--- .../usage/type_usage_declare_static.cc | 26 +- .../usage/type_usage_on_return_type.cc | 96 +++--- .../usage/type_usage_typedef_and_using.cc | 123 +++---- .../type_usage_typedef_and_using_template.cc | 43 +-- index_tests/usage/type_usage_various.cc | 47 +-- index_tests/usage/usage_inside_of_call.cc | 91 +++--- .../usage/usage_inside_of_call_simple.cc | 35 +- index_tests/usage/var_usage_call_function.cc | 34 +- index_tests/usage/var_usage_class_member.cc | 91 +++--- .../usage/var_usage_class_member_static.cc | 57 ++-- index_tests/usage/var_usage_cstyle_cast.cc | 42 +-- index_tests/usage/var_usage_extern.cc | 30 +- index_tests/usage/var_usage_func_parameter.cc | 33 +- index_tests/usage/var_usage_local.cc | 33 +- index_tests/usage/var_usage_shadowed_local.cc | 43 +-- .../usage/var_usage_shadowed_parameter.cc | 43 +-- index_tests/usage/var_usage_static.cc | 33 +- index_tests/vars/class_member.cc | 26 +- index_tests/vars/class_static_member.cc | 26 +- .../vars/class_static_member_decl_only.cc | 32 +- index_tests/vars/deduce_auto_type.cc | 48 +-- index_tests/vars/function_local.cc | 35 +- index_tests/vars/function_param.cc | 45 +-- index_tests/vars/function_param_unnamed.cc | 12 +- index_tests/vars/function_shadow_local.cc | 43 +-- index_tests/vars/function_shadow_param.cc | 43 +-- index_tests/vars/global_variable.cc | 21 +- index_tests/vars/global_variable_decl_only.cc | 18 +- .../vars/type_instance_on_using_type.cc | 54 +-- src/message_handler.cc | 5 +- 117 files changed, 3134 insertions(+), 3021 deletions(-) diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index 0da901610..7c5e23a23 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -14,16 +14,16 @@ class Foo; "detailed_name": "class Foo", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": ["1:7-1:10|1:1-1:10|0|1|1|-1", "2:7-2:10|2:1-2:10|0|1|1|-1", "4:7-4:10|4:1-4:10|0|1|1|-1"], - "spell": "3:7-3:10|0|1|2|-1", - "extent": "3:1-3:13|0|1|0|-1", - "alias_of": 0, + "spell": "3:7-3:10|3:1-3:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["1:7-1:10|1:1-1:10|1|-1", "2:7-2:10|2:1-2:10|1|-1", "4:7-4:10|4:1-4:10|1|-1"], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index 72fcaf0dc..7901e0fb2 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -18,75 +18,75 @@ void foo() { "detailed_name": "Foo::Foo()", "qual_name_offset": 0, "short_name": "Foo", + "spell": "3:3-3:6|3:3-3:11|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|1026|-1", - "extent": "3:3-3:11|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["7:7-7:8|4259594751088586730|3|16676|-1", "8:17-8:20|4259594751088586730|3|16676|-1"], - "callees": [] + "uses": ["7:7-7:8|16676|-1", "8:17-8:20|16676|-1"] }, { "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "6:6-6:9|6:1-9:2|2|-1", + "bases": [], + "vars": [10983126130596230582, 17165811951126099095], + "callees": ["7:7-7:8|3385168158331140247|3|16676", "7:7-7:8|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "6:6-6:9|0|1|2|-1", - "extent": "6:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [10983126130596230582, 17165811951126099095], - "uses": [], - "callees": ["7:7-7:8|3385168158331140247|3|16676", "7:7-7:8|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676", "8:17-8:20|3385168158331140247|3|16676"] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [3385168158331140247], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [10983126130596230582, 17165811951126099095], - "uses": ["3:3-3:6|15041163540773201510|2|4|-1", "7:3-7:6|4259594751088586730|3|4|-1", "8:3-8:6|4259594751088586730|3|4|-1", "8:17-8:20|4259594751088586730|3|4|-1"] + "uses": ["3:3-3:6|4|-1", "7:3-7:6|4|-1", "8:3-8:6|4|-1", "8:17-8:20|4|-1"] }], "usr2var": [{ "usr": 10983126130596230582, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", - "declarations": [], - "spell": "7:7-7:8|4259594751088586730|3|2|-1", - "extent": "7:3-7:8|4259594751088586730|3|0|-1", + "spell": "7:7-7:8|7:3-7:8|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 17165811951126099095, "detailed_name": "Foo *f2", "qual_name_offset": 5, "short_name": "f2", "hover": "Foo *f2 = new Foo()", - "declarations": [], - "spell": "8:8-8:10|4259594751088586730|3|2|-1", - "extent": "8:3-8:22|4259594751088586730|3|0|-1", + "spell": "8:8-8:10|8:3-8:22|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 97207f379..c8ad82b71 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -23,77 +23,77 @@ void foo() { "detailed_name": "Foo::Foo()", "qual_name_offset": 0, "short_name": "Foo", + "spell": "3:3-3:6|3:3-3:11|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "3:3-3:6|15041163540773201510|2|1026|-1", - "extent": "3:3-3:11|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["8:7-8:8|4259594751088586730|3|16676|-1"], - "callees": [] + "uses": ["8:7-8:8|16676|-1"] }, { "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "7:6-7:9|7:1-9:2|2|-1", + "bases": [], + "vars": [1893354193220338759], + "callees": ["8:7-8:8|3385168158331140247|3|16676", "8:7-8:8|3385168158331140247|3|16676"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "7:6-7:9|0|1|2|-1", - "extent": "7:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [1893354193220338759], - "uses": [], - "callees": ["8:7-8:8|3385168158331140247|3|16676", "8:7-8:8|3385168158331140247|3|16676"] + "uses": [] }, { "usr": 7440261702884428359, "detailed_name": "Foo::~Foo() noexcept", "qual_name_offset": 0, "short_name": "~Foo", + "spell": "4:3-4:7|4:3-4:12|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "4:3-4:7|15041163540773201510|2|1026|-1", - "extent": "4:3-4:12|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [3385168158331140247, 7440261702884428359], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [1893354193220338759], - "uses": ["3:3-3:6|15041163540773201510|2|4|-1", "4:4-4:7|15041163540773201510|2|4|-1", "8:3-8:6|4259594751088586730|3|4|-1"] + "uses": ["3:3-3:6|4|-1", "4:4-4:7|4|-1", "8:3-8:6|4|-1"] }], "usr2var": [{ "usr": 1893354193220338759, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", - "declarations": [], - "spell": "8:7-8:8|4259594751088586730|3|2|-1", - "extent": "8:3-8:8|4259594751088586730|3|0|-1", + "spell": "8:7-8:8|8:3-8:8|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index b3995cfd5..31c7c8ce9 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -17,75 +17,75 @@ void Make() { "detailed_name": "void Make()", "qual_name_offset": 5, "short_name": "Make", + "spell": "5:6-5:10|5:1-8:2|2|-1", + "bases": [], + "vars": [449111627548814328, 17097499197730163115], + "callees": ["6:8-6:12|10530961286677896857|3|16676", "6:8-6:12|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2|-1", - "extent": "5:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [449111627548814328, 17097499197730163115], - "uses": [], - "callees": ["6:8-6:12|10530961286677896857|3|16676", "6:8-6:12|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676", "7:15-7:19|10530961286677896857|3|16676"] + "uses": [] }, { "usr": 10530961286677896857, "detailed_name": "Type::Type()", "qual_name_offset": 0, "short_name": "Type", + "spell": "2:3-2:7|2:3-2:12|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "2:3-2:7|13487927231218873822|2|1026|-1", - "extent": "2:3-2:12|13487927231218873822|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["6:8-6:12|3957104924306079513|3|16676|-1", "7:15-7:19|3957104924306079513|3|16676|-1"], - "callees": [] + "uses": ["6:8-6:12|16676|-1", "7:15-7:19|16676|-1"] }], "usr2type": [{ "usr": 13487927231218873822, "detailed_name": "struct Type {}", "qual_name_offset": 7, "short_name": "Type", - "kind": 23, - "declarations": [], - "spell": "1:8-1:12|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:12|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [10530961286677896857], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [449111627548814328, 17097499197730163115], - "uses": ["2:3-2:7|13487927231218873822|2|4|-1", "6:3-6:7|3957104924306079513|3|4|-1", "7:15-7:19|3957104924306079513|3|4|-1"] + "uses": ["2:3-2:7|4|-1", "6:3-6:7|4|-1", "7:15-7:19|4|-1"] }], "usr2var": [{ "usr": 449111627548814328, "detailed_name": "Type foo0", "qual_name_offset": 5, "short_name": "foo0", - "declarations": [], - "spell": "6:8-6:12|3957104924306079513|3|2|-1", - "extent": "6:3-6:12|3957104924306079513|3|0|-1", + "spell": "6:8-6:12|6:3-6:12|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 17097499197730163115, "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", "hover": "Type foo1 = Type()", - "declarations": [], - "spell": "7:8-7:12|3957104924306079513|3|2|-1", - "extent": "7:3-7:21|3957104924306079513|3|0|-1", + "spell": "7:8-7:12|7:3-7:21|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index dfb742c2f..3b960a163 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -17,34 +17,34 @@ Foo::Foo() {} "detailed_name": "Foo::Foo::Foo()", "qual_name_offset": 0, "short_name": "Foo", + "spell": "4:6-4:9|4:1-4:11|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "4:6-4:9|15041163540773201510|2|1026|-1", - "extent": "4:1-4:11|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-1:14|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-1:14|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17319723337446061757], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["4:1-4:4|0|1|4|-1", "4:6-4:9|15041163540773201510|2|4|-1"] + "uses": ["4:1-4:4|4|-1", "4:6-4:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index c285c1d5d..5bc5004b4 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -33,96 +33,96 @@ OUTPUT: make_functions.h "detailed_name": "Foobar::Foobar(int &&, Bar *, bool *)", "qual_name_offset": 0, "short_name": "Foobar", + "spell": "7:3-7:9|7:3-7:32|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "7:3-7:9|14935975554338052500|2|1026|-1", - "extent": "7:3-7:32|14935975554338052500|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 13028995015627606181, "detailed_name": "Foobar::Foobar(int)", "qual_name_offset": 0, "short_name": "Foobar", + "spell": "6:3-6:9|6:3-6:17|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "6:3-6:9|14935975554338052500|2|1026|-1", - "extent": "6:3-6:17|14935975554338052500|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 13131778807733950299, "detailed_name": "Foobar::Foobar()", "qual_name_offset": 0, "short_name": "Foobar", + "spell": "5:3-5:9|5:3-5:14|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "5:3-5:9|14935975554338052500|2|1026|-1", - "extent": "5:3-5:14|14935975554338052500|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 17321436359755983845, "detailed_name": "Foobar::Foobar(int, Bar *, bool *)", "qual_name_offset": 0, "short_name": "Foobar", + "spell": "8:3-8:9|8:3-8:30|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "8:3-8:9|14935975554338052500|2|1026|-1", - "extent": "8:3-8:30|14935975554338052500|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 12993848456528750350, "detailed_name": "struct Bar {}", "qual_name_offset": 7, "short_name": "Bar", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-1:14|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-1:14|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:17-7:20|14935975554338052500|2|4|-1", "8:15-8:18|14935975554338052500|2|4|-1"] + "uses": ["7:17-7:20|4|-1", "8:15-8:18|4|-1"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", "qual_name_offset": 6, "short_name": "Foobar", - "kind": 5, - "declarations": [], - "spell": "3:7-3:13|0|1|2|-1", - "extent": "3:1-9:2|0|1|0|-1", - "alias_of": 0, + "spell": "3:7-3:13|3:1-9:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [13131778807733950299, 13028995015627606181, 3765833212244435302, 17321436359755983845], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:3-5:9|14935975554338052500|2|4|-1", "6:3-6:9|14935975554338052500|2|4|-1", "7:3-7:9|14935975554338052500|2|4|-1", "8:3-8:9|14935975554338052500|2|4|-1"] + "uses": ["5:3-5:9|4|-1", "6:3-6:9|4|-1", "7:3-7:9|4|-1", "8:3-8:9|4|-1"] }], "usr2var": [] } @@ -138,99 +138,103 @@ OUTPUT: make_functions.cc "detailed_name": "", "qual_name_offset": 0, "short_name": "", + "bases": [], + "vars": [2555873744476712860, 2555873744476712860, 2555873744476712860], + "callees": [], "kind": 0, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [2555873744476712860, 2555873744476712860, 2555873744476712860], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 2532818908869373467, "detailed_name": "T *maKE_NoRefs(Args ...args)", "qual_name_offset": 3, "short_name": "maKE_NoRefs", + "spell": "9:4-9:15|9:1-11:2|2|-1", + "bases": [], + "vars": [3908732770590594660], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "9:4-9:15|0|1|2|-1", - "extent": "9:1-11:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [3908732770590594660], - "uses": ["17:3-17:14|2816883305867289955|3|16420|-1"], - "callees": [] + "uses": ["17:3-17:14|16420|-1"] }, { "usr": 2816883305867289955, "detailed_name": "void caller22()", "qual_name_offset": 5, "short_name": "caller22", + "spell": "13:6-13:14|13:1-18:2|2|-1", + "bases": [], + "vars": [], + "callees": ["14:3-14:13|15793662558620604611|3|16420", "15:3-15:13|15793662558620604611|3|16420", "16:3-16:13|15793662558620604611|3|16420", "17:3-17:14|2532818908869373467|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "13:6-13:14|0|1|2|-1", - "extent": "13:1-18:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["14:3-14:13|15793662558620604611|3|16420", "15:3-15:13|15793662558620604611|3|16420", "16:3-16:13|15793662558620604611|3|16420", "17:3-17:14|2532818908869373467|3|16420"] + "uses": [] }, { "usr": 11138976705878544996, "detailed_name": "", "qual_name_offset": 0, "short_name": "", + "bases": [], + "vars": [16395392342608151399], + "callees": [], "kind": 0, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [16395392342608151399], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 11363675606380070883, "detailed_name": "", "qual_name_offset": 0, "short_name": "", + "bases": [], + "vars": [180270746871803062, 180270746871803062, 180270746871803062], + "callees": [], "kind": 0, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [180270746871803062, 180270746871803062, 180270746871803062], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 15793662558620604611, "detailed_name": "T *MakeUnique(Args &&...args)", "qual_name_offset": 3, "short_name": "MakeUnique", + "spell": "4:4-4:14|4:1-6:2|2|-1", + "bases": [], + "vars": [8463700030555379526], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "4:4-4:14|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [8463700030555379526], - "uses": ["14:3-14:13|2816883305867289955|3|16420|-1", "15:3-15:13|2816883305867289955|3|16420|-1", "16:3-16:13|2816883305867289955|3|16420|-1"], - "callees": [] + "uses": ["14:3-14:13|16420|-1", "15:3-15:13|16420|-1", "16:3-16:13|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [180270746871803062], "uses": [] }, { @@ -238,14 +242,15 @@ OUTPUT: make_functions.cc "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [180270746871803062], "uses": [] }, { @@ -253,92 +258,94 @@ OUTPUT: make_functions.cc "detailed_name": "struct Bar {}", "qual_name_offset": 7, "short_name": "Bar", - "kind": 23, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["16:29-16:32|2816883305867289955|3|4|-1", "17:30-17:33|2816883305867289955|3|4|-1"] + "uses": ["16:29-16:32|4|-1", "17:30-17:33|4|-1"] }, { "usr": 14935975554338052500, "detailed_name": "class Foobar {}", "qual_name_offset": 6, "short_name": "Foobar", - "kind": 5, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["14:14-14:20|2816883305867289955|3|4|-1", "15:14-15:20|2816883305867289955|3|4|-1", "16:14-16:20|2816883305867289955|3|4|-1", "17:15-17:21|2816883305867289955|3|4|-1"] + "uses": ["14:14-14:20|4|-1", "15:14-15:20|4|-1", "16:14-16:20|4|-1", "17:15-17:21|4|-1"] }], "usr2var": [{ "usr": 180270746871803062, "detailed_name": "int args", "qual_name_offset": 4, "short_name": "args", - "declarations": [], - "spell": "9:24-9:28|11363675606380070883|3|1026|-1", - "extent": "9:16-9:28|11363675606380070883|3|0|-1", + "spell": "9:24-9:28|9:16-9:28|1026|-1", "type": 87, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 2555873744476712860, "detailed_name": "int &&args", "qual_name_offset": 6, "short_name": "args", - "declarations": [], - "spell": "4:25-4:29|768523651983844320|3|1026|-1", - "extent": "4:15-4:29|768523651983844320|3|0|-1", + "spell": "4:25-4:29|4:15-4:29|1026|-1", "type": 0, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 3908732770590594660, "detailed_name": "Args ...args", "qual_name_offset": 8, "short_name": "args", - "declarations": [], - "spell": "9:24-9:28|2532818908869373467|3|1026|-1", - "extent": "9:16-9:28|2532818908869373467|3|0|-1", + "spell": "9:24-9:28|9:16-9:28|1026|-1", "type": 0, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 8463700030555379526, "detailed_name": "Args &&...args", "qual_name_offset": 10, "short_name": "args", - "declarations": [], - "spell": "4:25-4:29|15793662558620604611|3|1026|-1", - "extent": "4:15-4:29|15793662558620604611|3|0|-1", + "spell": "4:25-4:29|4:15-4:29|1026|-1", "type": 0, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16395392342608151399, "detailed_name": "int &&args", "qual_name_offset": 6, "short_name": "args", - "declarations": [], - "spell": "4:25-4:29|11138976705878544996|3|1026|-1", - "extent": "4:15-4:29|11138976705878544996|3|0|-1", + "spell": "4:25-4:29|4:15-4:29|1026|-1", "type": 0, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index 51a356771..ee90a78bf 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -16,16 +16,16 @@ class Foo; "detailed_name": "class Foo", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": ["1:7-1:10|1:1-1:10|0|1|1|-1", "2:7-2:10|2:1-2:10|0|1|1|-1", "4:7-4:10|4:1-4:10|0|1|1|-1"], - "spell": "3:7-3:10|0|1|2|-1", - "extent": "3:1-3:13|0|1|0|-1", - "alias_of": 0, + "spell": "3:7-3:10|3:1-3:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["1:7-1:10|1:1-1:10|1|-1", "2:7-2:10|2:1-2:10|1|-1", "4:7-4:10|4:1-4:10|1|-1"], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/declaration_vs_definition/class_member.cc b/index_tests/declaration_vs_definition/class_member.cc index ef14ac7be..0099e070e 100644 --- a/index_tests/declaration_vs_definition/class_member.cc +++ b/index_tests/declaration_vs_definition/class_member.cc @@ -13,14 +13,15 @@ class Foo { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [9736582033442720743], "uses": [] }, { @@ -28,19 +29,19 @@ class Foo { "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 9736582033442720743, "R": 0 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -49,13 +50,13 @@ class Foo { "detailed_name": "int Foo::foo", "qual_name_offset": 4, "short_name": "foo", - "declarations": [], - "spell": "2:7-2:10|15041163540773201510|2|1026|-1", - "extent": "2:3-2:10|15041163540773201510|2|0|-1", + "spell": "2:7-2:10|2:3-2:10|1026|-1", "type": 53, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 4655b4be4..6e7951e91 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -15,14 +15,15 @@ int Foo::foo; "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [8942920329766232482, 8942920329766232482], "uses": [] }, { @@ -30,31 +31,31 @@ int Foo::foo; "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:5-5:8|0|1|4|-1"] + "uses": ["5:5-5:8|4|-1"] }], "usr2var": [{ "usr": 8942920329766232482, "detailed_name": "static int Foo::foo", "qual_name_offset": 11, "short_name": "foo", - "declarations": ["2:14-2:17|2:3-2:17|15041163540773201510|2|1025|-1"], - "spell": "5:10-5:13|15041163540773201510|2|1026|-1", - "extent": "5:1-5:13|15041163540773201510|2|0|-1", + "spell": "5:10-5:13|5:1-5:13|1026|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 5, + "storage": 2, + "declarations": ["2:14-2:17|2:3-2:17|1025|-1"], + "uses": [] }] } */ diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index aacda01c1..f1ad37498 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -14,16 +14,16 @@ void foo(); "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-3:14|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1", "2:6-2:9|2:1-2:11|0|1|1|-1", "4:6-4:9|4:1-4:11|0|1|1|-1"], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-3:14|0|1|0|-1", - "bases": [], + "declarations": ["1:6-1:9|1:1-1:11|1|-1", "2:6-2:9|2:1-2:11|1|-1", "4:6-4:9|4:1-4:11|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index 0aa1487ee..fbf17f3a8 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -14,30 +14,31 @@ int foo(int a, int b) { return 0; } "detailed_name": "int foo(int, int)", "qual_name_offset": 4, "short_name": "foo", + "spell": "5:5-5:8|5:1-5:36|2|-1", + "bases": [], + "vars": [14555488990109936920, 10963664335057337329], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:5-1:8|1:1-1:18|0|1|1|-1", "2:5-2:8|2:1-3:16|0|1|1|-1", "4:5-4:8|4:1-4:26|0|1|1|-1"], - "spell": "5:5-5:8|0|1|2|-1", - "extent": "5:1-5:36|0|1|0|-1", - "bases": [], + "declarations": ["1:5-1:8|1:1-1:18|1|-1", "2:5-2:8|2:1-3:16|1|-1", "4:5-4:8|4:1-4:26|1|-1"], "derived": [], - "vars": [14555488990109936920, 10963664335057337329], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [14555488990109936920, 10963664335057337329], "uses": [] }], @@ -46,25 +47,25 @@ int foo(int a, int b) { return 0; } "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", - "declarations": [], - "spell": "5:20-5:21|2747674671862363334|3|1026|-1", - "extent": "5:16-5:21|2747674671862363334|3|0|-1", + "spell": "5:20-5:21|5:16-5:21|1026|-1", "type": 53, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 14555488990109936920, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "5:13-5:14|2747674671862363334|3|1026|-1", - "extent": "5:9-5:14|2747674671862363334|3|0|-1", + "spell": "5:13-5:14|5:9-5:14|1026|-1", "type": 53, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index da2b46fb9..ef280fdbd 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -16,60 +16,62 @@ void Foo::def() {} "detailed_name": "void Foo::declonly()", "qual_name_offset": 5, "short_name": "declonly", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:8-2:16|2:3-2:18|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["2:8-2:16|2:3-2:18|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 10939323144126021546, "detailed_name": "virtual void Foo::purevirtual() = 0", "qual_name_offset": 13, "short_name": "purevirtual", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["3:16-3:27|3:3-3:33|15041163540773201510|2|1089|-1"], - "bases": [], + "declarations": ["3:16-3:27|3:3-3:33|1089|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 15416083548883122431, "detailed_name": "void Foo::def()", "qual_name_offset": 5, "short_name": "def", + "spell": "7:11-7:14|7:1-7:19|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["4:8-4:11|4:3-4:13|15041163540773201510|2|1025|-1"], - "spell": "7:11-7:14|15041163540773201510|2|1026|-1", - "extent": "7:1-7:19|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["4:8-4:11|4:3-4:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [4012226004228259562, 10939323144126021546, 15416083548883122431], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:6-7:9|0|1|4|-1"] + "uses": ["7:6-7:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index a31baff5d..a49e0ed17 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -15,16 +15,16 @@ enum class Foo : uint8_t { "detailed_name": "typedef unsigned char uint8_t", "qual_name_offset": 22, "short_name": "uint8_t", - "kind": 252, - "declarations": [], - "spell": "1:23-1:30|0|1|2|-1", - "extent": "1:1-1:30|0|1|0|-1", - "alias_of": 0, + "spell": "1:23-1:30|1:1-1:30|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -32,16 +32,16 @@ enum class Foo : uint8_t { "detailed_name": "enum class Foo : uint8_t {}", "qual_name_offset": 11, "short_name": "Foo", - "kind": 10, - "declarations": [], - "spell": "2:12-2:15|0|1|2|-1", - "extent": "2:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:12-2:15|2:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -51,25 +51,25 @@ enum class Foo : uint8_t { "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", - "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026|-1", - "extent": "3:3-3:4|16985894625255407295|2|0|-1", + "spell": "3:3-3:4|3:3-3:4|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15962370213938840720, "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "declarations": [], - "spell": "4:3-4:4|16985894625255407295|2|1026|-1", - "extent": "4:3-4:9|16985894625255407295|2|0|-1", + "spell": "4:3-4:4|4:3-4:9|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index bf760444e..16697d86b 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -14,16 +14,16 @@ enum Foo { "detailed_name": "enum Foo {}", "qual_name_offset": 5, "short_name": "Foo", - "kind": 10, - "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:9|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -33,25 +33,25 @@ enum Foo { "qual_name_offset": 0, "short_name": "A", "hover": "A = 0", - "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026|-1", - "extent": "2:3-2:4|16985894625255407295|2|0|-1", + "spell": "2:3-2:4|2:3-2:4|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15962370213938840720, "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026|-1", - "extent": "3:3-3:9|16985894625255407295|2|0|-1", + "spell": "3:3-3:4|3:3-3:9|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 18cb37c06..3bf68d52b 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -21,16 +21,16 @@ enum class E : int32_t { "detailed_name": "enum class E : int32_t {}", "qual_name_offset": 11, "short_name": "E", - "kind": 10, - "declarations": [], - "spell": "8:12-8:13|0|1|2|-1", - "extent": "8:1-11:2|0|1|0|-1", - "alias_of": 0, + "spell": "8:12-8:13|8:1-11:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -38,16 +38,16 @@ enum class E : int32_t { "detailed_name": "typedef int int32_t", "qual_name_offset": 12, "short_name": "int32_t", - "kind": 252, - "declarations": [], - "spell": "6:13-6:20|0|1|2|-1", - "extent": "6:1-6:20|0|1|0|-1", - "alias_of": 0, + "spell": "6:13-6:20|6:1-6:20|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -55,16 +55,16 @@ enum class E : int32_t { "detailed_name": "enum Foo : int {}", "qual_name_offset": 5, "short_name": "Foo", - "kind": 10, - "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:9|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -74,50 +74,50 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "A", "hover": "A = 0", - "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026|-1", - "extent": "2:3-2:4|16985894625255407295|2|0|-1", + "spell": "2:3-2:4|2:3-2:4|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15962370213938840720, "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026|-1", - "extent": "3:3-3:9|16985894625255407295|2|0|-1", + "spell": "3:3-3:4|3:3-3:9|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16614320383091394267, "detailed_name": "E::E0", "qual_name_offset": 0, "short_name": "E0", "hover": "E::E0 = 0", - "declarations": [], - "spell": "9:3-9:5|2986879766914123941|2|1026|-1", - "extent": "9:3-9:5|2986879766914123941|2|0|-1", + "spell": "9:3-9:5|9:3-9:5|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16847439761518576294, "detailed_name": "E::E20 = 20", "qual_name_offset": 0, "short_name": "E20", - "declarations": [], - "spell": "10:3-10:6|2986879766914123941|2|1026|-1", - "extent": "10:3-10:11|2986879766914123941|2|0|-1", + "spell": "10:3-10:6|10:3-10:11|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index 07475c77f..9d3037107 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -16,18 +16,18 @@ Foo x = Foo::A; "detailed_name": "enum class Foo : int {}", "qual_name_offset": 11, "short_name": "Foo", - "kind": 10, - "declarations": [], - "spell": "1:12-1:15|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:12-1:15|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [10677751717622394455], - "uses": ["6:1-6:4|0|1|4|-1", "6:9-6:12|0|1|4|-1"] + "uses": ["6:1-6:4|4|-1", "6:9-6:12|4|-1"] }], "usr2var": [{ "usr": 439339022761937396, @@ -35,38 +35,38 @@ Foo x = Foo::A; "qual_name_offset": 0, "short_name": "A", "hover": "Foo::A = 0", - "declarations": [], - "spell": "2:3-2:4|16985894625255407295|2|1026|-1", - "extent": "2:3-2:4|16985894625255407295|2|0|-1", + "spell": "2:3-2:4|2:3-2:4|1026|-1", "type": 0, - "uses": ["6:14-6:15|0|1|4|-1"], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": ["6:14-6:15|4|-1"] }, { "usr": 10677751717622394455, "detailed_name": "Foo x", "qual_name_offset": 4, "short_name": "x", "hover": "Foo x = Foo::A", - "declarations": [], - "spell": "6:5-6:6|0|1|2|-1", - "extent": "6:1-6:15|0|1|0|-1", + "spell": "6:5-6:6|6:1-6:15|2|-1", "type": 16985894625255407295, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15962370213938840720, "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "declarations": [], - "spell": "3:3-3:4|16985894625255407295|2|1026|-1", - "extent": "3:3-3:9|16985894625255407295|2|0|-1", + "spell": "3:3-3:4|3:3-3:9|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc index 4b9d2f65f..6337f1eff 100644 --- a/index_tests/foobar.cc +++ b/index_tests/foobar.cc @@ -19,94 +19,94 @@ Foo b; "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", - "kind": 10, - "declarations": [], - "spell": "1:6-1:7|0|1|2|-1", - "extent": "1:1-1:10|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:7|1:1-1:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["9:5-9:6|0|1|4|-1"] + "uses": ["9:5-9:6|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "5:8-5:11|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "alias_of": 0, + "spell": "5:8-5:11|5:1-7:2|2|-1", "bases": [], - "derived": [], - "types": [13938528237873543349], "funcs": [], + "types": [13938528237873543349], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12028309045033782423], - "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] + "uses": ["9:1-9:4|4|-1", "10:1-10:4|4|-1"] }, { "usr": 13892793056005362145, "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", - "kind": 10, - "declarations": [], - "spell": "2:6-2:7|0|1|2|-1", - "extent": "2:1-2:10|0|1|0|-1", - "alias_of": 0, + "spell": "2:6-2:7|2:1-2:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:5-10:6|0|1|4|-1"] + "uses": ["10:5-10:6|4|-1"] }, { "usr": 13938528237873543349, "detailed_name": "struct Foo::Inner {}", "qual_name_offset": 7, "short_name": "Inner", - "kind": 23, - "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|1026|-1", - "extent": "6:3-6:18|10528472276654770367|2|0|-1", - "alias_of": 0, + "spell": "6:10-6:15|6:3-6:18|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 23, + "declarations": [], + "derived": [], "instances": [16721564935990383768], - "uses": ["9:9-9:14|0|1|4|-1"] + "uses": ["9:9-9:14|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, "detailed_name": "Foo b", "qual_name_offset": 7, "short_name": "b", - "declarations": [], - "spell": "10:8-10:9|0|1|2|-1", - "extent": "10:1-10:9|0|1|0|-1", + "spell": "10:8-10:9|10:1-10:9|2|-1", "type": 10528472276654770367, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", "qual_name_offset": 14, "short_name": "a", - "declarations": [], - "spell": "9:15-9:16|0|1|2|-1", - "extent": "9:1-9:16|0|1|0|-1", + "spell": "9:15-9:16|9:1-9:16|2|-1", "type": 13938528237873543349, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/function_declaration.cc b/index_tests/function_declaration.cc index 9c38f5741..49225d2f3 100644 --- a/index_tests/function_declaration.cc +++ b/index_tests/function_declaration.cc @@ -10,14 +10,15 @@ void foo(int a, int b); "detailed_name": "void foo(int a, int b)", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:9|1:1-1:23|0|1|1|-1"], - "bases": [], + "declarations": ["1:6-1:9|1:1-1:23|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index 1eb2ba755..5350dbc2b 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -12,16 +12,16 @@ void foo() {} "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-3:14|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1"], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-3:14|0|1|0|-1", - "bases": [], + "declarations": ["1:6-1:9|1:1-1:11|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/function_definition.cc b/index_tests/function_definition.cc index 7ceee6367..2176a6584 100644 --- a/index_tests/function_definition.cc +++ b/index_tests/function_definition.cc @@ -10,16 +10,16 @@ void foo() {} "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-1:14|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-1:14|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/inheritance/class_inherit.cc b/index_tests/inheritance/class_inherit.cc index 701b03966..791d98654 100644 --- a/index_tests/inheritance/class_inherit.cc +++ b/index_tests/inheritance/class_inherit.cc @@ -12,33 +12,33 @@ class Derived : public Parent {}; "detailed_name": "class Parent {}", "qual_name_offset": 6, "short_name": "Parent", - "kind": 5, - "declarations": [], - "spell": "1:7-1:13|0|1|2|-1", - "extent": "1:1-1:16|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:13|1:1-1:16|2|-1", "bases": [], - "derived": [10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["2:24-2:30|10963370434658308541|2|2052|-1"] + "uses": ["2:24-2:30|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Parent {}", "qual_name_offset": 6, "short_name": "Derived", - "kind": 5, - "declarations": [], - "spell": "2:7-2:14|0|1|2|-1", - "extent": "2:1-2:33|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:14|2:1-2:33|2|-1", "bases": [3866412049634585509], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 4e20cd1b8..4e3f5bded 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -23,86 +23,86 @@ class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}; "detailed_name": "class Derived1 : Base1 {}", "qual_name_offset": 6, "short_name": "Derived1", - "kind": 5, - "declarations": [], - "spell": "8:7-8:15|0|1|2|-1", - "extent": "8:1-8:29|0|1|0|-1", - "alias_of": 0, + "spell": "8:7-8:15|8:1-8:29|2|-1", "bases": [11930058224338108382], - "derived": [10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["13:43-13:51|10963370434658308541|2|2052|-1"] + "uses": ["13:43-13:51|2052|-1"] }, { "usr": 10651399730831737929, "detailed_name": "class Derived2 : Base2 {}", "qual_name_offset": 6, "short_name": "Derived2", - "kind": 5, - "declarations": [], - "spell": "11:7-11:15|0|1|2|-1", - "extent": "11:1-11:29|0|1|0|-1", - "alias_of": 0, + "spell": "11:7-11:15|11:1-11:29|2|-1", "bases": [11118288764693061434], - "derived": [10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["13:56-13:64|10963370434658308541|2|2052|-1"] + "uses": ["13:56-13:64|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : Base1<3>, Base2, Derived1<4>, Derived2 {}", "qual_name_offset": 6, "short_name": "Derived", - "kind": 5, - "declarations": [], - "spell": "13:7-13:14|0|1|2|-1", - "extent": "13:1-13:76|0|1|0|-1", - "alias_of": 0, + "spell": "13:7-13:14|13:1-13:76|2|-1", "bases": [11930058224338108382, 11118288764693061434, 5863733211528032190, 10651399730831737929], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["13:33-13:40|10963370434658308541|2|2052|-1", "13:65-13:72|10963370434658308541|2|2052|-1"] + "uses": ["13:33-13:40|2052|-1", "13:65-13:72|2052|-1"] }, { "usr": 11118288764693061434, "detailed_name": "class Base2 {}", "qual_name_offset": 6, "short_name": "Base2", - "kind": 5, - "declarations": [], - "spell": "5:7-5:12|0|1|2|-1", - "extent": "5:1-5:15|0|1|0|-1", - "alias_of": 0, + "spell": "5:7-5:12|5:1-5:15|2|-1", "bases": [], - "derived": [10651399730831737929, 10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10651399730831737929, 10963370434658308541], "instances": [], - "uses": ["13:27-13:32|10963370434658308541|2|2052|-1"] + "uses": ["11:18-11:23|2052|-1", "13:27-13:32|2052|-1"] }, { "usr": 11930058224338108382, "detailed_name": "class Base1 {}", "qual_name_offset": 6, "short_name": "Base1", - "kind": 5, - "declarations": [], - "spell": "2:7-2:12|0|1|2|-1", - "extent": "2:1-2:15|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:12|2:1-2:15|2|-1", "bases": [], - "derived": [5863733211528032190, 10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [5863733211528032190, 10963370434658308541], "instances": [], - "uses": ["13:17-13:22|10963370434658308541|2|2052|-1"] + "uses": ["8:18-8:23|2052|-1", "13:17-13:22|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/inheritance/class_multiple_inherit.cc b/index_tests/inheritance/class_multiple_inherit.cc index f8e171a2b..49b09501f 100644 --- a/index_tests/inheritance/class_multiple_inherit.cc +++ b/index_tests/inheritance/class_multiple_inherit.cc @@ -14,33 +14,33 @@ class Derived : public MiddleA, public MiddleB {}; "detailed_name": "class Root {}", "qual_name_offset": 6, "short_name": "Root", - "kind": 5, - "declarations": [], - "spell": "1:7-1:11|0|1|2|-1", - "extent": "1:1-1:14|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:11|1:1-1:14|2|-1", "bases": [], - "derived": [11863524815063131483, 14022569716337624303], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [11863524815063131483, 14022569716337624303], "instances": [], - "uses": ["2:24-2:28|11863524815063131483|2|2052|-1", "3:24-3:28|14022569716337624303|2|2052|-1"] + "uses": ["2:24-2:28|2052|-1", "3:24-3:28|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public MiddleA, public MiddleB {}", "qual_name_offset": 6, "short_name": "Derived", - "kind": 5, - "declarations": [], - "spell": "4:7-4:14|0|1|2|-1", - "extent": "4:1-4:50|0|1|0|-1", - "alias_of": 0, + "spell": "4:7-4:14|4:1-4:50|2|-1", "bases": [11863524815063131483, 14022569716337624303], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -48,35 +48,35 @@ class Derived : public MiddleA, public MiddleB {}; "detailed_name": "class MiddleA : public Root {}", "qual_name_offset": 6, "short_name": "MiddleA", - "kind": 5, - "declarations": [], - "spell": "2:7-2:14|0|1|2|-1", - "extent": "2:1-2:31|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:14|2:1-2:31|2|-1", "bases": [3897841498936210886], - "derived": [10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["4:24-4:31|10963370434658308541|2|2052|-1"] + "uses": ["4:24-4:31|2052|-1"] }, { "usr": 14022569716337624303, "detailed_name": "class MiddleB : public Root {}", "qual_name_offset": 6, "short_name": "MiddleB", - "kind": 5, - "declarations": [], - "spell": "3:7-3:14|0|1|2|-1", - "extent": "3:1-3:31|0|1|0|-1", - "alias_of": 0, + "spell": "3:7-3:14|3:1-3:31|2|-1", "bases": [3897841498936210886], - "derived": [10963370434658308541], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["4:40-4:47|10963370434658308541|2|2052|-1"] + "uses": ["4:40-4:47|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/inheritance/function_override.cc b/index_tests/inheritance/function_override.cc index 14a5661a7..319b43946 100644 --- a/index_tests/inheritance/function_override.cc +++ b/index_tests/inheritance/function_override.cc @@ -15,62 +15,63 @@ class Derived : public Root { "detailed_name": "void Derived::foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "5:8-5:11|5:3-5:25|5186|-1", + "bases": [9948027785633571339], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "5:8-5:11|10963370434658308541|2|5186|-1", - "extent": "5:3-5:25|10963370434658308541|2|0|-1", - "bases": [9948027785633571339], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 9948027785633571339, "detailed_name": "virtual void Root::foo()", "qual_name_offset": 13, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:16-2:19|2:3-2:21|3897841498936210886|2|1089|-1"], - "bases": [], + "declarations": ["2:16-2:19|2:3-2:21|1089|-1"], "derived": [6666242542855173890], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 3897841498936210886, "detailed_name": "class Root {}", "qual_name_offset": 6, "short_name": "Root", - "kind": 5, - "declarations": [], - "spell": "1:7-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [10963370434658308541], - "types": [], "funcs": [9948027785633571339], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["4:24-4:28|10963370434658308541|2|2052|-1"] + "uses": ["4:24-4:28|2052|-1"] }, { "usr": 10963370434658308541, "detailed_name": "class Derived : public Root {}", "qual_name_offset": 6, "short_name": "Derived", - "kind": 5, - "declarations": [], - "spell": "4:7-4:14|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "alias_of": 0, + "spell": "4:7-4:14|4:1-6:2|2|-1", "bases": [3897841498936210886], - "derived": [], - "types": [], "funcs": [6666242542855173890], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/inheritance/interface_pure_virtual.cc b/index_tests/inheritance/interface_pure_virtual.cc index 58ee1d4fb..fcf9841f5 100644 --- a/index_tests/inheritance/interface_pure_virtual.cc +++ b/index_tests/inheritance/interface_pure_virtual.cc @@ -12,30 +12,31 @@ class IFoo { "detailed_name": "virtual void IFoo::foo() = 0", "qual_name_offset": 13, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:16-2:19|2:3-2:25|9949214233977131946|2|1089|-1"], - "bases": [], + "declarations": ["2:16-2:19|2:3-2:25|1089|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 9949214233977131946, "detailed_name": "class IFoo {}", "qual_name_offset": 6, "short_name": "IFoo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [3277829753446788562], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 76cd27eef..f4ef3c4a2 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -18,98 +18,98 @@ struct Derived : Base0, Base1 { "detailed_name": "virtual Base1::~Base1() noexcept", "qual_name_offset": 8, "short_name": "~Base1", + "spell": "5:11-5:17|5:3-5:23|1090|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "5:11-5:17|15826803741381445676|2|1090|-1", - "extent": "5:3-5:23|15826803741381445676|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 13164726294460837993, "detailed_name": "Derived::~Derived() noexcept", "qual_name_offset": 0, "short_name": "~Derived", + "spell": "8:3-8:11|8:3-8:26|5186|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "8:3-8:11|10963370434658308541|2|5186|-1", - "extent": "8:3-8:26|10963370434658308541|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 16347272523198263017, "detailed_name": "virtual Base0::~Base0() noexcept", "qual_name_offset": 8, "short_name": "~Base0", + "spell": "2:11-2:17|2:3-2:23|1090|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "2:11-2:17|11628904180681204356|2|1090|-1", - "extent": "2:3-2:23|11628904180681204356|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 10963370434658308541, "detailed_name": "struct Derived : Base0, Base1 {}", "qual_name_offset": 7, "short_name": "Derived", - "kind": 23, - "declarations": [], - "spell": "7:8-7:15|0|1|2|-1", - "extent": "7:1-9:2|0|1|0|-1", - "alias_of": 0, + "spell": "7:8-7:15|7:1-9:2|2|-1", "bases": [11628904180681204356, 15826803741381445676], - "derived": [], - "types": [], "funcs": [13164726294460837993], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["8:4-8:11|10963370434658308541|2|4|-1"] + "uses": ["8:4-8:11|4|-1"] }, { "usr": 11628904180681204356, "detailed_name": "struct Base0 {}", "qual_name_offset": 7, "short_name": "Base0", - "kind": 23, - "declarations": [], - "spell": "1:8-1:13|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:13|1:1-3:2|2|-1", "bases": [], - "derived": [10963370434658308541], - "types": [], "funcs": [16347272523198263017], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["2:12-2:17|11628904180681204356|2|4|-1", "7:18-7:23|10963370434658308541|2|2052|-1"] + "uses": ["2:12-2:17|4|-1", "7:18-7:23|2052|-1"] }, { "usr": 15826803741381445676, "detailed_name": "struct Base1 {}", "qual_name_offset": 7, "short_name": "Base1", - "kind": 23, - "declarations": [], - "spell": "4:8-4:13|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "alias_of": 0, + "spell": "4:8-4:13|4:1-6:2|2|-1", "bases": [], - "derived": [10963370434658308541], - "types": [], "funcs": [8401779086123965305], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [10963370434658308541], "instances": [], - "uses": ["5:12-5:17|15826803741381445676|2|4|-1", "7:25-7:30|10963370434658308541|2|2052|-1"] + "uses": ["5:12-5:17|4|-1", "7:25-7:30|2052|-1"] }], "usr2var": [] } diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index b4e58a30e..059d148b8 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -21,43 +21,45 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-12:2|2|-1", + "bases": [], + "vars": [12666114896600231317, 2981279427664991319], + "callees": ["9:14-9:15|17926497908620168464|3|16420", "10:14-10:15|17926497908620168464|3|16420", "11:14-11:15|17926497908620168464|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-12:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [12666114896600231317, 2981279427664991319], - "uses": [], - "callees": ["9:14-9:15|17926497908620168464|3|16420", "10:14-10:15|17926497908620168464|3|16420", "11:14-11:15|17926497908620168464|3|16420"] + "uses": [] }, { "usr": 17926497908620168464, "detailed_name": "inline void foo()::(anon class)::operator()(int y) const", "qual_name_offset": 12, "short_name": "operator()", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [], - "uses": ["9:14-9:15|4259594751088586730|3|16420|-1", "10:14-10:15|4259594751088586730|3|16420|-1", "11:14-11:15|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["9:14-9:15|16420|-1", "10:14-10:15|16420|-1", "11:14-11:15|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12666114896600231317], "uses": [] }, { @@ -65,14 +67,15 @@ void foo() { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2981279427664991319], "uses": [] }], @@ -82,37 +85,37 @@ void foo() { "qual_name_offset": 9, "short_name": "dosomething", "hover": "(lambda) dosomething", - "declarations": [], - "spell": "4:8-4:19|4259594751088586730|3|2|-1", - "extent": "4:3-7:4|4259594751088586730|3|0|-1", + "spell": "4:8-4:19|4:3-7:4|2|-1", "type": 14635009347499519042, - "uses": ["9:3-9:14|4259594751088586730|3|4|-1", "10:3-10:14|4259594751088586730|3|4|-1", "11:3-11:14|4259594751088586730|3|4|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["9:3-9:14|4|-1", "10:3-10:14|4|-1", "11:3-11:14|4|-1"] }, { "usr": 12666114896600231317, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", - "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2|-1", - "extent": "2:3-2:8|4259594751088586730|3|0|-1", + "spell": "2:7-2:8|2:3-2:8|2|-1", "type": 53, - "uses": ["4:24-4:25|4259594751088586730|3|4|-1", "5:7-5:8|4259594751088586730|3|28|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["4:24-4:25|4|-1", "5:7-5:8|28|-1"] }, { "usr": 12879188959314906706, "detailed_name": "int y", "qual_name_offset": 4, "short_name": "y", - "declarations": [], - "spell": "4:31-4:32|17926497908620168464|3|2|-1", - "extent": "4:27-4:32|4259594751088586730|3|0|-1", + "spell": "4:31-4:32|4:27-4:32|2|-1", "type": 0, - "uses": ["6:7-6:8|4259594751088586730|3|28|-1"], "kind": 253, - "storage": 0 + "parent_kind": 6, + "storage": 0, + "declarations": [], + "uses": ["6:7-6:8|28|-1"] }] } */ diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index b88c3eaa7..413886651 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -21,45 +21,46 @@ FOO(make1(), make2); "detailed_name": "int a()", "qual_name_offset": 4, "short_name": "a", + "spell": "12:1-12:20|12:1-12:20|2|-1", + "bases": [], + "vars": [], + "callees": ["12:5-12:10|14400399977994209582|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["12:1-12:20|12:1-12:20|0|1|1|-1"], - "spell": "12:1-12:20|0|1|2|-1", - "extent": "12:1-12:20|0|1|0|-1", - "bases": [], + "declarations": ["12:1-12:20|12:1-12:20|1|-1"], "derived": [], - "vars": [], - "uses": ["2:7-2:8|0|1|64|0", "3:7-3:8|0|1|64|0"], - "callees": ["12:5-12:10|14400399977994209582|3|16420"] + "uses": ["2:7-2:8|64|0", "3:7-3:8|64|0"] }, { "usr": 14400399977994209582, "detailed_name": "int make1()", "qual_name_offset": 4, "short_name": "make1", + "spell": "6:5-6:10|6:1-8:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "6:5-6:10|0|1|2|-1", - "extent": "6:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["12:5-12:10|9720930732776154610|3|16420|-1", "12:5-12:10|0|1|64|0"], - "callees": [] + "uses": ["12:5-12:10|16420|-1", "12:5-12:10|64|0"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2878407290385495202], "uses": [] }], @@ -69,26 +70,26 @@ FOO(make1(), make2); "qual_name_offset": 10, "short_name": "make2", "hover": "const int make2 = 5", - "declarations": [], - "spell": "9:11-9:16|0|1|2|-1", - "extent": "9:1-9:20|0|1|0|-1", + "spell": "9:11-9:16|9:1-9:20|2|-1", "type": 53, - "uses": ["12:14-12:19|9720930732776154610|3|12|-1", "12:14-12:19|0|1|64|0"], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": ["12:14-12:19|12|-1", "12:14-12:19|64|0"] }, { "usr": 14219599523415845943, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO(aaa, bbb) \\\n int a();\\\n int a() { return aaa + bbb; }", - "declarations": [], - "spell": "1:9-1:12|0|1|2|-1", - "extent": "1:9-3:32|0|1|0|-1", + "spell": "1:9-1:12|1:9-3:32|2|-1", "type": 0, - "uses": ["12:1-12:4|0|1|64|-1"], "kind": 255, - "storage": 0 + "parent_kind": 1, + "storage": 0, + "declarations": [], + "uses": ["12:1-12:4|64|-1"] }] } */ \ No newline at end of file diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index 156ab2373..c8744e745 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -17,30 +17,31 @@ int x = A; "detailed_name": "Foo::Foo(Foo &&) = delete", "qual_name_offset": 0, "short_name": "Foo", + "spell": "5:12-5:15|5:12-5:15|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "5:12-5:15|15041163540773201510|2|1026|-1", - "extent": "5:12-5:15|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["5:12-5:15|0|1|64|0"], - "callees": [] + "uses": ["5:12-5:15|64|0"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [10677751717622394455], "uses": [] }, { @@ -48,18 +49,18 @@ int x = A; "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "4:8-4:11|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "alias_of": 0, + "spell": "4:8-4:11|4:1-6:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [13788753348312146871], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:12-5:15|15041163540773201510|2|4|-1", "5:12-5:15|0|1|64|0"] + "uses": ["5:12-5:15|4|-1", "5:12-5:15|64|0"] }], "usr2var": [{ "usr": 1569772797058982873, @@ -67,39 +68,39 @@ int x = A; "qual_name_offset": 0, "short_name": "A", "hover": "#define A 5", - "declarations": [], - "spell": "1:9-1:10|0|1|2|-1", - "extent": "1:9-1:12|0|1|0|-1", + "spell": "1:9-1:10|1:9-1:12|2|-1", "type": 0, - "uses": ["8:9-8:10|0|1|64|-1"], "kind": 255, - "storage": 0 + "parent_kind": 1, + "storage": 0, + "declarations": [], + "uses": ["8:9-8:10|64|-1"] }, { "usr": 4904139678698066671, "detailed_name": "DISALLOW", "qual_name_offset": 0, "short_name": "DISALLOW", "hover": "#define DISALLOW(type) type(type&&) = delete;", - "declarations": [], - "spell": "2:9-2:17|0|1|2|-1", - "extent": "2:9-2:46|0|1|0|-1", + "spell": "2:9-2:17|2:9-2:46|2|-1", "type": 0, - "uses": ["5:3-5:11|0|1|64|-1"], "kind": 255, - "storage": 0 + "parent_kind": 1, + "storage": 0, + "declarations": [], + "uses": ["5:3-5:11|64|-1"] }, { "usr": 10677751717622394455, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", "hover": "int x = A", - "declarations": [], - "spell": "8:5-8:6|0|1|2|-1", - "extent": "8:1-1:1|0|1|0|-1", + "spell": "8:5-8:6|8:1-1:1|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/method_declaration.cc b/index_tests/method_declaration.cc index fae12cdc6..c777fa497 100644 --- a/index_tests/method_declaration.cc +++ b/index_tests/method_declaration.cc @@ -16,30 +16,31 @@ class Foo { "detailed_name": "void Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:8-2:11|2:3-2:13|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["2:8-2:11|2:3-2:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17922201480358737771], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 895eac04d..94ff8e564 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -14,34 +14,34 @@ void Foo::foo() const {} "detailed_name": "void Foo::foo() const", "qual_name_offset": 5, "short_name": "foo", + "spell": "5:11-5:14|5:1-5:25|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["2:8-2:11|2:3-2:19|15041163540773201510|2|1025|-1"], - "spell": "5:11-5:14|15041163540773201510|2|1026|-1", - "extent": "5:1-5:25|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["2:8-2:11|2:3-2:19|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [6446764306530590711], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:6-5:9|0|1|4|-1"] + "uses": ["5:6-5:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/method_inline_declaration.cc b/index_tests/method_inline_declaration.cc index f2294cd0b..774bac0c0 100644 --- a/index_tests/method_inline_declaration.cc +++ b/index_tests/method_inline_declaration.cc @@ -12,32 +12,32 @@ class Foo { "detailed_name": "void Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "2:8-2:11|2:3-2:16|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "2:8-2:11|15041163540773201510|2|1026|-1", - "extent": "2:3-2:16|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17922201480358737771], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 784f210da..7ceb5e713 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -11,22 +11,7 @@ OUTPUT: funky_enum.h "includes": [], "skipped_ranges": [], "usr2func": [], - "usr2type": [{ - "usr": 16985894625255407295, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": [] - }], + "usr2type": [], "usr2var": [{ "usr": 439339022761937396, "detailed_name": "A", @@ -34,13 +19,13 @@ OUTPUT: funky_enum.h "short_name": "A", "hover": "A = 0", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", - "declarations": [], - "spell": "4:1-4:2|16985894625255407295|2|1026|-1", - "extent": "4:1-4:2|16985894625255407295|2|0|-1", + "spell": "4:1-4:2|4:1-4:2|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 8524995777615948802, "detailed_name": "C", @@ -48,13 +33,13 @@ OUTPUT: funky_enum.h "short_name": "C", "hover": "C = 2", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", - "declarations": [], - "spell": "6:1-6:2|16985894625255407295|2|1026|-1", - "extent": "6:1-6:2|16985894625255407295|2|0|-1", + "spell": "6:1-6:2|6:1-6:2|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15962370213938840720, "detailed_name": "B", @@ -62,13 +47,13 @@ OUTPUT: funky_enum.h "short_name": "B", "hover": "B = 1", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", - "declarations": [], - "spell": "5:1-5:2|16985894625255407295|2|1026|-1", - "extent": "5:1-5:2|16985894625255407295|2|0|-1", + "spell": "5:1-5:2|5:1-5:2|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } OUTPUT: funky_enum.cc @@ -84,16 +69,16 @@ OUTPUT: funky_enum.cc "detailed_name": "enum Foo {}", "qual_name_offset": 5, "short_name": "Foo", - "kind": 10, - "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:9|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index dc754b8cb..927f871b2 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -14,30 +14,31 @@ OUTPUT: header.h "detailed_name": "void Foo1()", "qual_name_offset": 5, "short_name": "Foo1", + "spell": "10:6-10:10|10:1-10:15|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "10:6-10:10|0|1|2|-1", - "extent": "10:1-10:15|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2638219001294786365, 8395885290297540138], "uses": [] }, { @@ -45,16 +46,16 @@ OUTPUT: header.h "detailed_name": "struct Foo2 {}", "qual_name_offset": 7, "short_name": "Foo2", - "kind": 23, - "declarations": [], - "spell": "13:8-13:12|0|1|2|-1", - "extent": "13:1-13:15|0|1|0|-1", - "alias_of": 0, + "spell": "13:8-13:12|13:1-13:15|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -62,16 +63,16 @@ OUTPUT: header.h "detailed_name": "using Foo0 = SameFileDerived", "qual_name_offset": 6, "short_name": "Foo0", - "kind": 252, - "declarations": [], - "spell": "7:7-7:11|0|1|2|-1", - "extent": "7:1-7:29|0|1|0|-1", - "alias_of": 16750616846959666305, + "spell": "7:7-7:11|7:1-7:29|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 16750616846959666305, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -79,16 +80,16 @@ OUTPUT: header.h "detailed_name": "enum Foo3 {}", "qual_name_offset": 5, "short_name": "Foo3", - "kind": 10, - "declarations": [], - "spell": "15:6-15:10|0|1|2|-1", - "extent": "15:1-15:22|0|1|0|-1", - "alias_of": 0, + "spell": "15:6-15:10|15:1-15:22|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -96,99 +97,99 @@ OUTPUT: header.h "detailed_name": "struct Base {}", "qual_name_offset": 7, "short_name": "Base", - "kind": 23, - "declarations": [], - "spell": "3:8-3:12|0|1|2|-1", - "extent": "3:1-3:15|0|1|0|-1", - "alias_of": 0, + "spell": "3:8-3:12|3:1-3:15|2|-1", "bases": [], - "derived": [16750616846959666305], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [16750616846959666305], "instances": [], - "uses": ["5:26-5:30|16750616846959666305|2|2052|-1"] + "uses": ["5:26-5:30|2052|-1"] }, { "usr": 16750616846959666305, "detailed_name": "struct SameFileDerived : Base {}", "qual_name_offset": 7, "short_name": "SameFileDerived", - "kind": 23, - "declarations": [], - "spell": "5:8-5:23|0|1|2|-1", - "extent": "5:1-5:33|0|1|0|-1", - "alias_of": 0, + "spell": "5:8-5:23|5:1-5:33|2|-1", "bases": [8420119006782424779], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:14-7:29|0|1|4|-1"] + "uses": ["7:14-7:29|4|-1"] }], "usr2var": [{ "usr": 2638219001294786365, "detailed_name": "int Foo4", "qual_name_offset": 4, "short_name": "Foo4", - "declarations": [], - "spell": "17:5-17:9|0|1|2|-1", - "extent": "17:1-17:9|0|1|0|-1", + "spell": "17:5-17:9|17:1-17:9|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 6141718166919284735, "detailed_name": "A", "qual_name_offset": 0, "short_name": "A", "hover": "A = 0", - "declarations": [], - "spell": "15:13-15:14|4481210672785600703|2|1026|-1", - "extent": "15:13-15:14|4481210672785600703|2|0|-1", + "spell": "15:13-15:14|15:13-15:14|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 7285646116511901840, "detailed_name": "C", "qual_name_offset": 0, "short_name": "C", "hover": "C = 2", - "declarations": [], - "spell": "15:19-15:20|4481210672785600703|2|1026|-1", - "extent": "15:19-15:20|4481210672785600703|2|0|-1", + "spell": "15:19-15:20|15:19-15:20|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 8395885290297540138, "detailed_name": "static int Foo5", "qual_name_offset": 11, "short_name": "Foo5", - "declarations": [], - "spell": "18:12-18:16|0|1|2|-1", - "extent": "18:1-18:16|0|1|0|-1", + "spell": "18:12-18:16|18:1-18:16|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }, { "usr": 17716334512218775320, "detailed_name": "B", "qual_name_offset": 0, "short_name": "B", "hover": "B = 1", - "declarations": [], - "spell": "15:16-15:17|4481210672785600703|2|1026|-1", - "extent": "15:16-15:17|4481210672785600703|2|0|-1", + "spell": "15:16-15:17|15:16-15:17|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }] } OUTPUT: impl.cc @@ -203,29 +204,30 @@ OUTPUT: impl.cc "detailed_name": "void Impl()", "qual_name_offset": 5, "short_name": "Impl", + "spell": "3:6-3:10|3:1-5:2|2|-1", + "bases": [], + "vars": [], + "callees": ["4:3-4:7|11650481237659640387|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["4:3-4:7|11650481237659640387|3|16420"] + "uses": [] }, { "usr": 11650481237659640387, "detailed_name": "void Foo1()", "qual_name_offset": 5, "short_name": "Foo1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [], - "uses": ["4:3-4:7|5817708529036841195|3|16420|-1"], - "callees": [] + "uses": ["4:3-4:7|16420|-1"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 75b57e371..e97af2376 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -14,14 +14,15 @@ OUTPUT: simple_header.h "detailed_name": "void header()", "qual_name_offset": 5, "short_name": "header", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["3:6-3:12|3:1-3:14|0|1|1|-1"], - "bases": [], + "declarations": ["3:6-3:12|3:1-3:14|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] @@ -38,29 +39,30 @@ OUTPUT: simple_impl.cc "detailed_name": "void impl()", "qual_name_offset": 5, "short_name": "impl", + "spell": "3:6-3:10|3:1-5:2|2|-1", + "bases": [], + "vars": [], + "callees": ["4:3-4:9|16236105532929924676|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["4:3-4:9|16236105532929924676|3|16420"] + "uses": [] }, { "usr": 16236105532929924676, "detailed_name": "void header()", "qual_name_offset": 5, "short_name": "header", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [], - "uses": ["4:3-4:9|3373269392705484958|3|16420|-1"], - "callees": [] + "uses": ["4:3-4:9|16420|-1"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 50096fb2e..d344cb7e5 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -12,30 +12,31 @@ OUTPUT: static.h "detailed_name": "static void Buffer::CreateSharedBuffer()", "qual_name_offset": 12, "short_name": "CreateSharedBuffer", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 0, "storage": 0, - "declarations": ["4:15-4:33|4:3-4:35|9411323049603567600|2|1025|-1"], - "bases": [], + "declarations": ["4:15-4:33|4:3-4:35|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 9411323049603567600, "detailed_name": "struct Buffer {}", "qual_name_offset": 7, "short_name": "Buffer", - "kind": 23, - "declarations": [], - "spell": "3:8-3:14|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "3:8-3:14|3:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [14576076421851654759], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -53,32 +54,33 @@ OUTPUT: static.cc "detailed_name": "static void Buffer::CreateSharedBuffer()", "qual_name_offset": 12, "short_name": "CreateSharedBuffer", + "spell": "3:14-3:32|3:1-3:37|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "3:14-3:32|9411323049603567600|2|1026|-1", - "extent": "3:1-3:37|9411323049603567600|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 9411323049603567600, "detailed_name": "struct Buffer {}", "qual_name_offset": 7, "short_name": "Buffer", - "kind": 23, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [14576076421851654759], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["3:6-3:12|0|1|4|-1"] + "uses": ["3:6-3:12|4|-1"] }], "usr2var": [] } diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 89d660a7a..7a69afced 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -12,28 +12,30 @@ void foo(); "detailed_name": "void (anon ns)::foo()", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["2:6-2:9|2:1-2:11|7144845543074395457|2|1|-1"], - "bases": [], + "declarations": ["2:6-2:9|2:1-2:11|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 7144845543074395457, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [5010253035933134245], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/namespaces/function_declaration.cc b/index_tests/namespaces/function_declaration.cc index 9ca5a4d88..fd16717e5 100644 --- a/index_tests/namespaces/function_declaration.cc +++ b/index_tests/namespaces/function_declaration.cc @@ -12,28 +12,30 @@ void foo(int a, int b); "detailed_name": "void hello::foo(int a, int b)", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["2:6-2:9|2:1-2:23|2029211996748007610|2|1025|-1"], - "bases": [], + "declarations": ["2:6-2:9|2:1-2:23|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", - "kind": 3, - "declarations": ["1:11-1:16|1:1-3:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [18343102288837190527], + "types": [], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:16|1:1-3:2|1|-1"], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/namespaces/function_definition.cc b/index_tests/namespaces/function_definition.cc index e732b06ec..afede23d8 100644 --- a/index_tests/namespaces/function_definition.cc +++ b/index_tests/namespaces/function_definition.cc @@ -12,30 +12,31 @@ void foo() {} "detailed_name": "void hello::foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "2:6-2:9|2:1-2:14|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 3, "storage": 0, "declarations": [], - "spell": "2:6-2:9|2029211996748007610|2|1026|-1", - "extent": "2:1-2:14|2029211996748007610|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", - "kind": 3, - "declarations": ["1:11-1:16|1:1-3:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [243328841292951622], + "types": [], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:16|1:1-3:2|1|-1"], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/namespaces/method_declaration.cc b/index_tests/namespaces/method_declaration.cc index b957b1d5f..236328cd5 100644 --- a/index_tests/namespaces/method_declaration.cc +++ b/index_tests/namespaces/method_declaration.cc @@ -14,28 +14,30 @@ class Foo { "detailed_name": "void hello::Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["3:8-3:11|3:3-3:13|4508214972876735896|2|1025|-1"], - "bases": [], + "declarations": ["3:8-3:11|3:3-3:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", - "kind": 3, - "declarations": ["1:11-1:16|1:1-5:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [4508214972876735896], "funcs": [], + "types": [4508214972876735896], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:16|1:1-5:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -43,16 +45,16 @@ class Foo { "detailed_name": "class hello::Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026|-1", - "extent": "2:1-4:2|2029211996748007610|2|0|-1", - "alias_of": 0, + "spell": "2:7-2:10|2:1-4:2|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [10487325150128053272], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 00f55200d..f2f47121c 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -16,30 +16,31 @@ void Foo::foo() {} "detailed_name": "void hello::Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "6:11-6:14|6:1-6:19|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["3:8-3:11|3:3-3:13|4508214972876735896|2|1025|-1"], - "spell": "6:11-6:14|4508214972876735896|2|1026|-1", - "extent": "6:1-6:19|4508214972876735896|2|0|-1", - "bases": [], + "declarations": ["3:8-3:11|3:3-3:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", - "kind": 3, - "declarations": ["1:11-1:16|1:1-7:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [4508214972876735896], "funcs": [], + "types": [4508214972876735896], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:16|1:1-7:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -47,18 +48,18 @@ void Foo::foo() {} "detailed_name": "class hello::Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026|-1", - "extent": "2:1-4:2|2029211996748007610|2|0|-1", - "alias_of": 0, + "spell": "2:7-2:10|2:1-4:2|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [10487325150128053272], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], - "uses": ["6:6-6:9|2029211996748007610|2|4|-1"] + "uses": ["6:6-6:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/namespaces/method_inline_declaration.cc b/index_tests/namespaces/method_inline_declaration.cc index 4d048be19..445bf61e9 100644 --- a/index_tests/namespaces/method_inline_declaration.cc +++ b/index_tests/namespaces/method_inline_declaration.cc @@ -14,30 +14,31 @@ class Foo { "detailed_name": "void hello::Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:8-3:11|3:3-3:16|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "3:8-3:11|4508214972876735896|2|1026|-1", - "extent": "3:3-3:16|4508214972876735896|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 2029211996748007610, "detailed_name": "namespace hello {}", "qual_name_offset": 10, "short_name": "hello", - "kind": 3, - "declarations": ["1:11-1:16|1:1-5:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [4508214972876735896], "funcs": [], + "types": [4508214972876735896], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:16|1:1-5:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -45,16 +46,16 @@ class Foo { "detailed_name": "class hello::Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "2:7-2:10|2029211996748007610|2|1026|-1", - "extent": "2:1-4:2|2029211996748007610|2|0|-1", - "alias_of": 0, + "spell": "2:7-2:10|2:1-4:2|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [10487325150128053272], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index b8cbce9c6..f74a7c798 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -23,30 +23,31 @@ void func() { "detailed_name": "void func()", "qual_name_offset": 5, "short_name": "func", + "spell": "11:6-11:10|11:1-14:2|2|-1", + "bases": [], + "vars": [6030927277961448585, 7657277353101371136], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "11:6-11:10|0|1|2|-1", - "extent": "11:1-14:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [6030927277961448585, 7657277353101371136], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [15042442838933090518, 6030927277961448585, 7657277353101371136], "uses": [] }, { @@ -54,64 +55,68 @@ void func() { "detailed_name": "namespace foo {}", "qual_name_offset": 10, "short_name": "foo", - "kind": 3, - "declarations": ["1:11-1:14|1:1-7:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [17805385787823406700], - "types": [17805385787823406700], "funcs": [], + "types": [17805385787823406700], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:14|1:1-7:2|1|-1"], + "derived": [17805385787823406700], "instances": [], - "uses": ["9:17-9:20|0|1|4|-1", "12:11-12:14|10818727483146447186|3|4|-1"] + "uses": ["9:17-9:20|4|-1", "12:11-12:14|4|-1"] }, { "usr": 11879713791858506216, "detailed_name": "namespace fbz = foo::bar::baz", "qual_name_offset": 10, "short_name": "fbz", - "kind": 252, - "declarations": ["9:11-9:14|9:1-9:30|0|1|1|-1"], - "alias_of": 14450849931009540802, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 14450849931009540802, + "kind": 252, + "parent_kind": 0, + "declarations": ["9:11-9:14|9:1-9:30|1|-1"], + "derived": [], "instances": [], - "uses": ["13:11-13:14|10818727483146447186|3|4|-1"] + "uses": ["13:11-13:14|4|-1"] }, { "usr": 14450849931009540802, "detailed_name": "namespace foo::bar::baz {}", "qual_name_offset": 10, "short_name": "baz", - "kind": 3, - "declarations": ["3:20-3:23|3:10-5:11|17805385787823406700|2|1025|-1"], - "alias_of": 0, "bases": [17805385787823406700], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 15042442838933090518, "R": -1 }], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["3:20-3:23|3:10-5:11|1025|-1"], + "derived": [], "instances": [], - "uses": ["9:27-9:30|0|1|4|-1", "12:21-12:24|10818727483146447186|3|4|-1"] + "uses": ["9:27-9:30|4|-1", "12:21-12:24|4|-1"] }, { "usr": 17805385787823406700, "detailed_name": "namespace foo::bar {}", "qual_name_offset": 10, "short_name": "bar", - "kind": 3, - "declarations": ["2:15-2:18|2:5-6:6|926793467007732869|2|1025|-1"], - "alias_of": 0, "bases": [926793467007732869], - "derived": [14450849931009540802], - "types": [14450849931009540802], "funcs": [], + "types": [14450849931009540802], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["2:15-2:18|2:5-6:6|1025|-1"], + "derived": [14450849931009540802], "instances": [], - "uses": ["9:22-9:25|0|1|4|-1", "12:16-12:19|10818727483146447186|3|4|-1"] + "uses": ["9:22-9:25|4|-1", "12:16-12:19|4|-1"] }], "usr2var": [{ "usr": 6030927277961448585, @@ -119,39 +124,39 @@ void func() { "qual_name_offset": 4, "short_name": "a", "hover": "int a = foo::bar::baz::qux", - "declarations": [], - "spell": "12:7-12:8|10818727483146447186|3|2|-1", - "extent": "12:3-12:29|10818727483146447186|3|0|-1", + "spell": "12:7-12:8|12:3-12:29|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 7657277353101371136, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", "hover": "int b = fbz::qux", - "declarations": [], - "spell": "13:7-13:8|10818727483146447186|3|2|-1", - "extent": "13:3-13:19|10818727483146447186|3|0|-1", + "spell": "13:7-13:8|13:3-13:19|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15042442838933090518, "detailed_name": "int foo::bar::baz::qux", "qual_name_offset": 4, "short_name": "qux", "hover": "int foo::bar::baz::qux = 42", - "declarations": [], - "spell": "4:18-4:21|14450849931009540802|2|1026|-1", - "extent": "4:14-4:26|14450849931009540802|2|0|-1", + "spell": "4:18-4:21|4:14-4:26|1026|-1", "type": 53, - "uses": ["12:26-12:29|10818727483146447186|3|12|-1", "13:16-13:19|10818727483146447186|3|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": ["12:26-12:29|12|-1", "13:16-13:19|12|-1"] }] } */ diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index 4565040d4..f90fd4b0d 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -19,45 +19,46 @@ void Runner() { "detailed_name": "void Runner()", "qual_name_offset": 5, "short_name": "Runner", + "spell": "6:6-6:12|6:1-10:2|2|-1", + "bases": [], + "vars": [], + "callees": ["7:7-7:13|17328473273923617489|3|16420", "9:3-9:9|17328473273923617489|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "6:6-6:12|0|1|2|-1", - "extent": "6:1-10:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["7:7-7:13|17328473273923617489|3|16420", "9:3-9:9|17328473273923617489|3|16420"] + "uses": [] }, { "usr": 17328473273923617489, "detailed_name": "void ns::Accept(int a)", "qual_name_offset": 5, "short_name": "Accept", + "spell": "3:8-3:14|3:3-3:24|1026|-1", + "bases": [], + "vars": [3649375698083002347], + "callees": [], "kind": 12, + "parent_kind": 3, "storage": 0, "declarations": [], - "spell": "3:8-3:14|11072669167287398027|2|1026|-1", - "extent": "3:3-3:24|11072669167287398027|2|0|-1", - "bases": [], "derived": [], - "vars": [3649375698083002347], - "uses": ["7:7-7:13|631910859630953711|3|16420|-1", "9:3-9:9|631910859630953711|3|16420|-1"], - "callees": [] + "uses": ["7:7-7:13|16420|-1", "9:3-9:9|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12898699035586282159, 3649375698083002347], "uses": [] }, { @@ -65,44 +66,45 @@ void Runner() { "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["1:11-1:13|1:1-4:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [17328473273923617489], + "types": [], "vars": [{ "L": 12898699035586282159, "R": -1 }], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:13|1:1-4:2|1|-1"], + "derived": [], "instances": [], - "uses": ["7:3-7:5|631910859630953711|3|4|-1", "7:14-7:16|631910859630953711|3|4|-1", "8:19-8:21|631910859630953711|3|4|-1"] + "uses": ["7:3-7:5|4|-1", "7:14-7:16|4|-1", "8:19-8:21|4|-1"] }], "usr2var": [{ "usr": 3649375698083002347, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "3:19-3:20|17328473273923617489|3|1026|-1", - "extent": "3:15-3:20|17328473273923617489|3|0|-1", + "spell": "3:19-3:20|3:15-3:20|1026|-1", "type": 53, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 12898699035586282159, "detailed_name": "int ns::Foo", "qual_name_offset": 4, "short_name": "Foo", - "declarations": [], - "spell": "2:7-2:10|11072669167287398027|2|1026|-1", - "extent": "2:3-2:10|11072669167287398027|2|0|-1", + "spell": "2:7-2:10|2:3-2:10|1026|-1", "type": 53, - "uses": ["7:18-7:21|631910859630953711|3|12|-1", "9:10-9:13|631910859630953711|3|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": ["7:18-7:21|12|-1", "9:10-9:13|12|-1"] }] } */ diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 009db1c0b..0640a220e 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -16,73 +16,76 @@ Foo &operator += (const Foo&, const int&); "detailed_name": "void Foo::operator()(bool)", "qual_name_offset": 5, "short_name": "operator()", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["3:8-3:16|3:3-3:24|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["3:8-3:16|3:3-3:24|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 3986818119971932909, "detailed_name": "int Foo::operator()(int a, int b)", "qual_name_offset": 4, "short_name": "operator()", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["4:7-4:15|4:3-4:31|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["4:7-4:15|4:3-4:31|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 7874436189163837815, "detailed_name": "void Foo::operator()(int)", "qual_name_offset": 5, "short_name": "operator()", + "spell": "2:8-2:18|2:3-2:27|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "2:8-2:18|15041163540773201510|2|1026|-1", - "extent": "2:3-2:27|15041163540773201510|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 8288368475529136092, "detailed_name": "Foo &operator+=(const Foo &, const int &)", "qual_name_offset": 5, "short_name": "operator+=", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["7:6-7:14|7:1-7:42|0|1|1|-1"], - "bases": [], + "declarations": ["7:6-7:14|7:1-7:42|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [7874436189163837815, 3545323327609582678, 3986818119971932909], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:1-7:4|0|1|4|-1", "7:25-7:28|0|1|4|-1"] + "uses": ["7:1-7:4|4|-1", "7:25-7:28|4|-1"] }], "usr2var": [] } diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index c29aae072..7120de031 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -16,43 +16,46 @@ OUTPUT: static_function_in_type.h "detailed_name": "static void ns::Foo::Register(ns::Manager *)", "qual_name_offset": 12, "short_name": "Register", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 0, "storage": 0, - "declarations": ["6:15-6:23|6:3-6:33|17262466801709381811|2|1025|-1"], - "bases": [], + "declarations": ["6:15-6:23|6:3-6:33|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 1972401196751872203, "detailed_name": "class ns::Manager", "qual_name_offset": 6, "short_name": "Manager", - "kind": 5, - "declarations": ["3:7-3:14|3:1-3:14|11072669167287398027|2|1025|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["3:7-3:14|3:1-3:14|1025|-1"], + "derived": [], "instances": [], - "uses": ["6:24-6:31|17262466801709381811|2|4|-1"] + "uses": ["6:24-6:31|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["1:11-1:13|1:1-9:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [1972401196751872203, 17262466801709381811], "funcs": [], + "types": [1972401196751872203, 17262466801709381811], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:13|1:1-9:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -60,16 +63,16 @@ OUTPUT: static_function_in_type.h "detailed_name": "struct ns::Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "5:8-5:11|11072669167287398027|2|1026|-1", - "extent": "5:1-7:2|11072669167287398027|2|0|-1", - "alias_of": 0, + "spell": "5:8-5:11|5:1-7:2|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17019747379608639279], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -87,46 +90,48 @@ OUTPUT: static_function_in_type.cc "detailed_name": "static void ns::Foo::Register(ns::Manager *)", "qual_name_offset": 12, "short_name": "Register", + "spell": "5:11-5:19|5:1-6:2|1026|-1", + "comments": "static", + "bases": [], + "vars": [13569879755236306838], + "callees": [], "kind": 254, + "parent_kind": 23, "storage": 0, - "comments": "static", "declarations": [], - "spell": "5:11-5:19|17262466801709381811|2|1026|-1", - "extent": "5:1-6:2|17262466801709381811|2|0|-1", - "bases": [], "derived": [], - "vars": [13569879755236306838], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 1972401196751872203, "detailed_name": "class ns::Manager", "qual_name_offset": 6, "short_name": "Manager", - "kind": 5, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [13569879755236306838], - "uses": ["5:20-5:27|11072669167287398027|2|4|-1"] + "uses": ["5:20-5:27|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["3:11-3:13|3:1-7:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["3:11-3:13|3:1-7:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -134,29 +139,30 @@ OUTPUT: static_function_in_type.cc "detailed_name": "struct ns::Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [17019747379608639279], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:6-5:9|11072669167287398027|2|4|-1"] + "uses": ["5:6-5:9|4|-1"] }], "usr2var": [{ "usr": 13569879755236306838, "detailed_name": "ns::Manager *m", "qual_name_offset": 13, "short_name": "m", - "declarations": [], - "spell": "5:29-5:30|17019747379608639279|3|1026|-1", - "extent": "5:20-5:30|17019747379608639279|3|0|-1", + "spell": "5:29-5:30|5:20-5:30|1026|-1", "type": 1972401196751872203, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 254, + "storage": 0, + "declarations": [], + "uses": [] }] } */ \ No newline at end of file diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index d9d069f79..efee4de53 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -16,13 +16,13 @@ "qual_name_offset": 0, "short_name": "FOO", "hover": "#define FOO", - "declarations": [], - "spell": "2:9-2:12|0|1|2|-1", - "extent": "2:9-2:12|0|1|0|-1", + "spell": "2:9-2:12|2:9-2:12|2|-1", "type": 0, - "uses": [], "kind": 255, - "storage": 0 + "parent_kind": 1, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index af88d365a..0cb68a030 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -17,51 +17,51 @@ void Foo::Bar(Template&) {} "detailed_name": "void Foo::Bar(Template &)", "qual_name_offset": 5, "short_name": "Bar", + "spell": "8:11-8:14|8:1-8:36|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 23, "storage": 0, - "declarations": ["5:8-5:11|5:3-5:30|15041163540773201510|2|1025|-1"], - "spell": "8:11-8:14|15041163540773201510|2|1026|-1", - "extent": "8:1-8:36|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["5:8-5:11|5:3-5:30|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "4:8-4:11|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "alias_of": 0, + "spell": "4:8-4:11|4:1-6:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [8412238651648388423], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["8:6-8:9|0|1|4|-1"] + "uses": ["8:6-8:9|4|-1"] }, { "usr": 17107291254533526269, "detailed_name": "class Template {}", "qual_name_offset": 6, "short_name": "Template", - "kind": 5, - "declarations": [], - "spell": "2:7-2:15|0|1|2|-1", - "extent": "2:1-2:18|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:15|2:1-2:18|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] + "uses": ["5:12-5:20|4|-1", "8:15-8:23|4|-1"] }], "usr2var": [] } diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 6548d39bf..b02443587 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -25,14 +25,15 @@ namespace ns { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12898699035586282159, 9008550860229740818], "uses": [] }, { @@ -40,30 +41,26 @@ namespace ns { "detailed_name": "enum ns::VarType {}", "qual_name_offset": 5, "short_name": "VarType", - "kind": 10, - "declarations": [], - "spell": "2:8-2:15|11072669167287398027|2|1026|-1", - "extent": "2:3-2:18|11072669167287398027|2|0|-1", - "alias_of": 0, + "spell": "2:8-2:15|2:3-2:18|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [4731849186641714451, 4731849186641714451], - "uses": ["6:22-6:29|12688716854043726585|2|4|-1", "6:44-6:51|12688716854043726585|2|4|-1", "10:18-10:25|11072669167287398027|2|4|-1"] + "uses": ["6:22-6:29|4|-1", "6:44-6:51|4|-1", "10:18-10:25|4|-1"] }, { "usr": 11072669167287398027, "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["1:11-1:13|1:1-15:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [1532099849728741556, 12688716854043726585], "funcs": [], + "types": [1532099849728741556, 12688716854043726585], "vars": [{ "L": 12898699035586282159, "R": -1 @@ -71,6 +68,11 @@ namespace ns { "L": 9008550860229740818, "R": -1 }], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:13|1:1-15:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -78,18 +80,18 @@ namespace ns { "detailed_name": "struct ns::Holder {}", "qual_name_offset": 7, "short_name": "Holder", - "kind": 23, - "declarations": [], - "spell": "5:10-5:16|11072669167287398027|2|1026|-1", - "extent": "5:3-7:4|11072669167287398027|2|0|-1", - "alias_of": 0, + "spell": "5:10-5:16|5:3-7:4|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:26-10:32|11072669167287398027|2|4|-1", "13:13-13:19|11072669167287398027|2|4|-1", "14:14-14:20|11072669167287398027|2|4|-1"] + "uses": ["10:26-10:32|4|-1", "13:13-13:19|4|-1", "14:14-14:20|4|-1"] }], "usr2var": [{ "usr": 4731849186641714451, @@ -97,39 +99,39 @@ namespace ns { "qual_name_offset": 29, "short_name": "static_var", "hover": "static constexpr ns::VarType ns::Holder::static_var = (VarType)0x0", - "declarations": ["6:30-6:40|6:5-6:55|12688716854043726585|2|1025|-1"], - "spell": "10:37-10:47|12688716854043726585|2|1026|-1", - "extent": "9:3-10:47|12688716854043726585|2|0|-1", + "spell": "10:37-10:47|9:3-10:47|1026|-1", "type": 1532099849728741556, - "uses": ["13:26-13:36|11072669167287398027|2|12|-1", "14:27-14:37|11072669167287398027|2|12|-1"], "kind": 13, - "storage": 2 + "parent_kind": 23, + "storage": 2, + "declarations": ["6:30-6:40|6:5-6:55|1025|-1"], + "uses": ["13:26-13:36|12|-1", "14:27-14:37|12|-1"] }, { "usr": 9008550860229740818, "detailed_name": "int ns::Foo2", "qual_name_offset": 4, "short_name": "Foo2", "hover": "int ns::Foo2 = Holder::static_var", - "declarations": [], - "spell": "14:7-14:11|11072669167287398027|2|1026|-1", - "extent": "14:3-14:37|11072669167287398027|2|0|-1", + "spell": "14:7-14:11|14:3-14:37|1026|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 12898699035586282159, "detailed_name": "int ns::Foo", "qual_name_offset": 4, "short_name": "Foo", "hover": "int ns::Foo = Holder::static_var", - "declarations": [], - "spell": "13:7-13:10|11072669167287398027|2|1026|-1", - "extent": "13:3-13:36|11072669167287398027|2|0|-1", + "spell": "13:7-13:10|13:3-13:36|1026|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/member_ref_in_template.cc b/index_tests/templates/member_ref_in_template.cc index 312441e28..c9cc268e8 100644 --- a/index_tests/templates/member_ref_in_template.cc +++ b/index_tests/templates/member_ref_in_template.cc @@ -30,48 +30,49 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "8:6-8:9|8:1-8:11|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2|-1", - "extent": "8:1-8:11|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 8905286151237717330, "detailed_name": "void C::bar()", "qual_name_offset": 5, "short_name": "bar", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["4:8-4:11|4:3-4:13|8402783583255987702|2|1025|-1"], - "bases": [], + "declarations": ["4:8-4:11|4:3-4:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 8402783583255987702, "detailed_name": "struct C {}", "qual_name_offset": 7, "short_name": "C", - "kind": 23, - "declarations": [], - "spell": "2:8-2:9|0|1|2|-1", - "extent": "2:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:9|2:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [8905286151237717330], + "types": [], "vars": [{ "L": 5866801090710377175, "R": -1 }], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -79,16 +80,16 @@ void foo() { "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "1:17-1:18|8402783583255987702|2|2|-1", - "extent": "1:11-1:18|8402783583255987702|2|0|-1", - "alias_of": 0, + "spell": "1:17-1:18|1:11-1:18|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 26, + "parent_kind": 5, + "declarations": [], + "derived": [], "instances": [5866801090710377175], "uses": [] }], @@ -97,13 +98,13 @@ void foo() { "detailed_name": "T C::x", "qual_name_offset": 2, "short_name": "x", - "declarations": [], - "spell": "3:5-3:6|8402783583255987702|2|1026|-1", - "extent": "3:3-3:6|8402783583255987702|2|0|-1", + "spell": "3:5-3:6|3:3-3:6|1026|-1", "type": 14750650276757822712, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc index a9005f186..de9c3143c 100644 --- a/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc @@ -21,30 +21,31 @@ namespace ns { "detailed_name": "static int ns::Foo::foo()", "qual_name_offset": 11, "short_name": "foo", + "spell": "5:16-5:19|5:5-7:6|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "5:16-5:19|14042997404480181958|2|1026|-1", - "extent": "5:5-7:6|14042997404480181958|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["10:21-10:24|11072669167287398027|2|36|-1", "11:22-11:25|11072669167287398027|2|36|-1"], - "callees": [] + "uses": ["10:21-10:24|36|-1", "11:22-11:25|36|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [15768138241775955040, 3182917058194750998], "uses": [] }, { @@ -52,13 +53,9 @@ namespace ns { "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["1:11-1:13|1:1-12:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [14042997404480181958], "funcs": [], + "types": [14042997404480181958], "vars": [{ "L": 15768138241775955040, "R": -1 @@ -66,6 +63,11 @@ namespace ns { "L": 3182917058194750998, "R": -1 }], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:13|1:1-12:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -73,18 +75,18 @@ namespace ns { "detailed_name": "struct ns::Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "3:10-3:13|11072669167287398027|2|1026|-1", - "extent": "3:3-8:4|11072669167287398027|2|0|-1", - "alias_of": 0, + "spell": "3:10-3:13|3:3-8:4|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [8221803074608342407], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:11-10:14|11072669167287398027|2|4|-1", "11:11-11:14|11072669167287398027|2|4|-1"] + "uses": ["10:11-10:14|4|-1", "11:11-11:14|4|-1"] }], "usr2var": [{ "usr": 3182917058194750998, @@ -92,26 +94,26 @@ namespace ns { "qual_name_offset": 4, "short_name": "b", "hover": "int ns::b = Foo::foo()", - "declarations": [], - "spell": "11:7-11:8|11072669167287398027|2|1026|-1", - "extent": "11:3-11:35|11072669167287398027|2|0|-1", + "spell": "11:7-11:8|11:3-11:35|1026|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15768138241775955040, "detailed_name": "int ns::a", "qual_name_offset": 4, "short_name": "a", "hover": "int ns::a = Foo::foo()", - "declarations": [], - "spell": "10:7-10:8|11072669167287398027|2|1026|-1", - "extent": "10:3-10:33|11072669167287398027|2|0|-1", + "spell": "10:7-10:8|10:3-10:33|1026|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc index b3144b08a..e8c8367c3 100644 --- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc +++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc @@ -17,13 +17,9 @@ namespace ns { "detailed_name": "namespace ns {}", "qual_name_offset": 10, "short_name": "ns", - "kind": 3, - "declarations": ["1:11-1:13|1:1-7:2|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [14042997404480181958], "funcs": [], + "types": [14042997404480181958], "vars": [{ "L": 15768138241775955040, "R": -1 @@ -31,6 +27,11 @@ namespace ns { "L": 3182917058194750998, "R": -1 }], + "alias_of": 0, + "kind": 3, + "parent_kind": 0, + "declarations": ["1:11-1:13|1:1-7:2|1|-1"], + "derived": [], "instances": [], "uses": [] }, { @@ -38,43 +39,43 @@ namespace ns { "detailed_name": "class ns::Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "3:9-3:12|11072669167287398027|2|1026|-1", - "extent": "3:3-3:15|11072669167287398027|2|0|-1", - "alias_of": 0, + "spell": "3:9-3:12|3:3-3:15|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 3, + "declarations": [], + "derived": [], "instances": [15768138241775955040, 3182917058194750998], - "uses": ["5:3-5:6|11072669167287398027|2|4|-1", "6:3-6:6|11072669167287398027|2|4|-1"] + "uses": ["5:3-5:6|4|-1", "6:3-6:6|4|-1"] }], "usr2var": [{ "usr": 3182917058194750998, "detailed_name": "Foo ns::b", "qual_name_offset": 10, "short_name": "b", - "declarations": [], - "spell": "6:13-6:14|11072669167287398027|2|1026|-1", - "extent": "6:3-6:14|11072669167287398027|2|0|-1", + "spell": "6:13-6:14|6:3-6:14|1026|-1", "type": 14042997404480181958, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15768138241775955040, "detailed_name": "Foo ns::a", "qual_name_offset": 9, "short_name": "a", - "declarations": [], - "spell": "5:12-5:13|11072669167287398027|2|1026|-1", - "extent": "5:3-5:13|11072669167287398027|2|0|-1", + "spell": "5:12-5:13|5:3-5:13|1026|-1", "type": 14042997404480181958, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 3, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 52cfe543b..4b414b7d1 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -52,69 +52,73 @@ void foo(float Value); "detailed_name": "template<> void foo(float Value)", "qual_name_offset": 16, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["43:6-43:9|42:1-43:50|0|1|1|-1"], - "bases": [], + "declarations": ["43:6-43:9|42:1-43:50|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 6113470698424012876, "detailed_name": "void vector >::clear()", "qual_name_offset": 5, "short_name": "clear", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["27:8-27:13|27:3-27:15|1663022413889915338|2|1025|-1"], - "bases": [], + "declarations": ["27:8-27:13|27:3-27:15|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 17498190318698490707, "detailed_name": "void foo(T Value)", "qual_name_offset": 5, "short_name": "foo", + "spell": "39:6-39:9|39:1-39:21|2|-1", + "bases": [], + "vars": [17826688417349629938], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "39:6-39:9|0|1|2|-1", - "extent": "39:1-39:21|0|1|0|-1", - "bases": [], "derived": [], - "vars": [17826688417349629938], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 18107614608385228556, "detailed_name": "void vector::clear()", "qual_name_offset": 5, "short_name": "clear", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["13:8-13:13|13:3-13:15|7440942986741176606|2|1025|-1"], - "bases": [], + "declarations": ["13:8-13:13|13:3-13:15|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [13914496963221806870], "uses": [] }, { @@ -122,84 +126,84 @@ void foo(float Value); "detailed_name": "template class function {}", "qual_name_offset": 46, "short_name": "function", - "kind": 5, - "declarations": [], - "spell": "5:7-5:15|0|1|2|-1", - "extent": "4:1-5:30|0|1|0|-1", - "alias_of": 0, + "spell": "5:7-5:15|4:1-5:30|2|-1", "bases": [15019211479263750068], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2933643612409209903], - "uses": ["7:1-7:9|0|1|4|-1"] + "uses": ["7:1-7:9|4|-1"] }, { "usr": 1663022413889915338, "detailed_name": "template<> class vector> {}", "qual_name_offset": 17, "short_name": "vector", - "kind": 5, - "declarations": [], - "spell": "26:7-26:13|0|1|2|-1", - "extent": "25:1-28:2|0|1|0|-1", - "alias_of": 0, + "spell": "26:7-26:13|25:1-28:2|2|-1", "bases": [7440942986741176606], - "derived": [], - "types": [], "funcs": [6113470698424012876], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [15931696253641284761], - "uses": ["26:7-26:13|0|1|4|-1", "33:1-33:7|0|1|4|-1"] + "uses": ["26:7-26:13|4|-1", "33:1-33:7|4|-1"] }, { "usr": 5760043510674081814, "detailed_name": "struct Z1 {}", "qual_name_offset": 7, "short_name": "Z1", - "kind": 23, - "declarations": [], - "spell": "19:8-19:10|0|1|2|-1", - "extent": "19:1-19:13|0|1|0|-1", - "alias_of": 0, + "spell": "19:8-19:10|19:1-19:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["21:23-21:25|0|1|4|-1", "32:8-32:10|0|1|4|-1"] + "uses": ["21:23-21:25|4|-1", "32:8-32:10|4|-1"] }, { "usr": 7440942986741176606, "detailed_name": "class vector {}", "qual_name_offset": 6, "short_name": "vector", - "kind": 5, - "declarations": [], - "spell": "12:7-12:13|0|1|2|-1", - "extent": "12:1-14:2|0|1|0|-1", - "alias_of": 0, + "spell": "12:7-12:13|12:1-14:2|2|-1", "bases": [], - "derived": [16155717907537731864, 1663022413889915338], - "types": [], "funcs": [18107614608385228556], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [16155717907537731864, 1663022413889915338], "instances": [5792869548777559988], - "uses": ["21:16-21:22|0|1|4|-1", "30:1-30:7|0|1|4|-1", "32:1-32:7|0|1|4|-1"] + "uses": ["17:7-17:13|4|-1", "21:16-21:22|4|-1", "30:1-30:7|4|-1", "32:1-32:7|4|-1"] }, { "usr": 9201299975592934124, "detailed_name": "enum Enum {}", "qual_name_offset": 5, "short_name": "Enum", - "kind": 10, - "declarations": [], - "spell": "35:6-35:10|0|1|2|-1", - "extent": "35:1-37:2|0|1|0|-1", - "alias_of": 0, + "spell": "35:6-35:10|35:1-37:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -207,33 +211,33 @@ void foo(float Value); "detailed_name": "struct Z2 {}", "qual_name_offset": 7, "short_name": "Z2", - "kind": 23, - "declarations": [], - "spell": "23:8-23:10|0|1|2|-1", - "extent": "23:1-23:13|0|1|0|-1", - "alias_of": 0, + "spell": "23:8-23:10|23:1-23:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["26:14-26:16|0|1|4|-1", "33:8-33:10|0|1|4|-1"] + "uses": ["26:14-26:16|4|-1", "33:8-33:10|4|-1"] }, { "usr": 14111105212951082474, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "38:20-38:21|17498190318698490707|3|2|-1", - "extent": "38:11-38:21|17498190318698490707|3|0|-1", - "alias_of": 0, + "spell": "38:20-38:21|38:11-38:21|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 26, + "parent_kind": 5, + "declarations": [], + "derived": [], "instances": [17826688417349629938], "uses": [] }, { @@ -241,29 +245,31 @@ void foo(float Value); "detailed_name": "class function", "qual_name_offset": 6, "short_name": "function", - "kind": 5, - "declarations": ["2:7-2:15|2:1-2:15|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [218068462278884837], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["2:7-2:15|2:1-2:15|1|-1"], + "derived": [218068462278884837], "instances": [], - "uses": [] + "uses": ["5:7-5:15|4|-1"] }, { "usr": 15440970074034693939, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [3566687051827176322], "uses": [] }, { @@ -271,145 +277,146 @@ void foo(float Value); "detailed_name": "class allocator", "qual_name_offset": 6, "short_name": "allocator", - "kind": 5, - "declarations": ["9:28-9:37|9:22-9:37|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["9:28-9:37|9:22-9:37|1|-1"], + "derived": [], "instances": [], - "uses": [] + "uses": ["11:39-11:48|4|-1"] }, { "usr": 16155717907537731864, "detailed_name": "template class vector> {}", "qual_name_offset": 28, "short_name": "vector", - "kind": 5, - "declarations": [], - "spell": "17:7-17:13|0|1|2|-1", - "extent": "16:1-17:20|0|1|0|-1", - "alias_of": 0, + "spell": "17:7-17:13|16:1-17:20|2|-1", "bases": [7440942986741176606], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [86949563628772958], - "uses": ["31:1-31:7|0|1|4|-1"] + "uses": ["31:1-31:7|4|-1"] }], "usr2var": [{ "usr": 86949563628772958, "detailed_name": "vector vip", "qual_name_offset": 14, "short_name": "vip", - "declarations": [], - "spell": "31:14-31:17|0|1|2|-1", - "extent": "31:1-31:17|0|1|0|-1", + "spell": "31:14-31:17|31:1-31:17|2|-1", "type": 16155717907537731864, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 2933643612409209903, "detailed_name": "function f", "qual_name_offset": 21, "short_name": "f", - "declarations": [], - "spell": "7:21-7:22|0|1|2|-1", - "extent": "7:1-7:22|0|1|0|-1", + "spell": "7:21-7:22|7:1-7:22|2|-1", "type": 218068462278884837, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 3566687051827176322, "detailed_name": "vector vz1", "qual_name_offset": 11, "short_name": "vz1", - "declarations": [], - "spell": "32:12-32:15|0|1|2|-1", - "extent": "32:1-32:15|0|1|0|-1", + "spell": "32:12-32:15|32:1-32:15|2|-1", "type": 15440970074034693939, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 4917621020431490070, "detailed_name": "Enum1", "qual_name_offset": 0, "short_name": "Enum1", "hover": "Enum1 = 1", - "declarations": [], - "spell": "36:10-36:15|9201299975592934124|2|1026|-1", - "extent": "36:10-36:15|9201299975592934124|2|0|-1", + "spell": "36:10-36:15|36:10-36:15|1026|-1", "type": 0, - "uses": [], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 5792869548777559988, "detailed_name": "vector vc", "qual_name_offset": 13, "short_name": "vc", - "declarations": [], - "spell": "30:14-30:16|0|1|2|-1", - "extent": "30:1-30:16|0|1|0|-1", + "spell": "30:14-30:16|30:1-30:16|2|-1", "type": 7440942986741176606, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 13914496963221806870, "detailed_name": "static const int kOnst", "qual_name_offset": 17, "short_name": "kOnst", "hover": "static const int kOnst = 7", - "declarations": [], - "spell": "41:18-41:23|0|1|2|-1", - "extent": "41:1-41:27|0|1|0|-1", + "spell": "41:18-41:23|41:1-41:27|2|-1", "type": 53, - "uses": ["43:27-43:32|0|1|12|-1"], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": ["43:27-43:32|12|-1"] }, { "usr": 15477793821005285152, "detailed_name": "Enum0", "qual_name_offset": 0, "short_name": "Enum0", "hover": "Enum0 = 0", - "declarations": [], - "spell": "36:3-36:8|9201299975592934124|2|1026|-1", - "extent": "36:3-36:8|9201299975592934124|2|0|-1", + "spell": "36:3-36:8|36:3-36:8|1026|-1", "type": 0, - "uses": ["43:20-43:25|0|1|4|-1"], "kind": 22, - "storage": 0 + "parent_kind": 10, + "storage": 0, + "declarations": [], + "uses": ["43:20-43:25|4|-1"] }, { "usr": 15931696253641284761, "detailed_name": "vector vz2", "qual_name_offset": 11, "short_name": "vz2", - "declarations": [], - "spell": "33:12-33:15|0|1|2|-1", - "extent": "33:1-33:15|0|1|0|-1", + "spell": "33:12-33:15|33:1-33:15|2|-1", "type": 1663022413889915338, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 17826688417349629938, "detailed_name": "T Value", "qual_name_offset": 2, "short_name": "Value", - "declarations": [], - "spell": "39:12-39:17|17498190318698490707|3|1026|-1", - "extent": "39:10-39:17|17498190318698490707|3|0|-1", + "spell": "39:12-39:17|39:10-39:17|1026|-1", "type": 14111105212951082474, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 1397ba801..c57b35ffe 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -27,62 +27,63 @@ void Template::Foo() {} "detailed_name": "void Template::Foo()", "qual_name_offset": 5, "short_name": "Foo", + "spell": "10:22-10:25|9:1-10:30|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, "declarations": [], - "spell": "10:22-10:25|17649312483543982122|2|1026|-1", - "extent": "9:1-10:30|17649312483543982122|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 11994188353303124840, "detailed_name": "void Template::Foo()", "qual_name_offset": 5, "short_name": "Foo", + "spell": "7:19-7:22|6:1-7:24|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["3:8-3:11|3:3-3:13|17107291254533526269|2|1025|-1"], - "spell": "7:19-7:22|17107291254533526269|2|1026|-1", - "extent": "6:1-7:24|17107291254533526269|2|0|-1", - "bases": [], + "declarations": ["3:8-3:11|3:3-3:13|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 17107291254533526269, "detailed_name": "class Template {}", "qual_name_offset": 6, "short_name": "Template", - "kind": 5, - "declarations": [], - "spell": "2:7-2:15|0|1|2|-1", - "extent": "2:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:15|2:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [11994188353303124840], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:6-7:14|0|1|4|-1", "10:6-10:14|0|1|4|-1"] + "uses": ["7:6-7:14|4|-1", "10:6-10:14|4|-1"] }, { "usr": 17649312483543982122, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [6995843774014807426], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/templates/template_class_func_usage_folded_into_one.cc b/index_tests/templates/template_class_func_usage_folded_into_one.cc index 2297d9966..6efb299e3 100644 --- a/index_tests/templates/template_class_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_func_usage_folded_into_one.cc @@ -18,30 +18,31 @@ int b = Foo::foo(); "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", + "spell": "3:14-3:17|3:3-5:4|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "3:14-3:17|10528472276654770367|2|1026|-1", - "extent": "3:3-5:4|10528472276654770367|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["8:19-8:22|0|1|36|-1", "9:20-9:23|0|1|36|-1"], - "callees": [] + "uses": ["8:19-8:22|36|-1", "9:20-9:23|36|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768, 12028309045033782423], "uses": [] }, { @@ -49,18 +50,18 @@ int b = Foo::foo(); "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "2:8-2:11|0|1|2|-1", - "extent": "2:1-6:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:11|2:1-6:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [8340731781048851399], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["8:9-8:12|0|1|4|-1", "9:9-9:12|0|1|4|-1"] + "uses": ["8:9-8:12|4|-1", "9:9-9:12|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -68,26 +69,26 @@ int b = Foo::foo(); "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::foo()", - "declarations": [], - "spell": "9:5-9:6|0|1|2|-1", - "extent": "9:1-9:25|0|1|0|-1", + "spell": "9:5-9:6|9:1-9:25|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::foo()", - "declarations": [], - "spell": "8:5-8:6|0|1|2|-1", - "extent": "8:1-8:24|0|1|0|-1", + "spell": "8:5-8:6|8:1-8:24|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc index 3fcb3672f..c364718f1 100644 --- a/index_tests/templates/template_class_template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_template_func_usage_folded_into_one.cc @@ -19,30 +19,31 @@ int b = Foo::foo(); "detailed_name": "static int Foo::foo()", "qual_name_offset": 11, "short_name": "foo", + "spell": "4:14-4:17|4:3-6:4|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 254, + "parent_kind": 23, "storage": 0, "declarations": [], - "spell": "4:14-4:17|10528472276654770367|2|1026|-1", - "extent": "4:3-6:4|10528472276654770367|2|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["9:19-9:22|0|1|36|-1", "10:20-10:23|0|1|36|-1"], - "callees": [] + "uses": ["9:19-9:22|36|-1", "10:20-10:23|36|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768, 12028309045033782423], "uses": [] }, { @@ -50,18 +51,18 @@ int b = Foo::foo(); "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "2:8-2:11|0|1|2|-1", - "extent": "2:1-7:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:11|2:1-7:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [9034026360701857235], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["9:9-9:12|0|1|4|-1", "10:9-10:12|0|1|4|-1"] + "uses": ["9:9-9:12|4|-1", "10:9-10:12|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -69,26 +70,26 @@ int b = Foo::foo(); "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::foo()", - "declarations": [], - "spell": "10:5-10:6|0|1|2|-1", - "extent": "10:1-10:33|0|1|0|-1", + "spell": "10:5-10:6|10:1-10:33|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::foo()", - "declarations": [], - "spell": "9:5-9:6|0|1|2|-1", - "extent": "9:1-9:31|0|1|0|-1", + "spell": "9:5-9:6|9:1-9:31|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc index 09bc2e7c6..b15eb530a 100644 --- a/index_tests/templates/template_class_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc @@ -38,94 +38,94 @@ VarDecl b "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", - "kind": 10, - "declarations": [], - "spell": "1:6-1:7|0|1|2|-1", - "extent": "1:1-1:10|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:7|1:1-1:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["9:5-9:6|0|1|4|-1"] + "uses": ["9:5-9:6|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "5:8-5:11|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "alias_of": 0, + "spell": "5:8-5:11|5:1-7:2|2|-1", "bases": [], - "derived": [], - "types": [13938528237873543349], "funcs": [], + "types": [13938528237873543349], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"] + "uses": ["9:1-9:4|4|-1", "10:1-10:4|4|-1"] }, { "usr": 13892793056005362145, "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", - "kind": 10, - "declarations": [], - "spell": "2:6-2:7|0|1|2|-1", - "extent": "2:1-2:10|0|1|0|-1", - "alias_of": 0, + "spell": "2:6-2:7|2:1-2:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:5-10:6|0|1|4|-1"] + "uses": ["10:5-10:6|4|-1"] }, { "usr": 13938528237873543349, "detailed_name": "struct Foo::Inner {}", "qual_name_offset": 7, "short_name": "Inner", - "kind": 23, - "declarations": [], - "spell": "6:10-6:15|10528472276654770367|2|1026|-1", - "extent": "6:3-6:18|10528472276654770367|2|0|-1", - "alias_of": 0, + "spell": "6:10-6:15|6:3-6:18|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 23, + "declarations": [], + "derived": [], "instances": [16721564935990383768, 12028309045033782423], - "uses": ["9:9-9:14|0|1|4|-1", "10:9-10:14|0|1|4|-1"] + "uses": ["9:9-9:14|4|-1", "10:9-10:14|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, "detailed_name": "Foo::Inner b", "qual_name_offset": 14, "short_name": "b", - "declarations": [], - "spell": "10:15-10:16|0|1|2|-1", - "extent": "10:1-10:16|0|1|0|-1", + "spell": "10:15-10:16|10:1-10:16|2|-1", "type": 13938528237873543349, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "Foo::Inner a", "qual_name_offset": 14, "short_name": "a", - "declarations": [], - "spell": "9:15-9:16|0|1|2|-1", - "extent": "9:1-9:16|0|1|0|-1", + "spell": "9:15-9:16|9:1-9:16|2|-1", "type": 13938528237873543349, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index 23d2ed6a4..8f8f0cd47 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -17,14 +17,15 @@ int b = Foo::var; "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [13545144895171991916, 16721564935990383768, 12028309045033782423], "uses": [] }, { @@ -32,18 +33,18 @@ int b = Foo::var; "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "2:8-2:11|0|1|2|-1", - "extent": "2:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:11|2:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["6:9-6:12|0|1|4|-1", "7:9-7:12|0|1|4|-1"] + "uses": ["6:9-6:12|4|-1", "7:9-7:12|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, @@ -51,37 +52,38 @@ int b = Foo::var; "qual_name_offset": 4, "short_name": "b", "hover": "int b = Foo::var", - "declarations": [], - "spell": "7:5-7:6|0|1|2|-1", - "extent": "7:1-7:23|0|1|0|-1", + "spell": "7:5-7:6|7:1-7:23|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 13545144895171991916, "detailed_name": "static constexpr int Foo::var", "qual_name_offset": 21, "short_name": "var", "hover": "static constexpr int Foo::var = 3", - "declarations": ["3:24-3:27|3:3-3:31|10528472276654770367|2|1025|-1"], "type": 53, - "uses": ["6:19-6:22|0|1|12|-1", "7:20-7:23|0|1|12|-1"], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": ["3:24-3:27|3:3-3:31|1025|-1"], + "uses": ["6:19-6:22|12|-1", "7:20-7:23|12|-1"] }, { "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = Foo::var", - "declarations": [], - "spell": "6:5-6:6|0|1|2|-1", - "extent": "6:1-6:22|0|1|0|-1", + "spell": "6:5-6:6|6:1-6:22|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_func_usage_folded_into_one.cc b/index_tests/templates/template_func_usage_folded_into_one.cc index c93297116..9c2538940 100644 --- a/index_tests/templates/template_func_usage_folded_into_one.cc +++ b/index_tests/templates/template_func_usage_folded_into_one.cc @@ -19,30 +19,31 @@ int b = foo(); "detailed_name": "static int foo()", "qual_name_offset": 11, "short_name": "foo", + "spell": "2:12-2:15|2:1-4:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "2:12-2:15|0|1|2|-1", - "extent": "2:1-4:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["6:9-6:12|0|1|36|-1", "7:9-7:12|0|1|36|-1"], - "callees": [] + "uses": ["6:9-6:12|36|-1", "7:9-7:12|36|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768, 12028309045033782423], "uses": [] }], @@ -52,26 +53,26 @@ int b = foo(); "qual_name_offset": 4, "short_name": "b", "hover": "int b = foo()", - "declarations": [], - "spell": "7:5-7:6|0|1|2|-1", - "extent": "7:1-7:20|0|1|0|-1", + "spell": "7:5-7:6|7:1-7:20|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", "hover": "int a = foo()", - "declarations": [], - "spell": "6:5-6:6|0|1|2|-1", - "extent": "6:1-6:19|0|1|0|-1", + "spell": "6:5-6:6|6:1-6:19|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc index fb7191797..05dfa00e7 100644 --- a/index_tests/templates/template_type_usage_folded_into_one.cc +++ b/index_tests/templates/template_type_usage_folded_into_one.cc @@ -15,43 +15,43 @@ Foo b; "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "2:7-2:10|0|1|2|-1", - "extent": "2:1-2:13|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:10|2:1-2:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768, 12028309045033782423], - "uses": ["4:1-4:4|0|1|4|-1", "5:1-5:4|0|1|4|-1"] + "uses": ["4:1-4:4|4|-1", "5:1-5:4|4|-1"] }], "usr2var": [{ "usr": 12028309045033782423, "detailed_name": "Foo b", "qual_name_offset": 10, "short_name": "b", - "declarations": [], - "spell": "5:11-5:12|0|1|2|-1", - "extent": "5:1-5:12|0|1|0|-1", + "spell": "5:11-5:12|5:1-5:12|2|-1", "type": 10528472276654770367, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "Foo a", "qual_name_offset": 9, "short_name": "a", - "declarations": [], - "spell": "4:10-4:11|0|1|2|-1", - "extent": "4:1-4:11|0|1|0|-1", + "spell": "4:10-4:11|4:1-4:11|2|-1", "type": 10528472276654770367, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 44489203a..7359e0dd7 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -41,33 +41,33 @@ UnexposedDecl var "detailed_name": "enum A {}", "qual_name_offset": 5, "short_name": "A", - "kind": 10, - "declarations": [], - "spell": "1:6-1:7|0|1|2|-1", - "extent": "1:1-1:10|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:7|1:1-1:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768], - "uses": ["7:1-7:2|0|1|4|-1", "7:11-7:12|0|1|4|-1"] + "uses": ["7:1-7:2|4|-1", "7:11-7:12|4|-1"] }, { "usr": 11919899838872947844, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", - "kind": 26, - "declarations": [], - "spell": "4:19-4:20|0|1|2|-1", - "extent": "4:10-4:20|0|1|0|-1", - "alias_of": 0, + "spell": "4:19-4:20|4:10-4:20|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 26, + "parent_kind": 5, + "declarations": [], + "derived": [], "instances": [8096973118640070624], "uses": [] }, { @@ -75,18 +75,18 @@ UnexposedDecl var "detailed_name": "enum B {}", "qual_name_offset": 5, "short_name": "B", - "kind": 10, - "declarations": [], - "spell": "2:6-2:7|0|1|2|-1", - "extent": "2:1-2:10|0|1|0|-1", - "alias_of": 0, + "spell": "2:6-2:7|2:1-2:10|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12028309045033782423], - "uses": ["8:1-8:2|0|1|4|-1", "8:11-8:12|0|1|4|-1"] + "uses": ["8:1-8:2|4|-1", "8:11-8:12|4|-1"] }], "usr2var": [{ "usr": 8096973118640070624, @@ -94,39 +94,39 @@ UnexposedDecl var "qual_name_offset": 2, "short_name": "var", "hover": "T var = T()", - "declarations": [], - "spell": "5:3-5:6|0|1|2|-1", - "extent": "5:1-5:12|0|1|0|-1", + "spell": "5:3-5:6|5:1-5:12|2|-1", "type": 11919899838872947844, - "uses": ["7:7-7:10|0|1|12|-1", "8:7-8:10|0|1|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": ["7:7-7:10|12|-1", "8:7-8:10|12|-1"] }, { "usr": 12028309045033782423, "detailed_name": "B b", "qual_name_offset": 2, "short_name": "b", "hover": "B b = var", - "declarations": [], - "spell": "8:3-8:4|0|1|2|-1", - "extent": "8:1-8:13|0|1|0|-1", + "spell": "8:3-8:4|8:1-8:13|2|-1", "type": 13892793056005362145, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16721564935990383768, "detailed_name": "A a", "qual_name_offset": 2, "short_name": "a", "hover": "A a = var", - "declarations": [], - "spell": "7:3-7:4|0|1|2|-1", - "extent": "7:1-7:13|0|1|0|-1", + "spell": "7:3-7:4|7:1-7:13|2|-1", "type": 6697181287623958829, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index 9d88a8bf1..baa5c2dc8 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -14,14 +14,15 @@ union vector3 { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [3348817847649945564, 4821094820988543895, 15292551660437765731], "uses": [] }, { @@ -29,15 +30,10 @@ union vector3 { "detailed_name": "anon struct", "qual_name_offset": 0, "short_name": "anon struct", - "kind": 23, - "declarations": [], - "spell": "2:3-2:9|17937907487590875128|2|1026|-1", - "extent": "2:3-2:28|17937907487590875128|2|0|-1", - "alias_of": 0, + "spell": "2:3-2:9|2:3-2:28|1026|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 3348817847649945564, "R": 0 @@ -48,6 +44,11 @@ union vector3 { "L": 15292551660437765731, "R": 64 }], + "alias_of": 0, + "kind": 23, + "parent_kind": 5, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -55,15 +56,10 @@ union vector3 { "detailed_name": "union vector3 {}", "qual_name_offset": 6, "short_name": "vector3", - "kind": 5, - "declarations": [], - "spell": "1:7-1:14|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:14|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [1428566502523368801], "funcs": [], + "types": [1428566502523368801], "vars": [{ "L": 1963212417280098348, "R": 0 @@ -77,6 +73,11 @@ union vector3 { "L": 15292551660437765731, "R": 64 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -85,49 +86,49 @@ union vector3 { "detailed_name": "float vector3::v[3]", "qual_name_offset": 6, "short_name": "v", - "declarations": [], - "spell": "3:9-3:10|17937907487590875128|2|1026|-1", - "extent": "3:3-3:13|17937907487590875128|2|0|-1", + "spell": "3:9-3:10|3:3-3:13|1026|-1", "type": 0, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 3348817847649945564, "detailed_name": "float vector3::(anon struct)::x", "qual_name_offset": 6, "short_name": "x", - "declarations": [], - "spell": "2:18-2:19|1428566502523368801|2|1026|-1", - "extent": "2:12-2:19|1428566502523368801|2|0|-1", + "spell": "2:18-2:19|2:12-2:19|1026|-1", "type": 82, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 4821094820988543895, "detailed_name": "float vector3::(anon struct)::y", "qual_name_offset": 6, "short_name": "y", - "declarations": [], - "spell": "2:21-2:22|1428566502523368801|2|1026|-1", - "extent": "2:12-2:22|1428566502523368801|2|0|-1", + "spell": "2:21-2:22|2:12-2:22|1026|-1", "type": 82, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15292551660437765731, "detailed_name": "float vector3::(anon struct)::z", "qual_name_offset": 6, "short_name": "z", - "declarations": [], - "spell": "2:24-2:25|1428566502523368801|2|1026|-1", - "extent": "2:12-2:25|1428566502523368801|2|0|-1", + "spell": "2:24-2:25|2:12-2:25|1026|-1", "type": 82, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/types/typedefs.cc b/index_tests/types/typedefs.cc index 17d3fcbd0..4a2844b70 100644 --- a/index_tests/types/typedefs.cc +++ b/index_tests/types/typedefs.cc @@ -11,32 +11,33 @@ static func g; "detailed_name": "static int g(const int *, const int *)", "qual_name_offset": 11, "short_name": "g", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["2:13-2:14|2:1-2:14|0|1|1|-1"], - "bases": [], + "declarations": ["2:13-2:14|2:1-2:14|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 10383876566159302459, "detailed_name": "typedef int (func)(const int *, const int *)", "qual_name_offset": 12, "short_name": "func", - "kind": 252, - "declarations": [], - "spell": "1:14-1:18|0|1|2|-1", - "extent": "1:1-1:47|0|1|0|-1", - "alias_of": 0, + "spell": "1:14-1:18|1:1-1:47|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["2:8-2:12|0|1|4|-1"] + "uses": ["2:8-2:12|4|-1"] }], "usr2var": [] } diff --git a/index_tests/unions/union_decl.cc b/index_tests/unions/union_decl.cc index 7861f8ff7..313c201e7 100644 --- a/index_tests/unions/union_decl.cc +++ b/index_tests/unions/union_decl.cc @@ -14,14 +14,15 @@ union Foo { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [8804696910588009104], "uses": [] }, { @@ -29,14 +30,15 @@ union Foo { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [9529311430721959843], "uses": [] }, { @@ -44,15 +46,10 @@ union Foo { "detailed_name": "union Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 9529311430721959843, "R": 0 @@ -60,6 +57,11 @@ union Foo { "L": 8804696910588009104, "R": 0 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -68,25 +70,25 @@ union Foo { "detailed_name": "bool Foo::b", "qual_name_offset": 5, "short_name": "b", - "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|1026|-1", - "extent": "3:3-3:9|8501689086387244262|2|0|-1", + "spell": "3:8-3:9|3:3-3:9|1026|-1", "type": 37, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 9529311430721959843, "detailed_name": "int Foo::a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|1026|-1", - "extent": "2:3-2:8|8501689086387244262|2|0|-1", + "spell": "2:7-2:8|2:3-2:8|1026|-1", "type": 53, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/unions/union_usage.cc b/index_tests/unions/union_usage.cc index 248f5975d..57bb2ebf4 100644 --- a/index_tests/unions/union_usage.cc +++ b/index_tests/unions/union_usage.cc @@ -21,30 +21,31 @@ void act(Foo*) { "detailed_name": "void act(Foo *)", "qual_name_offset": 5, "short_name": "act", + "spell": "8:6-8:9|8:1-10:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2|-1", - "extent": "8:1-10:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 37, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [8804696910588009104], "uses": [] }, { @@ -52,14 +53,15 @@ void act(Foo*) { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [9529311430721959843], "uses": [] }, { @@ -67,15 +69,10 @@ void act(Foo*) { "detailed_name": "union Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-4:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 9529311430721959843, "R": 0 @@ -83,45 +80,50 @@ void act(Foo*) { "L": 8804696910588009104, "R": 0 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2933643612409209903], - "uses": ["6:1-6:4|0|1|4|-1", "8:10-8:13|0|1|4|-1"] + "uses": ["6:1-6:4|4|-1", "8:10-8:13|4|-1"] }], "usr2var": [{ "usr": 2933643612409209903, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", - "declarations": [], - "spell": "6:5-6:6|0|1|2|-1", - "extent": "6:1-6:6|0|1|0|-1", + "spell": "6:5-6:6|6:1-6:6|2|-1", "type": 8501689086387244262, - "uses": ["9:3-9:4|13982179977217945200|3|4|-1"], "kind": 13, - "storage": 0 + "parent_kind": 0, + "storage": 0, + "declarations": [], + "uses": ["9:3-9:4|4|-1"] }, { "usr": 8804696910588009104, "detailed_name": "bool Foo::b : 3", "qual_name_offset": 5, "short_name": "b", - "declarations": [], - "spell": "3:8-3:9|8501689086387244262|2|1026|-1", - "extent": "3:3-3:13|8501689086387244262|2|0|-1", + "spell": "3:8-3:9|3:3-3:13|1026|-1", "type": 37, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 9529311430721959843, "detailed_name": "int Foo::a : 5", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "2:7-2:8|8501689086387244262|2|1026|-1", - "extent": "2:3-2:12|8501689086387244262|2|0|-1", + "spell": "2:7-2:8|2:3-2:12|1026|-1", "type": 53, - "uses": ["9:5-9:6|13982179977217945200|3|20|-1"], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": ["9:5-9:6|20|-1"] }] } */ diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index 53c436697..d002eb453 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -18,49 +18,49 @@ Foo::Foo() { "detailed_name": "void called()", "qual_name_offset": 5, "short_name": "called", + "spell": "1:6-1:12|1:1-1:17|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2|-1", - "extent": "1:1-1:17|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["8:3-8:9|3385168158331140247|3|16420|-1"], - "callees": [] + "uses": ["8:3-8:9|16420|-1"] }, { "usr": 3385168158331140247, "detailed_name": "Foo::Foo()", "qual_name_offset": 0, "short_name": "Foo", + "spell": "7:6-7:9|7:1-9:2|1026|-1", + "bases": [], + "vars": [], + "callees": ["8:3-8:9|468307235068920063|3|16420"], "kind": 9, + "parent_kind": 23, "storage": 0, - "declarations": ["4:3-4:6|4:3-4:8|15041163540773201510|2|1025|-1"], - "spell": "7:6-7:9|15041163540773201510|2|1026|-1", - "extent": "7:1-9:2|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["4:3-4:6|4:3-4:8|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": ["8:3-8:9|468307235068920063|3|16420"] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "3:8-3:11|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "3:8-3:11|3:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [3385168158331140247], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["4:3-4:6|15041163540773201510|2|4|-1", "7:1-7:4|0|1|4|-1", "7:6-7:9|15041163540773201510|2|4|-1"] + "uses": ["4:3-4:6|4|-1", "7:1-7:4|4|-1", "7:6-7:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/func_called_from_macro_argument.cc b/index_tests/usage/func_called_from_macro_argument.cc index 868db9e87..2c7f43050 100644 --- a/index_tests/usage/func_called_from_macro_argument.cc +++ b/index_tests/usage/func_called_from_macro_argument.cc @@ -16,29 +16,30 @@ void caller() { "detailed_name": "bool called(bool a, bool b)", "qual_name_offset": 5, "short_name": "called", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["3:6-3:12|3:1-3:28|0|1|1|-1"], - "bases": [], + "declarations": ["3:6-3:12|3:1-3:28|1|-1"], "derived": [], - "vars": [], - "uses": ["6:14-6:20|11404881820527069090|3|16420|-1", "6:14-6:20|0|1|64|0"], - "callees": [] + "uses": ["6:14-6:20|16420|-1", "6:14-6:20|64|0"] }, { "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, "short_name": "caller", + "spell": "5:6-5:12|5:1-7:2|2|-1", + "bases": [], + "vars": [], + "callees": ["6:14-6:20|3787803219955606747|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:12|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["6:14-6:20|3787803219955606747|3|16420"] + "uses": [] }], "usr2type": [], "usr2var": [{ @@ -47,13 +48,13 @@ void caller() { "qual_name_offset": 0, "short_name": "MACRO_CALL", "hover": "#define MACRO_CALL(e) e", - "declarations": [], - "spell": "1:9-1:19|0|1|2|-1", - "extent": "1:9-1:24|0|1|0|-1", + "spell": "1:9-1:19|1:9-1:24|2|-1", "type": 0, - "uses": ["6:3-6:13|0|1|64|-1"], "kind": 255, - "storage": 0 + "parent_kind": 1, + "storage": 0, + "declarations": [], + "uses": ["6:3-6:13|64|-1"] }] } */ \ No newline at end of file diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 0d223beca..9ff9b66ce 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -21,57 +21,59 @@ void foo() { "detailed_name": "void called()", "qual_name_offset": 5, "short_name": "called", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:12|1:1-1:14|0|1|1|-1"], - "bases": [], + "declarations": ["1:6-1:12|1:1-1:14|1|-1"], "derived": [], - "vars": [], - "uses": ["5:3-5:9|10177235824697315808|3|16420|-1"], - "callees": [] + "uses": ["5:3-5:9|16420|-1"] }, { "usr": 2459767597003442547, "detailed_name": "", "qual_name_offset": 0, "short_name": "", + "bases": [], + "vars": [], + "callees": ["5:3-5:9|468307235068920063|3|16420"], "kind": 0, + "parent_kind": 0, "storage": 0, "declarations": [], - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["5:3-5:9|468307235068920063|3|16420"] + "uses": [] }, { "usr": 4259594751088586730, "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "8:6-8:9|8:1-10:2|2|-1", + "bases": [], + "vars": [], + "callees": ["9:3-9:9|10177235824697315808|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "8:6-8:9|0|1|2|-1", - "extent": "8:1-10:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["9:3-9:9|10177235824697315808|3|16420"] + "uses": [] }, { "usr": 10177235824697315808, "detailed_name": "void caller()", "qual_name_offset": 5, "short_name": "caller", + "spell": "4:6-4:12|4:1-6:2|2|-1", + "bases": [], + "vars": [], + "callees": ["5:3-5:9|468307235068920063|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "4:6-4:12|0|1|2|-1", - "extent": "4:1-6:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["9:3-9:9|4259594751088586730|3|16420|-1"], - "callees": ["5:3-5:9|468307235068920063|3|16420"] + "uses": ["9:3-9:9|16420|-1"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_called_implicit_ctor.cc b/index_tests/usage/func_called_implicit_ctor.cc index 63a13f2b9..771ab3ce4 100644 --- a/index_tests/usage/func_called_implicit_ctor.cc +++ b/index_tests/usage/func_called_implicit_ctor.cc @@ -18,62 +18,63 @@ Wrapper caller() { "detailed_name": "int called()", "qual_name_offset": 4, "short_name": "called", + "spell": "5:5-5:11|5:1-5:27|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:5-5:11|0|1|2|-1", - "extent": "5:1-5:27|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["8:10-8:16|11404881820527069090|3|16420|-1"], - "callees": [] + "uses": ["8:10-8:16|16420|-1"] }, { "usr": 10544127002917214589, "detailed_name": "Wrapper::Wrapper(int i)", "qual_name_offset": 0, "short_name": "Wrapper", + "bases": [], + "vars": [], + "callees": [], "kind": 9, + "parent_kind": 0, "storage": 0, - "declarations": ["2:3-2:10|2:3-2:17|13611487872560323389|2|1025|-1"], - "bases": [], + "declarations": ["2:3-2:10|2:3-2:17|1025|-1"], "derived": [], - "vars": [], - "uses": ["8:10-8:16|11404881820527069090|3|16676|-1"], - "callees": [] + "uses": ["8:10-8:16|16676|-1"] }, { "usr": 11404881820527069090, "detailed_name": "Wrapper caller()", "qual_name_offset": 8, "short_name": "caller", + "spell": "7:9-7:15|7:1-9:2|2|-1", + "bases": [], + "vars": [], + "callees": ["8:10-8:16|10544127002917214589|3|16676", "8:10-8:16|468307235068920063|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "7:9-7:15|0|1|2|-1", - "extent": "7:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["8:10-8:16|10544127002917214589|3|16676", "8:10-8:16|468307235068920063|3|16420"] + "uses": [] }], "usr2type": [{ "usr": 13611487872560323389, "detailed_name": "struct Wrapper {}", "qual_name_offset": 7, "short_name": "Wrapper", - "kind": 23, - "declarations": [], - "spell": "1:8-1:15|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:15|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [10544127002917214589], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["2:3-2:10|13611487872560323389|2|4|-1", "7:1-7:8|0|1|4|-1"] + "uses": ["2:3-2:10|4|-1", "7:1-7:8|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index 9d4efdb62..b0c5fb4f2 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -17,46 +17,46 @@ void user() { "detailed_name": "void used()", "qual_name_offset": 5, "short_name": "used", + "spell": "3:6-3:10|3:1-3:15|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:10|0|1|2|-1", - "extent": "3:1-3:15|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|132|-1", "7:12-7:16|9376923949268137283|3|132|-1"], - "callees": [] + "uses": ["6:18-6:22|132|-1", "7:12-7:16|132|-1"] }, { "usr": 9376923949268137283, "detailed_name": "void user()", "qual_name_offset": 5, "short_name": "user", + "spell": "5:6-5:10|5:1-8:2|2|-1", + "bases": [], + "vars": [16088407831770615719], + "callees": ["6:18-6:22|5264867802674151787|3|132", "6:18-6:22|5264867802674151787|3|132", "7:3-7:10|12924914488846929470|3|16420", "7:12-7:16|5264867802674151787|3|132"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2|-1", - "extent": "5:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [16088407831770615719], - "uses": [], - "callees": ["6:18-6:22|5264867802674151787|3|132", "6:18-6:22|5264867802674151787|3|132", "7:3-7:10|12924914488846929470|3|16420", "7:12-7:16|5264867802674151787|3|132"] + "uses": [] }, { "usr": 12924914488846929470, "detailed_name": "void consume(void (*)())", "qual_name_offset": 5, "short_name": "consume", + "spell": "1:6-1:13|1:1-1:28|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:13|0|1|2|-1", - "extent": "1:1-1:28|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["7:3-7:10|9376923949268137283|3|16420|-1"], - "callees": [] + "uses": ["7:3-7:10|16420|-1"] }], "usr2type": [], "usr2var": [{ @@ -65,13 +65,13 @@ void user() { "qual_name_offset": 7, "short_name": "x", "hover": "void (*x)() = &used", - "declarations": [], - "spell": "6:10-6:11|9376923949268137283|3|2|-1", - "extent": "6:3-6:22|9376923949268137283|3|0|-1", + "spell": "6:10-6:11|6:3-6:22|2|-1", "type": 0, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index e8242960e..3e0582daf 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -17,47 +17,48 @@ void user() { "detailed_name": "void user()", "qual_name_offset": 5, "short_name": "user", + "spell": "5:6-5:10|5:1-7:2|2|-1", + "bases": [], + "vars": [4636142131003982569], + "callees": ["6:18-6:22|18417145003926999463|3|132", "6:18-6:22|18417145003926999463|3|132"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [4636142131003982569], - "uses": [], - "callees": ["6:18-6:22|18417145003926999463|3|132", "6:18-6:22|18417145003926999463|3|132"] + "uses": [] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", "qual_name_offset": 5, "short_name": "Used", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["2:8-2:12|2:3-2:14|1025|-1"], "derived": [], - "vars": [], - "uses": ["6:18-6:22|9376923949268137283|3|132|-1"], - "callees": [] + "uses": ["6:18-6:22|132|-1"] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [18417145003926999463], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["6:13-6:16|9376923949268137283|3|4|-1"] + "uses": ["6:13-6:16|4|-1"] }], "usr2var": [{ "usr": 4636142131003982569, @@ -65,13 +66,13 @@ void user() { "qual_name_offset": 16, "short_name": "x", "hover": "void (Foo::*)() x = &Foo::Used", - "declarations": [], - "spell": "6:8-6:9|9376923949268137283|3|2|-1", - "extent": "6:3-6:22|9376923949268137283|3|0|-1", + "spell": "6:8-6:9|6:3-6:22|2|-1", "type": 0, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/func_usage_call_func.cc b/index_tests/usage/func_usage_call_func.cc index 0ec91f0a7..298411347 100644 --- a/index_tests/usage/func_usage_call_func.cc +++ b/index_tests/usage/func_usage_call_func.cc @@ -13,31 +13,31 @@ void caller() { "detailed_name": "void called()", "qual_name_offset": 5, "short_name": "called", + "spell": "1:6-1:12|1:1-1:17|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2|-1", - "extent": "1:1-1:17|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["3:3-3:9|11404881820527069090|3|16420|-1"], - "callees": [] + "uses": ["3:3-3:9|16420|-1"] }, { "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, "short_name": "caller", + "spell": "2:6-2:12|2:1-4:2|2|-1", + "bases": [], + "vars": [], + "callees": ["3:3-3:9|468307235068920063|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "2:6-2:12|0|1|2|-1", - "extent": "2:1-4:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["3:3-3:9|468307235068920063|3|16420"] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index 726f13fd2..6e86be512 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -17,47 +17,48 @@ void user() { "detailed_name": "void user()", "qual_name_offset": 5, "short_name": "user", + "spell": "5:6-5:10|5:1-8:2|2|-1", + "bases": [], + "vars": [14045150712868309451], + "callees": ["7:6-7:10|18417145003926999463|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:10|0|1|2|-1", - "extent": "5:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [14045150712868309451], - "uses": [], - "callees": ["7:6-7:10|18417145003926999463|3|16420"] + "uses": [] }, { "usr": 18417145003926999463, "detailed_name": "void Foo::Used()", "qual_name_offset": 5, "short_name": "Used", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["2:8-2:12|2:3-2:14|1025|-1"], "derived": [], - "vars": [], - "uses": ["7:6-7:10|9376923949268137283|3|16420|-1"], - "callees": [] + "uses": ["7:6-7:10|16420|-1"] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [18417145003926999463], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [14045150712868309451], - "uses": ["6:3-6:6|9376923949268137283|3|4|-1"] + "uses": ["6:3-6:6|4|-1"] }], "usr2var": [{ "usr": 14045150712868309451, @@ -65,13 +66,13 @@ void user() { "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", - "declarations": [], - "spell": "6:8-6:9|9376923949268137283|3|2|-1", - "extent": "6:3-6:19|9376923949268137283|3|0|-1", + "spell": "6:8-6:9|6:3-6:19|2|-1", "type": 15041163540773201510, - "uses": ["7:3-7:4|9376923949268137283|3|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["7:3-7:4|12|-1"] }] } */ diff --git a/index_tests/usage/func_usage_class_inline_var_def.cc b/index_tests/usage/func_usage_class_inline_var_def.cc index 6872016b4..f62581eae 100644 --- a/index_tests/usage/func_usage_class_inline_var_def.cc +++ b/index_tests/usage/func_usage_class_inline_var_def.cc @@ -16,30 +16,31 @@ class Foo { "detailed_name": "static int helper()", "qual_name_offset": 11, "short_name": "helper", + "spell": "1:12-1:18|1:1-3:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:12-1:18|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["6:11-6:17|15041163540773201510|2|36|-1"], - "callees": [] + "uses": ["6:11-6:17|36|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [4220150017963593039], "uses": [] }, { @@ -47,19 +48,19 @@ class Foo { "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "5:7-5:10|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "alias_of": 0, + "spell": "5:7-5:10|5:1-7:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 4220150017963593039, "R": 0 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -69,13 +70,13 @@ class Foo { "qual_name_offset": 4, "short_name": "x", "hover": "int Foo::x = helper()", - "declarations": [], - "spell": "6:7-6:8|15041163540773201510|2|1026|-1", - "extent": "6:3-6:19|15041163540773201510|2|0|-1", + "spell": "6:7-6:8|6:3-6:19|1026|-1", "type": 53, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/func_usage_forward_decl_func.cc b/index_tests/usage/func_usage_forward_decl_func.cc index 1e7cef98e..06a1e767b 100644 --- a/index_tests/usage/func_usage_forward_decl_func.cc +++ b/index_tests/usage/func_usage_forward_decl_func.cc @@ -13,29 +13,30 @@ void usage() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:9|1:1-1:11|0|1|1|-1"], - "bases": [], + "declarations": ["1:6-1:9|1:1-1:11|1|-1"], "derived": [], - "vars": [], - "uses": ["4:3-4:6|6767773193109753523|3|16420|-1"], - "callees": [] + "uses": ["4:3-4:6|16420|-1"] }, { "usr": 6767773193109753523, "detailed_name": "void usage()", "qual_name_offset": 5, "short_name": "usage", + "spell": "3:6-3:11|3:1-5:2|2|-1", + "bases": [], + "vars": [], + "callees": ["4:3-4:6|4259594751088586730|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:11|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["4:3-4:6|4259594751088586730|3|16420"] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 9fdfb1edd..7da093ea0 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -16,47 +16,48 @@ void usage() { "detailed_name": "void usage()", "qual_name_offset": 5, "short_name": "usage", + "spell": "5:6-5:11|5:1-8:2|2|-1", + "bases": [], + "vars": [16229832321010999607], + "callees": ["7:6-7:9|17922201480358737771|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:11|0|1|2|-1", - "extent": "5:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [16229832321010999607], - "uses": [], - "callees": ["7:6-7:9|17922201480358737771|3|16420"] + "uses": [] }, { "usr": 17922201480358737771, "detailed_name": "void Foo::foo()", "qual_name_offset": 5, "short_name": "foo", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 0, "storage": 0, - "declarations": ["2:8-2:11|2:3-2:13|15041163540773201510|2|1025|-1"], - "bases": [], + "declarations": ["2:8-2:11|2:3-2:13|1025|-1"], "derived": [], - "vars": [], - "uses": ["7:6-7:9|6767773193109753523|3|16420|-1"], - "callees": [] + "uses": ["7:6-7:9|16420|-1"] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17922201480358737771], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16229832321010999607], - "uses": ["6:3-6:6|6767773193109753523|3|4|-1"] + "uses": ["6:3-6:6|4|-1"] }], "usr2var": [{ "usr": 16229832321010999607, @@ -64,13 +65,13 @@ void usage() { "qual_name_offset": 5, "short_name": "f", "hover": "Foo *f = nullptr", - "declarations": [], - "spell": "6:8-6:9|6767773193109753523|3|2|-1", - "extent": "6:3-6:19|6767773193109753523|3|0|-1", + "spell": "6:8-6:9|6:3-6:19|2|-1", "type": 15041163540773201510, - "uses": ["7:3-7:4|6767773193109753523|3|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["7:3-7:4|12|-1"] }] } */ diff --git a/index_tests/usage/func_usage_template_func.cc b/index_tests/usage/func_usage_template_func.cc index 72e6e6701..6a812a46c 100644 --- a/index_tests/usage/func_usage_template_func.cc +++ b/index_tests/usage/func_usage_template_func.cc @@ -16,29 +16,30 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "4:6-4:9|4:1-7:2|2|-1", + "bases": [], + "vars": [], + "callees": ["5:3-5:9|10585861037135727329|3|16420", "6:3-6:9|10585861037135727329|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2|-1", - "extent": "4:1-7:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["5:3-5:9|10585861037135727329|3|16420", "6:3-6:9|10585861037135727329|3|16420"] + "uses": [] }, { "usr": 10585861037135727329, "detailed_name": "void accept(T)", "qual_name_offset": 5, "short_name": "accept", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["2:6-2:12|2:1-2:15|0|1|1|-1"], - "bases": [], + "declarations": ["2:6-2:12|2:1-2:15|1|-1"], "derived": [], - "vars": [], - "uses": ["5:3-5:9|4259594751088586730|3|16420|-1", "6:3-6:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["5:3-5:9|16420|-1", "6:3-6:9|16420|-1"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 169d5ad47..f13a593f3 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -20,88 +20,88 @@ unique_ptr* return_type() { "detailed_name": "unique_ptr *return_type()", "qual_name_offset": 15, "short_name": "return_type", + "spell": "9:16-9:27|9:1-12:2|2|-1", + "bases": [], + "vars": [3364438781074774169], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "9:16-9:27|0|1|2|-1", - "extent": "9:1-12:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [3364438781074774169], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 3286534761799572592, "detailed_name": "class unique_ptr {}", "qual_name_offset": 6, "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "2:1-2:20|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:17|2:1-2:20|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [12857919739649552168, 18075066956054788088, 3364438781074774169], - "uses": ["6:8-6:18|0|1|4|-1", "7:8-7:18|0|1|4|-1", "9:1-9:11|0|1|4|-1", "10:3-10:13|16359708726068806331|3|4|-1"] + "uses": ["6:8-6:18|4|-1", "7:8-7:18|4|-1", "9:1-9:11|4|-1", "10:3-10:13|4|-1"] }, { "usr": 4750332761459066907, "detailed_name": "struct S {}", "qual_name_offset": 7, "short_name": "S", - "kind": 23, - "declarations": [], - "spell": "4:8-4:9|0|1|2|-1", - "extent": "4:1-4:12|0|1|0|-1", - "alias_of": 0, + "spell": "4:8-4:9|4:1-4:12|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:19-7:20|0|1|4|-1", "9:12-9:13|0|1|4|-1", "10:14-10:15|16359708726068806331|3|4|-1"] + "uses": ["7:19-7:20|4|-1", "9:12-9:13|4|-1", "10:14-10:15|4|-1"] }], "usr2var": [{ "usr": 3364438781074774169, "detailed_name": "unique_ptr *local", "qual_name_offset": 15, "short_name": "local", - "declarations": [], - "spell": "10:18-10:23|16359708726068806331|3|2|-1", - "extent": "10:3-10:23|16359708726068806331|3|0|-1", + "spell": "10:18-10:23|10:3-10:23|2|-1", "type": 3286534761799572592, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 12857919739649552168, "detailed_name": "static unique_ptr f0", "qual_name_offset": 24, "short_name": "f0", - "declarations": [], - "spell": "6:25-6:27|0|1|2|-1", - "extent": "6:1-6:27|0|1|0|-1", + "spell": "6:25-6:27|6:1-6:27|2|-1", "type": 3286534761799572592, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }, { "usr": 18075066956054788088, "detailed_name": "static unique_ptr f1", "qual_name_offset": 21, "short_name": "f1", - "declarations": [], - "spell": "7:22-7:24|0|1|2|-1", - "extent": "7:1-7:24|0|1|0|-1", + "spell": "7:22-7:24|7:1-7:24|2|-1", "type": 3286534761799572592, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 3ed6d40dc..4dedd1317 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -88,147 +88,151 @@ unique_ptr* Foo::foo() { return nullptr; } "detailed_name": "unique_ptr, S2> *as_return_type(unique_ptr *)", "qual_name_offset": 36, "short_name": "as_return_type", + "spell": "33:37-33:51|33:1-33:92|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "33:37-33:51|0|1|2|-1", - "extent": "33:1-33:92|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 13067214284561914253, "detailed_name": "void no_return_type(int)", "qual_name_offset": 5, "short_name": "no_return_type", + "spell": "40:6-40:20|40:1-40:28|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "40:6-40:20|0|1|2|-1", - "extent": "40:1-40:28|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 17922201480358737771, "detailed_name": "unique_ptr *Foo::foo()", "qual_name_offset": 20, "short_name": "foo", + "spell": "79:26-79:29|79:1-79:51|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["65:23-65:26|65:3-65:28|15041163540773201510|2|1025|-1"], - "spell": "79:26-79:29|15041163540773201510|2|1026|-1", - "extent": "79:1-79:51|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["65:23-65:26|65:3-65:28|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 18320186404467436976, "detailed_name": "void empty()", "qual_name_offset": 5, "short_name": "empty", + "spell": "53:6-53:11|53:1-55:2|2|-1", + "bases": [], + "vars": [500112618220246], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "53:6-53:11|0|1|2|-1", - "extent": "53:1-55:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [500112618220246], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 4310164820010458371, "detailed_name": "struct S1", "qual_name_offset": 7, "short_name": "S1", - "kind": 23, - "declarations": ["4:8-4:10|4:1-4:10|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["4:8-4:10|4:1-4:10|1|-1"], + "derived": [], "instances": [], - "uses": ["15:30-15:32|0|1|4|-1", "33:23-33:25|0|1|4|-1", "33:63-33:65|0|1|4|-1", "54:25-54:27|18320186404467436976|3|4|-1", "65:14-65:16|15041163540773201510|2|4|-1", "79:12-79:14|0|1|4|-1"] + "uses": ["15:30-15:32|4|-1", "33:23-33:25|4|-1", "33:63-33:65|4|-1", "54:25-54:27|4|-1", "65:14-65:16|4|-1", "79:12-79:14|4|-1"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", "qual_name_offset": 7, "short_name": "S2", - "kind": 23, - "declarations": ["5:8-5:10|5:1-5:10|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["5:8-5:10|5:1-5:10|1|-1"], + "derived": [], "instances": [], - "uses": ["15:34-15:36|0|1|4|-1", "15:39-15:41|0|1|4|-1", "33:27-33:29|0|1|4|-1", "33:32-33:34|0|1|4|-1", "33:67-33:69|0|1|4|-1", "54:29-54:31|18320186404467436976|3|4|-1", "54:34-54:36|18320186404467436976|3|4|-1", "65:18-65:20|15041163540773201510|2|4|-1", "79:16-79:18|0|1|4|-1"] + "uses": ["15:34-15:36|4|-1", "15:39-15:41|4|-1", "33:27-33:29|4|-1", "33:32-33:34|4|-1", "33:67-33:69|4|-1", "54:29-54:31|4|-1", "54:34-54:36|4|-1", "65:18-65:20|4|-1", "79:16-79:18|4|-1"] }, { "usr": 14209198335088845323, "detailed_name": "class unique_ptr", "qual_name_offset": 6, "short_name": "unique_ptr", - "kind": 5, - "declarations": ["2:7-2:17|2:1-2:17|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["2:7-2:17|2:1-2:17|1|-1"], + "derived": [], "instances": [2933643612409209903, 500112618220246], - "uses": ["15:8-15:18|0|1|4|-1", "15:19-15:29|0|1|4|-1", "33:1-33:11|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] + "uses": ["15:8-15:18|4|-1", "15:19-15:29|4|-1", "33:1-33:11|4|-1", "33:12-33:22|4|-1", "33:52-33:62|4|-1", "54:3-54:13|4|-1", "54:14-54:24|4|-1", "65:3-65:13|4|-1", "79:1-79:11|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "64:7-64:10|0|1|2|-1", - "extent": "64:1-66:2|0|1|0|-1", - "alias_of": 0, + "spell": "64:7-64:10|64:1-66:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [17922201480358737771], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["79:21-79:24|0|1|4|-1"] + "uses": ["79:21-79:24|4|-1"] }], "usr2var": [{ "usr": 500112618220246, "detailed_name": "unique_ptr, S2> *local", "qual_name_offset": 36, "short_name": "local", - "declarations": [], - "spell": "54:39-54:44|18320186404467436976|3|2|-1", - "extent": "54:3-54:44|18320186404467436976|3|0|-1", + "spell": "54:39-54:44|54:3-54:44|2|-1", "type": 14209198335088845323, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 2933643612409209903, "detailed_name": "extern unique_ptr, S2> f", "qual_name_offset": 42, "short_name": "f", - "declarations": ["15:43-15:44|15:1-15:44|0|1|1|-1"], "type": 14209198335088845323, - "uses": [], "kind": 13, - "storage": 1 + "parent_kind": 0, + "storage": 1, + "declarations": ["15:43-15:44|15:1-15:44|1|-1"], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc index 9f7c8da2f..75c9d63ed 100644 --- a/index_tests/usage/type_usage_as_template_parameter_simple.cc +++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc @@ -16,46 +16,47 @@ static unique_ptr foo; "detailed_name": "class unique_ptr {}", "qual_name_offset": 6, "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "spell": "2:7-2:17|0|1|2|-1", - "extent": "2:1-2:20|0|1|0|-1", - "alias_of": 0, + "spell": "2:7-2:17|2:1-2:20|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [3398408600781120939], - "uses": ["6:8-6:18|0|1|4|-1"] + "uses": ["6:8-6:18|4|-1"] }, { "usr": 4750332761459066907, "detailed_name": "struct S", "qual_name_offset": 7, "short_name": "S", - "kind": 23, - "declarations": ["4:8-4:9|4:1-4:9|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["4:8-4:9|4:1-4:9|1|-1"], + "derived": [], "instances": [], - "uses": ["6:19-6:20|0|1|4|-1"] + "uses": ["6:19-6:20|4|-1"] }], "usr2var": [{ "usr": 3398408600781120939, "detailed_name": "static unique_ptr foo", "qual_name_offset": 21, "short_name": "foo", - "declarations": [], - "spell": "6:22-6:25|0|1|2|-1", - "extent": "6:1-6:25|0|1|0|-1", + "spell": "6:22-6:25|6:1-6:25|2|-1", "type": 3286534761799572592, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_extern.cc b/index_tests/usage/type_usage_declare_extern.cc index 4d09cd857..afe6962f1 100644 --- a/index_tests/usage/type_usage_declare_extern.cc +++ b/index_tests/usage/type_usage_declare_extern.cc @@ -12,29 +12,30 @@ extern T t; "detailed_name": "struct T {}", "qual_name_offset": 7, "short_name": "T", - "kind": 23, - "declarations": [], - "spell": "1:8-1:9|0|1|2|-1", - "extent": "1:1-1:12|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:9|1:1-1:12|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [1346710425945444872], - "uses": ["3:8-3:9|0|1|4|-1"] + "uses": ["3:8-3:9|4|-1"] }], "usr2var": [{ "usr": 1346710425945444872, "detailed_name": "extern T t", "qual_name_offset": 9, "short_name": "t", - "declarations": ["3:10-3:11|3:1-3:11|0|1|1|-1"], "type": 5673439900521455039, - "uses": [], "kind": 13, - "storage": 1 + "parent_kind": 0, + "storage": 1, + "declarations": ["3:10-3:11|3:1-3:11|1|-1"], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_field.cc b/index_tests/usage/type_usage_declare_field.cc index 09cae9e57..fe6f1afb9 100644 --- a/index_tests/usage/type_usage_declare_field.cc +++ b/index_tests/usage/type_usage_declare_field.cc @@ -17,47 +17,43 @@ struct Foo { "detailed_name": "struct ImplementedType {}", "qual_name_offset": 7, "short_name": "ImplementedType", - "kind": 23, - "declarations": [], - "spell": "2:8-2:23|0|1|2|-1", - "extent": "2:1-2:26|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:23|2:1-2:26|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [14727441168849658842], - "uses": ["6:3-6:18|15041163540773201510|2|4|-1"] + "uses": ["6:3-6:18|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:19|1:1-1:19|1|-1"], + "derived": [], "instances": [14314859014962085433], - "uses": ["5:3-5:14|15041163540773201510|2|4|-1"] + "uses": ["5:3-5:14|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "4:8-4:11|0|1|2|-1", - "extent": "4:1-7:2|0|1|0|-1", - "alias_of": 0, + "spell": "4:8-4:11|4:1-7:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 14314859014962085433, "R": 0 @@ -65,6 +61,11 @@ struct Foo { "L": 14727441168849658842, "R": 64 }], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -73,25 +74,25 @@ struct Foo { "detailed_name": "ForwardType *Foo::a", "qual_name_offset": 13, "short_name": "a", - "declarations": [], - "spell": "5:16-5:17|15041163540773201510|2|1026|-1", - "extent": "5:3-5:17|15041163540773201510|2|0|-1", + "spell": "5:16-5:17|5:3-5:17|1026|-1", "type": 13749354388332789217, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 14727441168849658842, "detailed_name": "ImplementedType Foo::b", "qual_name_offset": 16, "short_name": "b", - "declarations": [], - "spell": "6:19-6:20|15041163540773201510|2|1026|-1", - "extent": "6:3-6:20|15041163540773201510|2|0|-1", + "spell": "6:19-6:20|6:3-6:20|1026|-1", "type": 8508299082070213750, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index 39fd917dd..82415f552 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -16,74 +16,75 @@ void Foo() { "detailed_name": "void Foo()", "qual_name_offset": 5, "short_name": "Foo", + "spell": "4:6-4:9|4:1-7:2|2|-1", + "bases": [], + "vars": [16374832544037266261, 2580122838476012357], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2|-1", - "extent": "4:1-7:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [16374832544037266261, 2580122838476012357], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 8508299082070213750, "detailed_name": "struct ImplementedType {}", "qual_name_offset": 7, "short_name": "ImplementedType", - "kind": 23, - "declarations": [], - "spell": "2:8-2:23|0|1|2|-1", - "extent": "2:1-2:26|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:23|2:1-2:26|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [2580122838476012357], - "uses": ["6:3-6:18|4654328188330986029|3|4|-1"] + "uses": ["6:3-6:18|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:19|1:1-1:19|1|-1"], + "derived": [], "instances": [16374832544037266261], - "uses": ["5:3-5:14|4654328188330986029|3|4|-1"] + "uses": ["5:3-5:14|4|-1"] }], "usr2var": [{ "usr": 2580122838476012357, "detailed_name": "ImplementedType b", "qual_name_offset": 16, "short_name": "b", - "declarations": [], - "spell": "6:19-6:20|4654328188330986029|3|2|-1", - "extent": "6:3-6:20|4654328188330986029|3|0|-1", + "spell": "6:19-6:20|6:3-6:20|2|-1", "type": 8508299082070213750, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 16374832544037266261, "detailed_name": "ForwardType *a", "qual_name_offset": 13, "short_name": "a", - "declarations": [], - "spell": "5:16-5:17|4654328188330986029|3|2|-1", - "extent": "5:3-5:17|4654328188330986029|3|0|-1", + "spell": "5:16-5:17|5:3-5:17|2|-1", "type": 13749354388332789217, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 1570ef020..ae7c00063 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -13,74 +13,75 @@ void foo(ForwardType* f, ImplementedType a) {} "detailed_name": "void foo(ForwardType *f, ImplementedType a)", "qual_name_offset": 5, "short_name": "foo", + "spell": "4:6-4:9|4:1-4:47|2|-1", + "bases": [], + "vars": [13058491096576226774, 11055777568039014776], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|2|-1", - "extent": "4:1-4:47|0|1|0|-1", - "bases": [], "derived": [], - "vars": [13058491096576226774, 11055777568039014776], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 8508299082070213750, "detailed_name": "struct ImplementedType {}", "qual_name_offset": 7, "short_name": "ImplementedType", - "kind": 23, - "declarations": [], - "spell": "2:8-2:23|0|1|2|-1", - "extent": "2:1-2:26|0|1|0|-1", - "alias_of": 0, + "spell": "2:8-2:23|2:1-2:26|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [11055777568039014776], - "uses": ["4:26-4:41|0|1|4|-1"] + "uses": ["4:26-4:41|4|-1"] }, { "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:19|1:1-1:19|1|-1"], + "derived": [], "instances": [13058491096576226774], - "uses": ["4:10-4:21|0|1|4|-1"] + "uses": ["4:10-4:21|4|-1"] }], "usr2var": [{ "usr": 11055777568039014776, "detailed_name": "ImplementedType a", "qual_name_offset": 16, "short_name": "a", - "declarations": [], - "spell": "4:42-4:43|1699390678058422036|3|1026|-1", - "extent": "4:26-4:43|1699390678058422036|3|0|-1", + "spell": "4:42-4:43|4:26-4:43|1026|-1", "type": 8508299082070213750, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 13058491096576226774, "detailed_name": "ForwardType *f", "qual_name_offset": 13, "short_name": "f", - "declarations": [], - "spell": "4:23-4:24|1699390678058422036|3|1026|-1", - "extent": "4:10-4:24|1699390678058422036|3|0|-1", + "spell": "4:23-4:24|4:10-4:24|1026|-1", "type": 13749354388332789217, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 3f205c9da..7c33416a7 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -18,45 +18,46 @@ void foo(Foo* f, Foo*) {} "detailed_name": "void foo(Foo *f, Foo *)", "qual_name_offset": 5, "short_name": "foo", + "spell": "4:6-4:9|4:1-4:26|2|-1", + "bases": [], + "vars": [13823260660189154978], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["3:6-3:9|3:1-3:23|0|1|1|-1"], - "spell": "4:6-4:9|0|1|2|-1", - "extent": "4:1-4:26|0|1|0|-1", - "bases": [], + "declarations": ["3:6-3:9|3:1-3:23|1|-1"], "derived": [], - "vars": [13823260660189154978], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:11|1:1-1:11|1|-1"], + "derived": [], "instances": [13823260660189154978], - "uses": ["3:10-3:13|0|1|4|-1", "3:18-3:21|0|1|4|-1", "4:10-4:13|0|1|4|-1", "4:18-4:21|0|1|4|-1"] + "uses": ["3:10-3:13|4|-1", "3:18-3:21|4|-1", "4:10-4:13|4|-1", "4:18-4:21|4|-1"] }], "usr2var": [{ "usr": 13823260660189154978, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", - "declarations": [], - "spell": "4:15-4:16|8908726657907936744|3|1026|-1", - "extent": "4:10-4:16|8908726657907936744|3|0|-1", + "spell": "4:15-4:16|4:10-4:16|1026|-1", "type": 15041163540773201510, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_param_unnamed.cc b/index_tests/usage/type_usage_declare_param_unnamed.cc index f50fab00c..292087394 100644 --- a/index_tests/usage/type_usage_declare_param_unnamed.cc +++ b/index_tests/usage/type_usage_declare_param_unnamed.cc @@ -10,32 +10,33 @@ void foo(ForwardType*) {} "detailed_name": "void foo(ForwardType *)", "qual_name_offset": 5, "short_name": "foo", + "spell": "2:6-2:9|2:1-2:26|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "2:6-2:9|0|1|2|-1", - "extent": "2:1-2:26|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 13749354388332789217, "detailed_name": "struct ForwardType", "qual_name_offset": 7, "short_name": "ForwardType", - "kind": 23, - "declarations": ["1:8-1:19|1:1-1:19|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:19|1:1-1:19|1|-1"], + "derived": [], "instances": [], - "uses": ["2:10-2:21|0|1|4|-1"] + "uses": ["2:10-2:21|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index ec1f4d9c4..b6131373b 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -16,108 +16,108 @@ void foo(Type& a0, const Type& a1) { "detailed_name": "void foo(Type &a0, const Type &a1)", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-8:2|2|-1", + "bases": [], + "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 13487927231218873822, "detailed_name": "struct Type {}", "qual_name_offset": 7, "short_name": "Type", - "kind": 23, - "declarations": [], - "spell": "1:8-1:12|0|1|2|-1", - "extent": "1:1-1:15|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:12|1:1-1:15|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [7997456978847868736, 17228576662112939520, 15429032129697337561, 6081981442495435784, 5004072032239834773, 14939253431683105646], - "uses": ["3:10-3:14|0|1|4|-1", "3:26-3:30|0|1|4|-1", "4:3-4:7|16858540520096802573|3|4|-1", "5:3-5:7|16858540520096802573|3|4|-1", "6:9-6:13|16858540520096802573|3|4|-1", "7:9-7:13|16858540520096802573|3|4|-1"] + "uses": ["3:10-3:14|4|-1", "3:26-3:30|4|-1", "4:3-4:7|4|-1", "5:3-5:7|4|-1", "6:9-6:13|4|-1", "7:9-7:13|4|-1"] }], "usr2var": [{ "usr": 5004072032239834773, "detailed_name": "const Type *a4", "qual_name_offset": 12, "short_name": "a4", - "declarations": [], - "spell": "6:15-6:17|16858540520096802573|3|2|-1", - "extent": "6:3-6:17|16858540520096802573|3|0|-1", + "spell": "6:15-6:17|6:3-6:17|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 6081981442495435784, "detailed_name": "Type *a3", "qual_name_offset": 6, "short_name": "a3", - "declarations": [], - "spell": "5:9-5:11|16858540520096802573|3|2|-1", - "extent": "5:3-5:11|16858540520096802573|3|0|-1", + "spell": "5:9-5:11|5:3-5:11|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 7997456978847868736, "detailed_name": "Type &a0", "qual_name_offset": 6, "short_name": "a0", - "declarations": [], - "spell": "3:16-3:18|16858540520096802573|3|1026|-1", - "extent": "3:10-3:18|16858540520096802573|3|0|-1", + "spell": "3:16-3:18|3:10-3:18|1026|-1", "type": 13487927231218873822, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 14939253431683105646, "detailed_name": "const Type *const a5", "qual_name_offset": 18, "short_name": "a5", "hover": "const Type *const a5 = nullptr", - "declarations": [], - "spell": "7:21-7:23|16858540520096802573|3|2|-1", - "extent": "7:3-7:33|16858540520096802573|3|0|-1", + "spell": "7:21-7:23|7:3-7:33|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 15429032129697337561, "detailed_name": "Type a2", "qual_name_offset": 5, "short_name": "a2", - "declarations": [], - "spell": "4:8-4:10|16858540520096802573|3|2|-1", - "extent": "4:3-4:10|16858540520096802573|3|0|-1", + "spell": "4:8-4:10|4:3-4:10|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 17228576662112939520, "detailed_name": "const Type &a1", "qual_name_offset": 12, "short_name": "a1", - "declarations": [], - "spell": "3:32-3:34|16858540520096802573|3|1026|-1", - "extent": "3:20-3:34|16858540520096802573|3|0|-1", + "spell": "3:32-3:34|3:20-3:34|1026|-1", "type": 13487927231218873822, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_declare_static.cc b/index_tests/usage/type_usage_declare_static.cc index ccff19e21..3957ceb21 100644 --- a/index_tests/usage/type_usage_declare_static.cc +++ b/index_tests/usage/type_usage_declare_static.cc @@ -11,31 +11,31 @@ static Type t; "detailed_name": "struct Type {}", "qual_name_offset": 7, "short_name": "Type", - "kind": 23, - "declarations": [], - "spell": "1:8-1:12|0|1|2|-1", - "extent": "1:1-1:15|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:12|1:1-1:15|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [6601831367240627080], - "uses": ["2:8-2:12|0|1|4|-1"] + "uses": ["2:8-2:12|4|-1"] }], "usr2var": [{ "usr": 6601831367240627080, "detailed_name": "static Type t", "qual_name_offset": 12, "short_name": "t", - "declarations": [], - "spell": "2:13-2:14|0|1|2|-1", - "extent": "2:1-2:14|0|1|0|-1", + "spell": "2:13-2:14|2:1-2:14|2|-1", "type": 13487927231218873822, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 7a07f9738..cb6ef08e6 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -27,107 +27,109 @@ static Type* bar() { return nullptr; } "detailed_name": "void Foo::Empty()", "qual_name_offset": 5, "short_name": "Empty", + "spell": "13:11-13:16|13:1-13:21|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["9:8-9:13|9:3-9:15|15041163540773201510|2|1025|-1"], - "spell": "13:11-13:16|15041163540773201510|2|1026|-1", - "extent": "13:1-13:21|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["9:8-9:13|9:3-9:15|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 4259594751088586730, "detailed_name": "Type *foo()", "qual_name_offset": 6, "short_name": "foo", + "spell": "5:7-5:10|5:1-5:32|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["3:7-3:10|3:1-3:12|0|1|1|-1", "4:7-4:10|4:1-4:12|0|1|1|-1"], - "spell": "5:7-5:10|0|1|2|-1", - "extent": "5:1-5:32|0|1|0|-1", - "bases": [], + "declarations": ["3:7-3:10|3:1-3:12|1|-1", "4:7-4:10|4:1-4:12|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 7746867874366499515, "detailed_name": "extern const Type &external()", "qual_name_offset": 19, "short_name": "external", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["15:20-15:28|15:1-15:30|0|1|1|-1"], - "bases": [], + "declarations": ["15:20-15:28|15:1-15:30|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 13402221340333431092, "detailed_name": "Type *Foo::Get(int)", "qual_name_offset": 6, "short_name": "Get", + "spell": "12:12-12:15|12:1-12:40|1026|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["8:9-8:12|8:3-8:17|15041163540773201510|2|1025|-1"], - "spell": "12:12-12:15|15041163540773201510|2|1026|-1", - "extent": "12:1-12:40|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["8:9-8:12|8:3-8:17|1025|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 18408440185620243373, "detailed_name": "static Type *bar()", "qual_name_offset": 13, "short_name": "bar", + "spell": "18:14-18:17|18:1-18:39|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["17:14-17:17|17:1-17:19|0|1|1|-1"], - "spell": "18:14-18:17|0|1|2|-1", - "extent": "18:1-18:39|0|1|0|-1", - "bases": [], + "declarations": ["17:14-17:17|17:1-17:19|1|-1"], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 13487927231218873822, "detailed_name": "struct Type", "qual_name_offset": 7, "short_name": "Type", - "kind": 23, - "declarations": ["1:8-1:12|1:1-1:12|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:12|1:1-1:12|1|-1"], + "derived": [], "instances": [], - "uses": ["3:1-3:5|0|1|4|-1", "4:1-4:5|0|1|4|-1", "5:1-5:5|0|1|4|-1", "8:3-8:7|15041163540773201510|2|4|-1", "12:1-12:5|0|1|4|-1", "15:14-15:18|0|1|4|-1", "17:8-17:12|0|1|4|-1", "18:8-18:12|0|1|4|-1"] + "uses": ["3:1-3:5|4|-1", "4:1-4:5|4|-1", "5:1-5:5|4|-1", "8:3-8:7|4|-1", "12:1-12:5|4|-1", "15:14-15:18|4|-1", "17:8-17:12|4|-1", "18:8-18:12|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "7:7-7:10|0|1|2|-1", - "extent": "7:1-10:2|0|1|0|-1", - "alias_of": 0, + "spell": "7:7-7:10|7:1-10:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [13402221340333431092, 4240751906910175539], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["12:7-12:10|0|1|4|-1", "13:6-13:9|0|1|4|-1"] + "uses": ["12:7-12:10|4|-1", "13:6-13:9|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_typedef_and_using.cc b/index_tests/usage/type_usage_typedef_and_using.cc index 65ca72f32..58c82325d 100644 --- a/index_tests/usage/type_usage_typedef_and_using.cc +++ b/index_tests/usage/type_usage_typedef_and_using.cc @@ -19,94 +19,94 @@ void accept3(Foo3*) {} "detailed_name": "void accept1(Foo1 *)", "qual_name_offset": 5, "short_name": "accept1", + "spell": "8:6-8:13|8:1-8:23|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "8:6-8:13|0|1|2|-1", - "extent": "8:1-8:23|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 9119341505144503905, "detailed_name": "void accept(Foo *)", "qual_name_offset": 5, "short_name": "accept", + "spell": "7:6-7:12|7:1-7:21|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "7:6-7:12|0|1|2|-1", - "extent": "7:1-7:21|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 10523262907746124479, "detailed_name": "void accept2(Foo2 *)", "qual_name_offset": 5, "short_name": "accept2", + "spell": "9:6-9:13|9:1-9:23|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "9:6-9:13|0|1|2|-1", - "extent": "9:1-9:23|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }, { "usr": 14986366321326974406, "detailed_name": "void accept3(Foo3 *)", "qual_name_offset": 5, "short_name": "accept3", + "spell": "10:6-10:13|10:1-10:23|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "10:6-10:13|0|1|2|-1", - "extent": "10:1-10:23|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 1544499294580512394, "detailed_name": "using Foo1 = Foo *", "qual_name_offset": 6, "short_name": "Foo1", - "kind": 252, - "declarations": [], - "spell": "2:7-2:11|0|1|2|-1", - "extent": "2:1-2:18|0|1|0|-1", - "alias_of": 15041163540773201510, + "spell": "2:7-2:11|2:1-2:18|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 15041163540773201510, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["4:14-4:18|0|1|4|-1", "8:14-8:18|0|1|4|-1"] + "uses": ["4:14-4:18|4|-1", "8:14-8:18|4|-1"] }, { "usr": 2638219001294786365, "detailed_name": "using Foo4 = int", "qual_name_offset": 6, "short_name": "Foo4", - "kind": 252, - "declarations": [], - "spell": "5:7-5:11|0|1|2|-1", - "extent": "5:1-5:17|0|1|0|-1", - "alias_of": 0, + "spell": "5:7-5:11|5:1-5:17|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }, { @@ -114,50 +114,51 @@ void accept3(Foo3*) {} "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:11|1:1-1:11|1|-1"], + "derived": [], "instances": [], - "uses": ["2:14-2:17|0|1|4|-1", "3:9-3:12|0|1|4|-1", "7:13-7:16|0|1|4|-1"] + "uses": ["2:14-2:17|4|-1", "3:9-3:12|4|-1", "7:13-7:16|4|-1"] }, { "usr": 15466821155413653804, "detailed_name": "typedef Foo Foo2", "qual_name_offset": 12, "short_name": "Foo2", - "kind": 252, - "declarations": [], - "spell": "3:13-3:17|0|1|2|-1", - "extent": "3:1-3:17|0|1|0|-1", - "alias_of": 15041163540773201510, + "spell": "3:13-3:17|3:1-3:17|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 15041163540773201510, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["9:14-9:18|0|1|4|-1"] + "uses": ["9:14-9:18|4|-1"] }, { "usr": 17897026942631673064, "detailed_name": "using Foo3 = Foo1", "qual_name_offset": 6, "short_name": "Foo3", - "kind": 252, - "declarations": [], - "spell": "4:7-4:11|0|1|2|-1", - "extent": "4:1-4:18|0|1|0|-1", - "alias_of": 1544499294580512394, + "spell": "4:7-4:11|4:1-4:18|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 1544499294580512394, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:14-10:18|0|1|4|-1"] + "uses": ["10:14-10:18|4|-1"] }], "usr2var": [] } diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index 3c742067b..008484833 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -15,48 +15,49 @@ typedef Foo Foo2; "detailed_name": "using Foo1 = Foo", "qual_name_offset": 6, "short_name": "Foo1", - "kind": 252, - "declarations": [], - "spell": "4:7-4:11|0|1|2|-1", - "extent": "4:1-4:22|0|1|0|-1", - "alias_of": 10528472276654770367, + "spell": "4:7-4:11|4:1-4:22|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 10528472276654770367, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["5:13-5:17|0|1|4|-1"] + "uses": ["5:13-5:17|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 5, - "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": ["2:8-2:11|2:1-2:11|1|-1"], + "derived": [], "instances": [], - "uses": ["4:14-4:17|0|1|4|-1", "5:9-5:12|0|1|4|-1"] + "uses": ["4:14-4:17|4|-1", "5:9-5:12|4|-1"] }, { "usr": 15933698173231330933, "detailed_name": "typedef Foo Foo2", "qual_name_offset": 18, "short_name": "Foo2", - "kind": 252, - "declarations": [], - "spell": "5:19-5:23|0|1|2|-1", - "extent": "5:1-5:23|0|1|0|-1", - "alias_of": 10528472276654770367, + "spell": "5:19-5:23|5:1-5:23|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 10528472276654770367, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index 5baaf0f81..d3c8959a6 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -19,57 +19,58 @@ extern Foo foo; "detailed_name": "Foo *Foo::make()", "qual_name_offset": 5, "short_name": "make", + "spell": "5:11-5:15|5:1-8:2|1026|-1", + "bases": [], + "vars": [16380484338511689669], + "callees": [], "kind": 6, + "parent_kind": 5, "storage": 0, - "declarations": ["2:8-2:12|2:3-2:14|15041163540773201510|2|1025|-1"], - "spell": "5:11-5:15|15041163540773201510|2|1026|-1", - "extent": "5:1-8:2|15041163540773201510|2|0|-1", - "bases": [], + "declarations": ["2:8-2:12|2:3-2:14|1025|-1"], "derived": [], - "vars": [16380484338511689669], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [9488177941273031343], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16380484338511689669, 14455976355866885943], - "uses": ["2:3-2:6|15041163540773201510|2|4|-1", "5:1-5:4|0|1|4|-1", "5:6-5:9|0|1|4|-1", "6:3-6:6|9488177941273031343|3|4|-1", "10:8-10:11|0|1|4|-1"] + "uses": ["2:3-2:6|4|-1", "5:1-5:4|4|-1", "5:6-5:9|4|-1", "6:3-6:6|4|-1", "10:8-10:11|4|-1"] }], "usr2var": [{ "usr": 14455976355866885943, "detailed_name": "extern Foo foo", "qual_name_offset": 11, "short_name": "foo", - "declarations": ["10:12-10:15|10:1-10:15|0|1|1|-1"], "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 1 + "parent_kind": 0, + "storage": 1, + "declarations": ["10:12-10:15|10:1-10:15|1|-1"], + "uses": [] }, { "usr": 16380484338511689669, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", - "declarations": [], - "spell": "6:7-6:8|9488177941273031343|3|2|-1", - "extent": "6:3-6:8|9488177941273031343|3|0|-1", + "spell": "6:7-6:8|6:3-6:8|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 6, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 39ef7456b..44d654160 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -24,56 +24,59 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "12:6-12:9|12:1-15:2|2|-1", + "bases": [], + "vars": [8039186520399841081], + "callees": ["14:3-14:9|18319417758892371313|3|16420", "14:14-14:17|11404602816585117695|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "12:6-12:9|0|1|2|-1", - "extent": "12:1-15:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [8039186520399841081], - "uses": [], - "callees": ["14:3-14:9|18319417758892371313|3|16420", "14:14-14:17|11404602816585117695|3|16420"] + "uses": [] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", "qual_name_offset": 4, "short_name": "gen", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["3:5-3:8|3:1-3:10|0|1|1|-1"], - "bases": [], + "declarations": ["3:5-3:8|3:1-3:10|1|-1"], "derived": [], - "vars": [], - "uses": ["14:14-14:17|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["14:14-14:17|16420|-1"] }, { "usr": 18319417758892371313, "detailed_name": "void called(int a)", "qual_name_offset": 5, "short_name": "called", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:12|1:1-1:19|0|1|1|-1"], - "bases": [], + "declarations": ["1:6-1:12|1:1-1:19|1|-1"], "derived": [], - "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["14:3-14:9|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [11489549839875479478, 9648311402855509901, 11489549839875479478, 8039186520399841081], "uses": [] }, { @@ -81,21 +84,21 @@ void foo() { "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "5:8-5:11|0|1|2|-1", - "extent": "5:1-8:2|0|1|0|-1", - "alias_of": 0, + "spell": "5:8-5:11|5:1-8:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 9648311402855509901, "R": 0 }], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["10:5-10:8|0|1|4|-1", "14:22-14:25|4259594751088586730|3|4|-1", "14:40-14:43|4259594751088586730|3|4|-1"] + "uses": ["10:5-10:8|4|-1", "14:22-14:25|4|-1", "14:40-14:43|4|-1"] }], "usr2var": [{ "usr": 8039186520399841081, @@ -103,37 +106,37 @@ void foo() { "qual_name_offset": 4, "short_name": "a", "hover": "int a = 5", - "declarations": [], - "spell": "13:7-13:8|4259594751088586730|3|2|-1", - "extent": "13:3-13:12|4259594751088586730|3|0|-1", + "spell": "13:7-13:8|13:3-13:12|2|-1", "type": 53, - "uses": ["14:10-14:11|4259594751088586730|3|12|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["14:10-14:11|12|-1"] }, { "usr": 9648311402855509901, "detailed_name": "int Foo::field_var", "qual_name_offset": 4, "short_name": "field_var", - "declarations": [], - "spell": "7:7-7:16|15041163540773201510|2|1026|-1", - "extent": "7:3-7:16|15041163540773201510|2|0|-1", + "spell": "7:7-7:16|7:3-7:16|1026|-1", "type": 53, - "uses": ["14:28-14:37|4259594751088586730|3|12|-1"], "kind": 8, - "storage": 0 + "parent_kind": 23, + "storage": 0, + "declarations": [], + "uses": ["14:28-14:37|12|-1"] }, { "usr": 11489549839875479478, "detailed_name": "static int Foo::static_var", "qual_name_offset": 11, "short_name": "static_var", - "declarations": ["6:14-6:24|6:3-6:24|15041163540773201510|2|1025|-1"], - "spell": "10:10-10:20|15041163540773201510|2|1026|-1", - "extent": "10:1-10:24|15041163540773201510|2|0|-1", + "spell": "10:10-10:20|10:1-10:24|1026|-1", "type": 53, - "uses": ["14:45-14:55|4259594751088586730|3|12|-1"], "kind": 13, - "storage": 2 + "parent_kind": 23, + "storage": 2, + "declarations": ["6:14-6:24|6:3-6:24|1025|-1"], + "uses": ["14:45-14:55|12|-1"] }] } */ diff --git a/index_tests/usage/usage_inside_of_call_simple.cc b/index_tests/usage/usage_inside_of_call_simple.cc index db2c738ed..c2320556c 100644 --- a/index_tests/usage/usage_inside_of_call_simple.cc +++ b/index_tests/usage/usage_inside_of_call_simple.cc @@ -16,44 +16,45 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "5:6-5:9|5:1-7:2|2|-1", + "bases": [], + "vars": [], + "callees": ["6:3-6:9|18319417758892371313|3|16420", "6:10-6:13|11404602816585117695|3|16420", "6:18-6:21|11404602816585117695|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "5:6-5:9|0|1|2|-1", - "extent": "5:1-7:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["6:3-6:9|18319417758892371313|3|16420", "6:10-6:13|11404602816585117695|3|16420", "6:18-6:21|11404602816585117695|3|16420"] + "uses": [] }, { "usr": 11404602816585117695, "detailed_name": "int gen()", "qual_name_offset": 4, "short_name": "gen", + "spell": "3:5-3:8|3:1-3:24|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:5-3:8|0|1|2|-1", - "extent": "3:1-3:24|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["6:10-6:13|4259594751088586730|3|16420|-1", "6:18-6:21|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["6:10-6:13|16420|-1", "6:18-6:21|16420|-1"] }, { "usr": 18319417758892371313, "detailed_name": "void called(int a)", "qual_name_offset": 5, "short_name": "called", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["1:6-1:12|1:1-1:19|0|1|1|-1"], - "bases": [], + "declarations": ["1:6-1:12|1:1-1:19|1|-1"], "derived": [], - "vars": [], - "uses": ["6:3-6:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["6:3-6:9|16420|-1"] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index e28d09549..1b867cea7 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -17,31 +17,31 @@ void caller() { "detailed_name": "void called()", "qual_name_offset": 5, "short_name": "called", + "spell": "1:6-1:12|1:1-1:17|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:12|0|1|2|-1", - "extent": "1:1-1:17|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": ["4:13-4:19|11404881820527069090|3|132|-1", "7:3-7:9|11404881820527069090|3|16420|-1"], - "callees": [] + "uses": ["4:13-4:19|132|-1", "7:3-7:9|16420|-1"] }, { "usr": 11404881820527069090, "detailed_name": "void caller()", "qual_name_offset": 5, "short_name": "caller", + "spell": "3:6-3:12|3:1-8:2|2|-1", + "bases": [], + "vars": [9121974011454213596], + "callees": ["4:13-4:19|468307235068920063|3|132", "4:13-4:19|468307235068920063|3|132", "7:3-7:9|468307235068920063|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:12|0|1|2|-1", - "extent": "3:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [9121974011454213596], - "uses": [], - "callees": ["4:13-4:19|468307235068920063|3|132", "4:13-4:19|468307235068920063|3|132", "7:3-7:9|468307235068920063|3|16420"] + "uses": [] }], "usr2type": [], "usr2var": [{ @@ -50,13 +50,13 @@ void caller() { "qual_name_offset": 5, "short_name": "x", "hover": "auto x = &called", - "declarations": [], - "spell": "4:8-4:9|11404881820527069090|3|2|-1", - "extent": "4:3-4:19|11404881820527069090|3|0|-1", + "spell": "4:8-4:9|4:3-4:19|2|-1", "type": 0, - "uses": ["5:3-5:4|11404881820527069090|3|16428|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["5:3-5:4|16428|-1"] }] } */ diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index 1a25fe9ff..9f230cd5d 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -27,56 +27,59 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "10:6-10:9|10:1-18:2|2|-1", + "bases": [], + "vars": [14669930844300034456], + "callees": ["14:3-14:9|17175780305784503374|3|16420", "15:3-15:9|17175780305784503374|3|16420", "16:3-16:9|12086644540399881766|3|16420", "17:3-17:9|17175780305784503374|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "10:6-10:9|0|1|2|-1", - "extent": "10:1-18:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [14669930844300034456], - "uses": [], - "callees": ["14:3-14:9|17175780305784503374|3|16420", "15:3-15:9|17175780305784503374|3|16420", "16:3-16:9|12086644540399881766|3|16420", "17:3-17:9|17175780305784503374|3|16420"] + "uses": [] }, { "usr": 12086644540399881766, "detailed_name": "void accept(int *)", "qual_name_offset": 5, "short_name": "accept", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["8:6-8:12|8:1-8:18|0|1|1|-1"], - "bases": [], + "declarations": ["8:6-8:12|8:1-8:18|1|-1"], "derived": [], - "vars": [], - "uses": ["16:3-16:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["16:3-16:9|16420|-1"] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", "qual_name_offset": 5, "short_name": "accept", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["7:6-7:12|7:1-7:17|0|1|1|-1"], - "bases": [], + "declarations": ["7:6-7:12|7:1-7:17|1|-1"], "derived": [], - "vars": [], - "uses": ["14:3-14:9|4259594751088586730|3|16420|-1", "15:3-15:9|4259594751088586730|3|16420|-1", "17:3-17:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["14:3-14:9|16420|-1", "15:3-15:9|16420|-1", "17:3-17:9|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [4220150017963593039, 3873837747174060388], "uses": [] }, { @@ -84,15 +87,10 @@ void foo() { "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 4220150017963593039, "R": 0 @@ -100,45 +98,50 @@ void foo() { "L": 3873837747174060388, "R": 32 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [14669930844300034456], - "uses": ["11:3-11:6|4259594751088586730|3|4|-1"] + "uses": ["11:3-11:6|4|-1"] }], "usr2var": [{ "usr": 3873837747174060388, "detailed_name": "int Foo::y", "qual_name_offset": 4, "short_name": "y", - "declarations": [], - "spell": "4:7-4:8|15041163540773201510|2|1026|-1", - "extent": "4:3-4:8|15041163540773201510|2|0|-1", + "spell": "4:7-4:8|4:3-4:8|1026|-1", "type": 53, - "uses": ["17:12-17:13|4259594751088586730|3|12|-1"], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": ["17:12-17:13|12|-1"] }, { "usr": 4220150017963593039, "detailed_name": "int Foo::x", "qual_name_offset": 4, "short_name": "x", - "declarations": [], - "spell": "3:7-3:8|15041163540773201510|2|1026|-1", - "extent": "3:3-3:8|15041163540773201510|2|0|-1", + "spell": "3:7-3:8|3:3-3:8|1026|-1", "type": 53, - "uses": ["12:5-12:6|4259594751088586730|3|20|-1", "13:5-13:6|4259594751088586730|3|4|-1", "14:12-14:13|4259594751088586730|3|12|-1", "15:12-15:13|4259594751088586730|3|12|-1", "16:13-16:14|4259594751088586730|3|132|-1"], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": ["12:5-12:6|20|-1", "13:5-13:6|4|-1", "14:12-14:13|12|-1", "15:12-15:13|12|-1", "16:13-16:14|132|-1"] }, { "usr": 14669930844300034456, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", - "declarations": [], - "spell": "11:7-11:8|4259594751088586730|3|2|-1", - "extent": "11:3-11:8|4259594751088586730|3|0|-1", + "spell": "11:7-11:8|11:3-11:8|2|-1", "type": 15041163540773201510, - "uses": ["12:3-12:4|4259594751088586730|3|4|-1", "13:3-13:4|4259594751088586730|3|4|-1", "14:10-14:11|4259594751088586730|3|4|-1", "15:10-15:11|4259594751088586730|3|4|-1", "16:11-16:12|4259594751088586730|3|4|-1", "17:10-17:11|4259594751088586730|3|4|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["12:3-12:4|4|-1", "13:3-13:4|4|-1", "14:10-14:11|4|-1", "15:10-15:11|4|-1", "16:11-16:12|4|-1", "17:10-17:11|4|-1"] }] } */ diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 8c21456f1..9c8e4d57a 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -18,43 +18,45 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "7:6-7:9|7:1-9:2|2|-1", + "bases": [], + "vars": [], + "callees": ["8:3-8:9|17175780305784503374|3|16420"], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "7:6-7:9|0|1|2|-1", - "extent": "7:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": ["8:3-8:9|17175780305784503374|3|16420"] + "uses": [] }, { "usr": 17175780305784503374, "detailed_name": "void accept(int)", "qual_name_offset": 5, "short_name": "accept", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, - "declarations": ["5:6-5:12|5:1-5:17|0|1|1|-1"], - "bases": [], + "declarations": ["5:6-5:12|5:1-5:17|1|-1"], "derived": [], - "vars": [], - "uses": ["8:3-8:9|4259594751088586730|3|16420|-1"], - "callees": [] + "uses": ["8:3-8:9|16420|-1"] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [8599782646965457351], "uses": [] }, { @@ -62,29 +64,30 @@ void foo() { "detailed_name": "struct Foo {}", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": [], - "spell": "1:8-1:11|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:11|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["8:10-8:13|4259594751088586730|3|4|-1"] + "uses": ["8:10-8:13|4|-1"] }], "usr2var": [{ "usr": 8599782646965457351, "detailed_name": "static int Foo::x", "qual_name_offset": 11, "short_name": "x", - "declarations": ["2:14-2:15|2:3-2:15|15041163540773201510|2|1025|-1"], "type": 53, - "uses": ["8:15-8:16|4259594751088586730|3|12|-1"], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": ["2:14-2:15|2:3-2:15|1025|-1"], + "uses": ["8:15-8:16|12|-1"] }] } */ diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index dd3fe7081..e041ffba4 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -18,35 +18,35 @@ const VarType Holder::static_var; "detailed_name": "enum VarType {}", "qual_name_offset": 5, "short_name": "VarType", - "kind": 10, - "declarations": [], - "spell": "1:6-1:13|0|1|2|-1", - "extent": "1:1-1:16|0|1|0|-1", - "alias_of": 0, + "spell": "1:6-1:13|1:1-1:16|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 10, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [7057400933868440116, 7057400933868440116], - "uses": ["4:20-4:27|10028537921178202800|2|4|-1", "4:42-4:49|10028537921178202800|2|4|-1", "7:7-7:14|0|1|4|-1"] + "uses": ["4:20-4:27|4|-1", "4:42-4:49|4|-1", "7:7-7:14|4|-1"] }, { "usr": 10028537921178202800, "detailed_name": "struct Holder {}", "qual_name_offset": 7, "short_name": "Holder", - "kind": 23, - "declarations": [], - "spell": "3:8-3:14|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "alias_of": 0, + "spell": "3:8-3:14|3:1-5:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["7:15-7:21|0|1|4|-1"] + "uses": ["7:15-7:21|4|-1"] }], "usr2var": [{ "usr": 7057400933868440116, @@ -54,13 +54,13 @@ const VarType Holder::static_var; "qual_name_offset": 25, "short_name": "static_var", "hover": "static constexpr VarType Holder::static_var = (VarType)0x0", - "declarations": ["4:28-4:38|4:3-4:53|10028537921178202800|2|1025|-1"], - "spell": "7:23-7:33|10028537921178202800|2|1026|-1", - "extent": "7:1-7:33|10028537921178202800|2|0|-1", + "spell": "7:23-7:33|7:1-7:33|1026|-1", "type": 5792006888140599735, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 23, + "storage": 2, + "declarations": ["4:28-4:38|4:3-4:53|1025|-1"], + "uses": [] }] } */ diff --git a/index_tests/usage/var_usage_extern.cc b/index_tests/usage/var_usage_extern.cc index 0d3469e62..14cb93e7f 100644 --- a/index_tests/usage/var_usage_extern.cc +++ b/index_tests/usage/var_usage_extern.cc @@ -13,30 +13,31 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-5:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [16721564935990383768], "uses": [] }], @@ -45,11 +46,12 @@ void foo() { "detailed_name": "extern int a", "qual_name_offset": 11, "short_name": "a", - "declarations": ["1:12-1:13|1:1-1:13|0|1|1|-1"], "type": 53, - "uses": ["4:3-4:4|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 1 + "parent_kind": 0, + "storage": 1, + "declarations": ["1:12-1:13|1:1-1:13|1|-1"], + "uses": ["4:3-4:4|20|-1"] }] } */ diff --git a/index_tests/usage/var_usage_func_parameter.cc b/index_tests/usage/var_usage_func_parameter.cc index 2a5e0867a..069c72628 100644 --- a/index_tests/usage/var_usage_func_parameter.cc +++ b/index_tests/usage/var_usage_func_parameter.cc @@ -11,30 +11,31 @@ void foo(int a) { "detailed_name": "void foo(int a)", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-3:2|2|-1", + "bases": [], + "vars": [10063793875496522529], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [10063793875496522529], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [10063793875496522529], "uses": [] }], @@ -43,13 +44,13 @@ void foo(int a) { "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026|-1", - "extent": "1:10-1:15|11998306017310352355|3|0|-1", + "spell": "1:14-1:15|1:10-1:15|1026|-1", "type": 53, - "uses": ["2:3-2:4|11998306017310352355|3|4|-1"], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["2:3-2:4|4|-1"] }] } */ diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index b4ed38423..577d810c5 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -12,30 +12,31 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-4:2|2|-1", + "bases": [], + "vars": [14014650769929566957], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-4:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [14014650769929566957], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [14014650769929566957], "uses": [] }], @@ -44,13 +45,13 @@ void foo() { "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", - "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2|-1", - "extent": "2:3-2:8|4259594751088586730|3|0|-1", + "spell": "2:7-2:8|2:3-2:8|2|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["3:3-3:4|20|-1"] }] } */ diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index 2aaf27be2..efe2d4604 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -17,30 +17,31 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-9:2|2|-1", + "bases": [], + "vars": [13311055950748663970, 14036425367303419504], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [13311055950748663970, 14036425367303419504], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [13311055950748663970, 14036425367303419504], "uses": [] }], @@ -49,25 +50,25 @@ void foo() { "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2|-1", - "extent": "2:3-2:8|4259594751088586730|3|0|-1", + "spell": "2:7-2:8|2:3-2:8|2|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20|-1", "8:3-8:4|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["3:3-3:4|20|-1", "8:3-8:4|20|-1"] }, { "usr": 14036425367303419504, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "5:9-5:10|4259594751088586730|3|2|-1", - "extent": "5:5-5:10|4259594751088586730|3|0|-1", + "spell": "5:9-5:10|5:5-5:10|2|-1", "type": 53, - "uses": ["6:5-6:6|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["6:5-6:6|20|-1"] }] } */ diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index 801f3a750..dfa4a6ca0 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -17,30 +17,31 @@ void foo(int a) { "detailed_name": "void foo(int a)", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-8:2|2|-1", + "bases": [], + "vars": [11608231465452906059, 6997229590862003559], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-8:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [11608231465452906059, 6997229590862003559], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [11608231465452906059, 6997229590862003559], "uses": [] }], @@ -49,25 +50,25 @@ void foo(int a) { "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "4:9-4:10|11998306017310352355|3|2|-1", - "extent": "4:5-4:10|11998306017310352355|3|0|-1", + "spell": "4:9-4:10|4:5-4:10|2|-1", "type": 53, - "uses": ["5:5-5:6|11998306017310352355|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["5:5-5:6|20|-1"] }, { "usr": 11608231465452906059, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026|-1", - "extent": "1:10-1:15|11998306017310352355|3|0|-1", + "spell": "1:14-1:15|1:10-1:15|1026|-1", "type": 53, - "uses": ["2:3-2:4|11998306017310352355|3|20|-1", "7:3-7:4|11998306017310352355|3|20|-1"], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["2:3-2:4|20|-1", "7:3-7:4|20|-1"] }] } */ diff --git a/index_tests/usage/var_usage_static.cc b/index_tests/usage/var_usage_static.cc index 396f3ded3..705fddff9 100644 --- a/index_tests/usage/var_usage_static.cc +++ b/index_tests/usage/var_usage_static.cc @@ -14,30 +14,31 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-5:2|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [11823161916242867318], "uses": [] }], @@ -46,13 +47,13 @@ void foo() { "detailed_name": "static int a", "qual_name_offset": 11, "short_name": "a", - "declarations": [], - "spell": "1:12-1:13|0|1|2|-1", - "extent": "1:1-1:13|0|1|0|-1", + "spell": "1:12-1:13|1:1-1:13|2|-1", "type": 53, - "uses": ["4:3-4:4|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": ["4:3-4:4|20|-1"] }] } */ diff --git a/index_tests/vars/class_member.cc b/index_tests/vars/class_member.cc index 7bb7bc970..9b62aec7e 100644 --- a/index_tests/vars/class_member.cc +++ b/index_tests/vars/class_member.cc @@ -12,34 +12,34 @@ class Foo { "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [{ "L": 13799811842374292251, "R": 0 }], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [13799811842374292251], - "uses": ["2:3-2:6|15041163540773201510|2|4|-1"] + "uses": ["2:3-2:6|4|-1"] }], "usr2var": [{ "usr": 13799811842374292251, "detailed_name": "Foo *Foo::member", "qual_name_offset": 5, "short_name": "member", - "declarations": [], - "spell": "2:8-2:14|15041163540773201510|2|1026|-1", - "extent": "2:3-2:14|15041163540773201510|2|0|-1", + "spell": "2:8-2:14|2:3-2:14|1026|-1", "type": 15041163540773201510, - "uses": [], "kind": 8, - "storage": 0 + "parent_kind": 5, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 86e090415..3c67ac6ec 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -14,31 +14,31 @@ Foo* Foo::member = nullptr; "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [5844987037615239736, 5844987037615239736], - "uses": ["2:10-2:13|15041163540773201510|2|4|-1", "4:1-4:4|0|1|4|-1", "4:6-4:9|0|1|4|-1"] + "uses": ["2:10-2:13|4|-1", "4:1-4:4|4|-1", "4:6-4:9|4|-1"] }], "usr2var": [{ "usr": 5844987037615239736, "detailed_name": "static Foo *Foo::member", "qual_name_offset": 12, "short_name": "member", - "declarations": ["2:15-2:21|2:3-2:21|15041163540773201510|2|1025|-1"], - "spell": "4:11-4:17|15041163540773201510|2|1026|-1", - "extent": "4:1-4:27|15041163540773201510|2|0|-1", + "spell": "4:11-4:17|4:1-4:27|1026|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 5, + "storage": 2, + "declarations": ["2:15-2:21|2:3-2:21|1025|-1"], + "uses": [] }] } */ diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index d01c6220a..c0a3172a7 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -12,14 +12,15 @@ class Foo { "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [5844987037615239736], "uses": [] }, { @@ -27,16 +28,16 @@ class Foo { "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-3:2|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], "uses": [] }], @@ -45,11 +46,12 @@ class Foo { "detailed_name": "static int Foo::member", "qual_name_offset": 11, "short_name": "member", - "declarations": ["2:14-2:20|2:3-2:20|15041163540773201510|2|1025|-1"], "type": 53, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": ["2:14-2:20|2:3-2:20|1025|-1"], + "uses": [] }] } */ diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index f76c0460f..a86eb701d 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -14,34 +14,34 @@ void f() { "detailed_name": "void f()", "qual_name_offset": 5, "short_name": "f", + "spell": "2:6-2:7|2:1-5:2|2|-1", + "bases": [], + "vars": [10601729374837386290, 18422884837902130475], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "2:6-2:7|0|1|2|-1", - "extent": "2:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [10601729374837386290, 18422884837902130475], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "class Foo {}", "qual_name_offset": 6, "short_name": "Foo", - "kind": 5, - "declarations": [], - "spell": "1:7-1:10|0|1|2|-1", - "extent": "1:1-1:13|0|1|0|-1", - "alias_of": 0, + "spell": "1:7-1:10|1:1-1:13|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 5, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [10601729374837386290, 18422884837902130475], - "uses": ["3:16-3:19|880549676430489861|3|4|-1", "4:17-4:20|880549676430489861|3|4|-1"] + "uses": ["3:16-3:19|4|-1", "4:17-4:20|4|-1"] }], "usr2var": [{ "usr": 10601729374837386290, @@ -49,26 +49,26 @@ void f() { "qual_name_offset": 5, "short_name": "x", "hover": "auto x = new Foo()", - "declarations": [], - "spell": "3:8-3:9|880549676430489861|3|2|-1", - "extent": "3:3-3:21|880549676430489861|3|0|-1", + "spell": "3:8-3:9|3:3-3:21|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 18422884837902130475, "detailed_name": "Foo *y", "qual_name_offset": 5, "short_name": "y", "hover": "Foo *y = new Foo()", - "declarations": [], - "spell": "4:9-4:10|880549676430489861|3|2|-1", - "extent": "4:3-4:22|880549676430489861|3|0|-1", + "spell": "4:9-4:10|4:3-4:22|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 66b965733..70a985bab 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -14,45 +14,46 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-5:2|2|-1", + "bases": [], + "vars": [13198746475679542317], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [13198746475679542317], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:11|1:1-1:11|1|-1"], + "derived": [], "instances": [13198746475679542317], - "uses": ["4:3-4:6|4259594751088586730|3|4|-1"] + "uses": ["4:3-4:6|4|-1"] }], "usr2var": [{ "usr": 13198746475679542317, "detailed_name": "Foo *a", "qual_name_offset": 5, "short_name": "a", - "declarations": [], - "spell": "4:8-4:9|4259594751088586730|3|2|-1", - "extent": "4:3-4:9|4259594751088586730|3|0|-1", + "spell": "4:8-4:9|4:3-4:9|2|-1", "type": 15041163540773201510, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index a9c8683f2..751fbd651 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -12,57 +12,58 @@ void foo(Foo* p0, Foo* p1) {} "detailed_name": "void foo(Foo *p0, Foo *p1)", "qual_name_offset": 5, "short_name": "foo", + "spell": "3:6-3:9|3:1-3:30|2|-1", + "bases": [], + "vars": [8730439006497971620, 2525014371090380500], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-3:30|0|1|0|-1", - "bases": [], "derived": [], - "vars": [8730439006497971620, 2525014371090380500], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 15041163540773201510, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, - "declarations": ["1:8-1:11|1:1-1:11|0|1|1|-1"], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": ["1:8-1:11|1:1-1:11|1|-1"], + "derived": [], "instances": [8730439006497971620, 2525014371090380500], - "uses": ["3:10-3:13|0|1|4|-1", "3:19-3:22|0|1|4|-1"] + "uses": ["3:10-3:13|4|-1", "3:19-3:22|4|-1"] }], "usr2var": [{ "usr": 2525014371090380500, "detailed_name": "Foo *p1", "qual_name_offset": 5, "short_name": "p1", - "declarations": [], - "spell": "3:24-3:26|8908726657907936744|3|1026|-1", - "extent": "3:19-3:26|8908726657907936744|3|0|-1", + "spell": "3:24-3:26|3:19-3:26|1026|-1", "type": 15041163540773201510, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 8730439006497971620, "detailed_name": "Foo *p0", "qual_name_offset": 5, "short_name": "p0", - "declarations": [], - "spell": "3:15-3:17|8908726657907936744|3|1026|-1", - "extent": "3:10-3:17|8908726657907936744|3|0|-1", + "spell": "3:15-3:17|3:10-3:17|1026|-1", "type": 15041163540773201510, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/function_param_unnamed.cc b/index_tests/vars/function_param_unnamed.cc index 48b4f60ba..bd8c9d84b 100644 --- a/index_tests/vars/function_param_unnamed.cc +++ b/index_tests/vars/function_param_unnamed.cc @@ -9,16 +9,16 @@ void foo(int, int) {} "detailed_name": "void foo(int, int)", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-1:22|2|-1", + "bases": [], + "vars": [], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-1:22|0|1|0|-1", - "bases": [], "derived": [], - "vars": [], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [], "usr2var": [] diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index d6ffa4ef5..0ccc91e30 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -17,30 +17,31 @@ void foo() { "detailed_name": "void foo()", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-9:2|2|-1", + "bases": [], + "vars": [1894874819807168345, 4508045017817092115], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-9:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [1894874819807168345, 4508045017817092115], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [1894874819807168345, 4508045017817092115], "uses": [] }], @@ -49,25 +50,25 @@ void foo() { "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "2:7-2:8|4259594751088586730|3|2|-1", - "extent": "2:3-2:8|4259594751088586730|3|0|-1", + "spell": "2:7-2:8|2:3-2:8|2|-1", "type": 53, - "uses": ["3:3-3:4|4259594751088586730|3|20|-1", "8:3-8:4|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["3:3-3:4|20|-1", "8:3-8:4|20|-1"] }, { "usr": 4508045017817092115, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", - "declarations": [], - "spell": "5:9-5:10|4259594751088586730|3|2|-1", - "extent": "5:5-5:10|4259594751088586730|3|0|-1", + "spell": "5:9-5:10|5:5-5:10|2|-1", "type": 53, - "uses": ["6:5-6:6|4259594751088586730|3|20|-1"], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": ["6:5-6:6|20|-1"] }] } */ diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index 9ef35ec9f..80f8d4f1c 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -11,30 +11,31 @@ void foo(int p) { "detailed_name": "void foo(int p)", "qual_name_offset": 5, "short_name": "foo", + "spell": "1:6-1:9|1:1-3:2|2|-1", + "bases": [], + "vars": [5875271969926422921, 11404600766177939811], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "1:6-1:9|0|1|2|-1", - "extent": "1:1-3:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [5875271969926422921, 11404600766177939811], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 53, "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [5875271969926422921, 11404600766177939811], "uses": [] }], @@ -43,26 +44,26 @@ void foo(int p) { "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", - "declarations": [], - "spell": "1:14-1:15|11998306017310352355|3|1026|-1", - "extent": "1:10-1:15|11998306017310352355|3|0|-1", + "spell": "1:14-1:15|1:10-1:15|1026|-1", "type": 53, - "uses": [], "kind": 253, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }, { "usr": 11404600766177939811, "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", "hover": "int p = 0", - "declarations": [], - "spell": "2:9-2:10|11998306017310352355|3|2|-1", - "extent": "2:5-2:14|11998306017310352355|3|0|-1", + "spell": "2:9-2:10|2:5-2:14|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/global_variable.cc b/index_tests/vars/global_variable.cc index 0f563a73c..3ce2d1192 100644 --- a/index_tests/vars/global_variable.cc +++ b/index_tests/vars/global_variable.cc @@ -10,14 +10,15 @@ static int global = 0; "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [6834525061342585382], "uses": [] }], @@ -27,13 +28,13 @@ static int global = 0; "qual_name_offset": 11, "short_name": "global", "hover": "static int global = 0", - "declarations": [], - "spell": "1:12-1:18|0|1|2|-1", - "extent": "1:1-1:22|0|1|0|-1", + "spell": "1:12-1:18|1:1-1:22|2|-1", "type": 53, - "uses": [], "kind": 13, - "storage": 2 + "parent_kind": 0, + "storage": 2, + "declarations": [], + "uses": [] }] } */ diff --git a/index_tests/vars/global_variable_decl_only.cc b/index_tests/vars/global_variable_decl_only.cc index 0ecf84a27..1ba9f2e4c 100644 --- a/index_tests/vars/global_variable_decl_only.cc +++ b/index_tests/vars/global_variable_decl_only.cc @@ -10,14 +10,15 @@ extern int global; "detailed_name": "", "qual_name_offset": 0, "short_name": "", - "kind": 0, - "declarations": [], - "alias_of": 0, "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 0, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [9937941849651546906], "uses": [] }], @@ -26,11 +27,12 @@ extern int global; "detailed_name": "extern int global", "qual_name_offset": 11, "short_name": "global", - "declarations": ["1:12-1:18|1:1-1:18|0|1|1|-1"], "type": 53, - "uses": [], "kind": 13, - "storage": 1 + "parent_kind": 0, + "storage": 1, + "declarations": ["1:12-1:18|1:1-1:18|1|-1"], + "uses": [] }] } */ diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index b924afd5b..ce3607eb2 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -16,64 +16,64 @@ void Foo() { "detailed_name": "void Foo()", "qual_name_offset": 5, "short_name": "Foo", + "spell": "3:6-3:9|3:1-5:2|2|-1", + "bases": [], + "vars": [6975456769752895964], + "callees": [], "kind": 12, + "parent_kind": 0, "storage": 0, "declarations": [], - "spell": "3:6-3:9|0|1|2|-1", - "extent": "3:1-5:2|0|1|0|-1", - "bases": [], "derived": [], - "vars": [6975456769752895964], - "uses": [], - "callees": [] + "uses": [] }], "usr2type": [{ "usr": 4750332761459066907, "detailed_name": "struct S {}", "qual_name_offset": 7, "short_name": "S", - "kind": 23, - "declarations": [], - "spell": "1:8-1:9|0|1|2|-1", - "extent": "1:1-1:12|0|1|0|-1", - "alias_of": 0, + "spell": "1:8-1:9|1:1-1:12|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 0, + "kind": 23, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [], - "uses": ["2:11-2:12|0|1|4|-1"] + "uses": ["2:11-2:12|4|-1"] }, { "usr": 7434820806199665424, "detailed_name": "using F = S", "qual_name_offset": 6, "short_name": "F", - "kind": 252, - "declarations": [], - "spell": "2:7-2:8|0|1|2|-1", - "extent": "2:1-2:12|0|1|0|-1", - "alias_of": 4750332761459066907, + "spell": "2:7-2:8|2:1-2:12|2|-1", "bases": [], - "derived": [], - "types": [], "funcs": [], + "types": [], "vars": [], + "alias_of": 4750332761459066907, + "kind": 252, + "parent_kind": 0, + "declarations": [], + "derived": [], "instances": [6975456769752895964], - "uses": ["4:3-4:4|4654328188330986029|3|4|-1"] + "uses": ["4:3-4:4|4|-1"] }], "usr2var": [{ "usr": 6975456769752895964, "detailed_name": "F a", "qual_name_offset": 2, "short_name": "a", - "declarations": [], - "spell": "4:5-4:6|4654328188330986029|3|2|-1", - "extent": "4:3-4:6|4654328188330986029|3|0|-1", + "spell": "4:5-4:6|4:3-4:6|2|-1", "type": 7434820806199665424, - "uses": [], "kind": 13, - "storage": 0 + "parent_kind": 12, + "storage": 0, + "declarations": [], + "uses": [] }] } */ diff --git a/src/message_handler.cc b/src/message_handler.cc index 03cf15e25..1b699ed0b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -140,9 +140,8 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { // Group symbols together. std::unordered_map grouped_symbols; - for (auto &sym_refcnt : file->symbol2refcnt) { - if (sym_refcnt.second <= 0) continue; - SymbolRef sym = sym_refcnt.first; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0) continue; std::string_view detailed_name; lsSymbolKind parent_kind = lsSymbolKind::Unknown; lsSymbolKind kind = lsSymbolKind::Unknown; From de9c77e1ccbe6c5cc69b746db791290c682e8cb3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 6 Oct 2018 15:23:23 -0700 Subject: [PATCH 254/378] Improve completion blacklist some undesired candidates additionalTextEdits if clang>=7 Use CodePatterns for preprocessor directive completion if there is a # Prefer textEdit over insertText --- src/clang_complete.cc | 19 ++- src/clang_complete.hh | 9 +- src/include_complete.cc | 3 +- src/lsp_completion.h | 19 +-- src/messages/textDocument_completion.cc | 189 ++++++++++----------- src/messages/textDocument_signatureHelp.cc | 13 +- 6 files changed, 116 insertions(+), 136 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index d487caa95..32ef2ef7b 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -71,6 +71,18 @@ struct ProxyFileSystem : FileSystem { #endif namespace ccls { + +lsTextEdit ToTextEdit(const clang::SourceManager &SM, + const clang::LangOptions &L, + const clang::FixItHint &FixIt) { + lsTextEdit edit; + edit.newText = FixIt.CodeToInsert; + auto r = FromCharSourceRange(SM, L, FixIt.RemoveRange); + edit.range = + lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; + return edit; +} + struct PreambleStatCache { llvm::StringMap> Cache; @@ -235,12 +247,7 @@ class StoreDiags : public DiagnosticConsumer { for (const FixItHint &FixIt : Info.getFixItHints()) { if (!IsConcerned(SM, FixIt.RemoveRange.getBegin())) return false; - lsTextEdit edit; - edit.newText = FixIt.CodeToInsert; - auto r = FromCharSourceRange(SM, *LangOpts, FixIt.RemoveRange); - edit.range = - lsRange{{r.start.line, r.start.column}, {r.end.line, r.end.column}}; - last->edits.push_back(std::move(edit)); + last->edits.push_back(ToTextEdit(SM, *LangOpts, FixIt)); } return true; }; diff --git a/src/clang_complete.hh b/src/clang_complete.hh index c7c131b11..7d610d2d5 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -49,6 +49,10 @@ struct Diag : DiagBase { std::vector edits; }; +lsTextEdit ToTextEdit(const clang::SourceManager &SM, + const clang::LangOptions &L, + const clang::FixItHint &FixIt); + struct CompletionSession : public std::enable_shared_from_this { std::mutex mutex; @@ -184,9 +188,8 @@ struct CompleteConsumerCache { std::lock_guard lock(mutex); action(); } - bool IsCacheValid(const lsTextDocumentPositionParams ¶ms) { + bool IsCacheValid(const std::string path, lsPosition position) { std::lock_guard lock(mutex); - return path == params.textDocument.uri.GetPath() && - position == params.position; + return this->path == path && this->position == position; } }; diff --git a/src/include_complete.cc b/src/include_complete.cc index e634e189d..cf220a56e 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -84,8 +84,7 @@ lsCompletionItem BuildCompletionItem(const std::string &path, lsCompletionItem item; item.label = ElideLongPath(path); item.detail = path; // the include path, used in de-duplicating - item.textEdit = lsTextEdit(); - item.textEdit->newText = path; + item.textEdit.newText = path; item.insertTextFormat = lsInsertTextFormat::PlainText; item.use_angle_brackets_ = use_angle_brackets; if (is_stl) { diff --git a/src/lsp_completion.h b/src/lsp_completion.h index ef387380f..0963afd31 100644 --- a/src/lsp_completion.h +++ b/src/lsp_completion.h @@ -114,12 +114,12 @@ struct lsCompletionItem { // // *Note:* The range of the edit must be a single line range and it must // contain the position at which completion has been requested. - std::optional textEdit; + lsTextEdit textEdit; // An std::optional array of additional text edits that are applied when // selecting this completion. Edits must not overlap with the main edit // nor with themselves. - // std::vector additionalTextEdits; + std::vector additionalTextEdits; // An std::optional command that is executed *after* inserting this // completion. *Note* that additional modifications to the current document @@ -128,18 +128,7 @@ struct lsCompletionItem { // An data entry field that is preserved on a completion item between // a completion and a completion resolve request. // data ? : any - - // Use this helper to figure out what content the completion item will insert - // into the document, as it could live in either |textEdit|, |insertText|, or - // |label|. - const std::string &InsertedContent() const { - if (textEdit) - return textEdit->newText; - if (!insertText.empty()) - return insertText; - return label; - } }; MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation, - sortText, insertText, filterText, insertTextFormat, - textEdit); + sortText, filterText, insertText, insertTextFormat, + textEdit, additionalTextEdits); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index daa6c7c3a..5558c8061 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -107,8 +107,8 @@ void DecorateIncludePaths(const std::smatch &match, else quote0 = quote1 = '"'; - item.textEdit->newText = - prefix + quote0 + item.textEdit->newText + quote1 + suffix; + item.textEdit.newText = + prefix + quote0 + item.textEdit.newText + quote1 + suffix; item.label = prefix + quote0 + item.label + quote1 + suffix; item.filterText = std::nullopt; } @@ -137,27 +137,6 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) { return {ok, match[3], match[5], match[6], match}; } -static const std::vector preprocessorKeywords = { - "define", "undef", "include", "if", "ifdef", "ifndef", - "else", "elif", "endif", "line", "error", "pragma"}; - -std::vector -PreprocessorKeywordCompletionItems(const std::smatch &match) { - std::vector items; - for (auto &keyword : preprocessorKeywords) { - lsCompletionItem item; - item.label = keyword; - item.priority_ = (keyword == "include" ? 2 : 1); - item.textEdit = lsTextEdit(); - std::string space = (keyword == "else" || keyword == "endif") ? "" : " "; - item.textEdit->newText = match[1].str() + "#" + match[2].str() + keyword + - space + match[6].str(); - item.insertTextFormat = lsInsertTextFormat::PlainText; - items.push_back(item); - } - return items; -} - template char *tofixedbase64(T input, char *out) { const char *digits = "./0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -174,11 +153,9 @@ template char *tofixedbase64(T input, char *out) { // Pre-filters completion responses before sending to vscode. This results in a // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. -void FilterAndSortCompletionResponse( - Out_TextDocumentComplete *complete_response, - const std::string &complete_text, bool has_open_paren) { - if (!g_config->completion.filterAndSort) - return; +void FilterCandidates(Out_TextDocumentComplete *complete_response, + const std::string &complete_text, lsPosition begin_pos, + lsPosition end_pos, bool has_open_paren) { auto &items = complete_response->result.items; auto finalize = [&]() { @@ -188,9 +165,21 @@ void FilterAndSortCompletionResponse( complete_response->result.isIncomplete = true; } - if (has_open_paren) - for (auto &item : items) - item.insertText = item.label; + for (auto &item : items) { + item.textEdit.range = lsRange{begin_pos, end_pos}; + if (has_open_paren) + item.textEdit.newText = item.label; + // https://github.com/Microsoft/language-server-protocol/issues/543 + // Order of textEdit and additionalTextEdits is unspecified. + auto &edits = item.additionalTextEdits; + if (edits.size() && edits[0].range.end == begin_pos) { + item.textEdit.range.start = edits[0].range.start; + item.textEdit.newText = edits[0].newText + item.textEdit.newText; + edits.erase(edits.begin()); + } + // Compatibility + item.insertText = item.textEdit.newText; + } // Set sortText. Note that this happens after resizing - we could do it // before, but then we should also sort by priority. @@ -200,7 +189,7 @@ void FilterAndSortCompletionResponse( }; // No complete text; don't run any filtering logic except to trim the items. - if (complete_text.empty()) { + if (!g_config->completion.filterAndSort || complete_text.empty()) { finalize(); return; } @@ -261,19 +250,6 @@ bool IsOpenParenOrAngle(const std::vector &lines, return false; } -unsigned GetCompletionPriority(const CodeCompletionString &CCS, - CXCursorKind result_kind, - const std::optional &typedText) { - unsigned priority = CCS.getPriority(); - if (CCS.getAvailability() != CXAvailability_Available || - result_kind == CXCursor_Destructor || - result_kind == CXCursor_ConversionFunction || - (result_kind == CXCursor_CXXMethod && typedText && - StartsWith(*typedText, "operator"))) - priority *= 100; - return priority; -} - lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { case CXCursor_UnexposedDecl: @@ -366,11 +342,11 @@ lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { } } -void BuildItem(std::vector &out, - const CodeCompletionString &CCS) { +void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS, + std::vector &out) { assert(!out.empty()); auto first = out.size() - 1; - + bool ignore = false; std::string result_type; for (const auto &Chunk : CCS) { @@ -404,7 +380,7 @@ void BuildItem(std::vector &out, // Duplicate last element, the recursive call will complete it. if (g_config->completion.duplicateOptional) { out.push_back(out.back()); - BuildItem(out, *Chunk.Optional); + BuildItem(R, *Chunk.Optional, out); } continue; } @@ -415,15 +391,20 @@ void BuildItem(std::vector &out, for (auto i = first; i < out.size(); ++i) { out[i].label += text; - if (!g_config->client.snippetSupport && !out[i].parameters_.empty()) + if (ignore || + (!g_config->client.snippetSupport && out[i].parameters_.size())) continue; if (Kind == CodeCompletionString::CK_Placeholder) { - out[i].insertText += + if (R.Kind == CodeCompletionResult::RK_Pattern) { + ignore = true; + continue; + } + out[i].textEdit.newText += "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; out[i].insertTextFormat = lsInsertTextFormat::Snippet; } else if (Kind != CodeCompletionString::CK_Informative) { - out[i].insertText += text; + out[i].textEdit.newText += text; } } } @@ -453,12 +434,25 @@ class CompletionConsumer : public CodeCompleteConsumer { void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, CodeCompletionResult *Results, unsigned NumResults) override { + if (Context.getKind() == CodeCompletionContext::CCC_Recovery) + return; ls_items.reserve(NumResults); for (unsigned i = 0; i != NumResults; i++) { auto &R = Results[i]; if (R.Availability == CXAvailability_NotAccessible || R.Availability == CXAvailability_NotAvailable) continue; + if (R.Declaration) { + if (R.Declaration->getKind() == Decl::CXXDestructor) + continue; + if (auto *RD = dyn_cast(R.Declaration)) + if (RD->isInjectedClassName()) + continue; + auto NK = R.Declaration->getDeclName().getNameKind(); + if (NK == DeclarationName::CXXOperatorName || + NK == DeclarationName::CXXLiteralOperatorName) + continue; + } CodeCompletionString *CCS = R.CreateCodeCompletionString( S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); @@ -470,19 +464,27 @@ class CompletionConsumer : public CodeCompleteConsumer { size_t first_idx = ls_items.size(); ls_items.push_back(ls_item); - BuildItem(ls_items, *CCS); + BuildItem(R, *CCS, ls_items); for (size_t j = first_idx; j < ls_items.size(); j++) { if (g_config->client.snippetSupport && ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) - ls_items[j].insertText += "$0"; - ls_items[j].priority_ = GetCompletionPriority( - *CCS, Results[i].CursorKind, ls_items[j].filterText); + ls_items[j].textEdit.newText += "$0"; + ls_items[j].priority_ = CCS->getPriority(); if (!g_config->completion.detailedLabel) { ls_items[j].detail = ls_items[j].label; ls_items[j].label = ls_items[j].filterText.value_or(""); } } +#if LLVM_VERSION_MAJOR >= 7 + for (const FixItHint &FixIt : R.FixIts) { + auto &AST = S.getASTContext(); + lsTextEdit ls_edit = + ccls::ToTextEdit(AST.getSourceManager(), AST.getLangOpts(), FixIt); + for (size_t j = first_idx; j < ls_items.size(); j++) + ls_items[j].additionalTextEdits.push_back(ls_edit); + } +#endif } } @@ -497,7 +499,7 @@ struct Handler_TextDocumentCompletion void Run(In_TextDocumentComplete *request) override { static CompleteConsumerCache> cache; - auto ¶ms = request->params; + const auto ¶ms = request->params; Out_TextDocumentComplete out; out.id = request->id; @@ -556,55 +558,36 @@ struct Handler_TextDocumentCompletion std::string completion_text; lsPosition end_pos = params.position; - params.position = file->FindStableCompletionSource( - request->params.position, &completion_text, &end_pos); + lsPosition begin_pos = file->FindStableCompletionSource( + params.position, &completion_text, &end_pos); - ParseIncludeLineResult result = ParseIncludeLine(buffer_line); + ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos); - if (result.ok) { + if (preprocess.ok && preprocess.keyword.compare("include") == 0) { Out_TextDocumentComplete out; out.id = request->id; - - if (result.quote.empty() && result.pattern.empty()) { - // no quote or path of file, do preprocessor keyword completion - if (!std::any_of(preprocessorKeywords.begin(), - preprocessorKeywords.end(), - [&result](std::string_view k) { - return k == result.keyword; - })) { - out.result.items = PreprocessorKeywordCompletionItems(result.match); - FilterAndSortCompletionResponse(&out, result.keyword, has_open_paren); - } - } else if (result.keyword.compare("include") == 0) { - { - // do include completion - std::unique_lock lock( - include_complete->completion_items_mutex, std::defer_lock); - if (include_complete->is_scanning) - lock.lock(); - std::string quote = result.match[5]; - for (auto &item : include_complete->completion_items) - if (quote.empty() || - quote == (item.use_angle_brackets_ ? "<" : "\"")) - out.result.items.push_back(item); - } - FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren); - DecorateIncludePaths(result.match, &out.result.items); + { + std::unique_lock lock( + include_complete->completion_items_mutex, std::defer_lock); + if (include_complete->is_scanning) + lock.lock(); + std::string quote = preprocess.match[5]; + for (auto &item : include_complete->completion_items) + if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + out.result.items.push_back(item); } - - for (lsCompletionItem &item : out.result.items) { - item.textEdit->range.start.line = params.position.line; - item.textEdit->range.start.character = 0; - item.textEdit->range.end.line = params.position.line; - item.textEdit->range.end.character = (int)buffer_line.size(); - } - + begin_pos.character = 0; + end_pos.character = (int)buffer_line.size(); + FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos, + has_open_paren); + DecorateIncludePaths(preprocess.match, &out.result.items); pipeline::WriteStdout(kMethodType, out); } else { + std::string path = params.textDocument.uri.GetPath(); CompletionManager::OnComplete callback = - [completion_text, has_open_paren, id = request->id, - params = request->params](CodeCompleteConsumer *OptConsumer) { + [completion_text, path, begin_pos, end_pos, has_open_paren, + id = request->id](CodeCompleteConsumer *OptConsumer) { if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); @@ -612,14 +595,13 @@ struct Handler_TextDocumentCompletion out.id = id; out.result.items = Consumer->ls_items; - FilterAndSortCompletionResponse(&out, completion_text, - has_open_paren); + FilterCandidates(&out, completion_text, begin_pos, end_pos, + has_open_paren); pipeline::WriteStdout(kMethodType, out); if (!Consumer->from_cache) { - std::string path = params.textDocument.uri.GetPath(); cache.WithLock([&]() { cache.path = path; - cache.position = params.position; + cache.position = begin_pos; cache.result = Consumer->ls_items; }); } @@ -627,18 +609,19 @@ struct Handler_TextDocumentCompletion clang::CodeCompleteOptions CCOpts; CCOpts.IncludeBriefComments = true; + CCOpts.IncludeCodePatterns = preprocess.ok; // if there is a # #if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; #endif CCOpts.IncludeMacros = true; - if (cache.IsCacheValid(params)) { + if (cache.IsCacheValid(path, begin_pos)) { CompletionConsumer Consumer(CCOpts, true); cache.WithLock([&]() { Consumer.ls_items = cache.result; }); callback(&Consumer); } else { clang_complete->completion_request_.PushBack( std::make_unique( - request->id, params.textDocument, params.position, + request->id, params.textDocument, begin_pos, std::make_unique(CCOpts, false), CCOpts, callback)); } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 1635cb35e..ef501c536 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -184,18 +184,18 @@ struct Handler_TextDocumentSignatureHelp void Run(In_TextDocumentSignatureHelp *request) override { static CompleteConsumerCache cache; - auto ¶ms = request->params; + const auto ¶ms = request->params; std::string path = params.textDocument.uri.GetPath(); + lsPosition begin_pos = params.position; if (WorkingFile *file = working_files->GetFileByFilename(path)) { std::string completion_text; lsPosition end_pos = params.position; - params.position = file->FindStableCompletionSource( + begin_pos = file->FindStableCompletionSource( request->params.position, &completion_text, &end_pos); } CompletionManager::OnComplete callback = - [id = request->id, - params = request->params](CodeCompleteConsumer *OptConsumer) { + [id = request->id, path, begin_pos](CodeCompleteConsumer *OptConsumer) { if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); @@ -204,10 +204,9 @@ struct Handler_TextDocumentSignatureHelp out.result = Consumer->ls_sighelp; pipeline::WriteStdout(kMethodType, out); if (!Consumer->from_cache) { - std::string path = params.textDocument.uri.GetPath(); cache.WithLock([&]() { cache.path = path; - cache.position = params.position; + cache.position = begin_pos; cache.result = Consumer->ls_sighelp; }); } @@ -217,7 +216,7 @@ struct Handler_TextDocumentSignatureHelp CCOpts.IncludeGlobals = false; CCOpts.IncludeMacros = false; CCOpts.IncludeBriefComments = false; - if (cache.IsCacheValid(params)) { + if (cache.IsCacheValid(path, begin_pos)) { SignatureHelpConsumer Consumer(CCOpts, true); cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); callback(&Consumer); From 5a1ed4c94385b9d2a3f6b711485f2c45360c0b81 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 7 Oct 2018 22:02:28 -0700 Subject: [PATCH 255/378] Support workspace folders --- CMakeLists.txt | 2 +- src/clang_tu.cc | 4 +- src/config.h | 5 +- src/include_complete.cc | 59 +++---- src/lsp.h | 6 + src/message_handler.cc | 15 +- src/messages/ccls_info.cc | 4 +- src/messages/initialize.cc | 45 ++++-- src/messages/workspace_did.cc | 108 +++++++++++++ .../workspace_didChangeConfiguration.cc | 49 ------ src/pipeline.cc | 28 ++-- src/project.cc | 146 ++++++++++-------- src/project.h | 17 +- 13 files changed, 298 insertions(+), 190 deletions(-) create mode 100644 src/messages/workspace_did.cc delete mode 100644 src/messages/workspace_didChangeConfiguration.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 47af70f04..29a3008fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,7 +231,7 @@ target_sources(ccls PRIVATE src/messages/textDocument_rename.cc src/messages/textDocument_signatureHelp.cc src/messages/textDocument_typeDefinition.cc - src/messages/workspace_didChangeConfiguration.cc + src/messages/workspace_did.cc src/messages/workspace_didChangeWatchedFiles.cc src/messages/workspace_symbol.cc ) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index b58a69e9c..d1dd3f021 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -30,7 +30,9 @@ std::string PathFromFileEntry(const FileEntry &file) { Name = file.getName(); std::string ret = NormalizePath(Name); // Resolve /usr/include/c++/7.3.0 symlink. - if (!StartsWith(ret, g_config->projectRoot)) { + if (!llvm::any_of(g_config->workspaceFolders, [&](const std::string &root) { + return StartsWith(ret, root); + })) { SmallString<256> dest; llvm::sys::fs::real_path(ret, dest); ret = llvm::sys::path::convert_to_slash(dest.str()); diff --git a/src/config.h b/src/config.h index abb31deec..b358cb673 100644 --- a/src/config.h +++ b/src/config.h @@ -29,8 +29,9 @@ initialization options specified by the client. For example, in shell syntax: '--init={"index": {"comments": 2, "whitelist": ["."]}}' */ struct Config { - // Root directory of the project. **Not available for configuration** - std::string projectRoot; + // **Not available for configuration** + std::string fallbackFolder; + std::vector workspaceFolders; // If specified, this option overrides compile_commands.json and this // external command will be executed with an option |projectRoot|. // The initialization options will be provided as stdin. diff --git a/src/include_complete.cc b/src/include_complete.cc index cf220a56e..c75398495 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -59,23 +59,27 @@ size_t TrimCommonPathPrefix(const std::string &result, } // Returns true iff angle brackets should be used. -bool TrimPath(Project *project, const std::string &project_root, - std::string *insert_path) { - size_t start = TrimCommonPathPrefix(*insert_path, project_root); +bool TrimPath(Project *project, std::string &path) { + size_t pos = 0; bool angle = false; - - for (auto &include_dir : project->quote_include_directories) - start = std::max(start, TrimCommonPathPrefix(*insert_path, include_dir)); - - for (auto &include_dir : project->angle_include_directories) { - auto len = TrimCommonPathPrefix(*insert_path, include_dir); - if (len > start) { - start = len; + for (auto &[root, folder] : project->root2folder) { + size_t pos1 = 0; + for (auto &search : folder.angle_search_list) + pos1 = std::max(pos1, TrimCommonPathPrefix(path, search)); + if (pos1 > pos) { + pos = pos1; angle = true; } - } - *insert_path = insert_path->substr(start); + pos1 = TrimCommonPathPrefix(path, root); + for (auto &search : folder.quote_search_list) + pos1 = std::max(pos1, TrimCommonPathPrefix(path, search)); + if (pos1 > pos) { + pos = pos1; + angle = false; + } + } + path = path.substr(pos); return angle; } @@ -119,13 +123,15 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { set_thread_name("include"); - Timer timer("include", "scan include paths"); - TimeRegion region(timer); - - for (const std::string &dir : project_->quote_include_directories) - InsertIncludesFromDirectory(dir, false /*use_angle_brackets*/); - for (const std::string &dir : project_->angle_include_directories) - InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/); + std::unordered_set angle_set, quote_set; + for (auto &[root, folder] : project_->root2folder) { + for (const std::string &search : folder.angle_search_list) + if (angle_set.insert(search).second) + InsertIncludesFromDirectory(search, true); + for (const std::string &search : folder.quote_search_list) + if (quote_set.insert(search).second) + InsertIncludesFromDirectory(search, false); + } is_scanning = false; }) @@ -152,22 +158,21 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, } } -void IncludeComplete::AddFile(const std::string &absolute_path) { - if (!EndsWithAny(absolute_path, g_config->completion.include.suffixWhitelist)) +void IncludeComplete::AddFile(const std::string &path) { + if (!EndsWithAny(path, g_config->completion.include.suffixWhitelist)) return; - if (match_ && !match_->IsMatch(absolute_path)) + if (match_ && !match_->IsMatch(path)) return; - std::string trimmed_path = absolute_path; - bool use_angle_brackets = - TrimPath(project_, g_config->projectRoot, &trimmed_path); + std::string trimmed_path = path; + bool use_angle_brackets = TrimPath(project_, trimmed_path); lsCompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets, false /*is_stl*/); std::unique_lock lock(completion_items_mutex, std::defer_lock); if (is_scanning) lock.lock(); - InsertCompletionItem(absolute_path, std::move(item)); + InsertCompletionItem(path, std::move(item)); } void IncludeComplete::InsertIncludesFromDirectory(std::string directory, diff --git a/src/lsp.h b/src/lsp.h index dbe73984b..aa8029dd9 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -307,6 +307,12 @@ struct lsTextDocumentDidChangeParams { MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, textDocument, contentChanges); +struct lsWorkspaceFolder { + lsDocumentUri uri; + std::string name; +}; +MAKE_REFLECT_STRUCT(lsWorkspaceFolder, uri, name); + // Show a message to the user. enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; MAKE_REFLECT_TYPE_PROXY(lsMessageType) diff --git a/src/message_handler.cc b/src/message_handler.cc index 1b699ed0b..ddffa25c7 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -90,27 +90,24 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, if (out_file_id) *out_file_id = -1; - bool indexing; + bool has_entry = false; { std::lock_guard lock(project->mutex_); - indexing = project->path_to_entry_index.find(absolute_path) != - project->path_to_entry_index.end(); + for (auto &[root, folder] : project->root2folder) + has_entry |= folder.path2entry_index.count(absolute_path); } - if (indexing) - LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; - else - LOG_S(INFO) << "unable to find file \"" << absolute_path << "\""; if (id) { Out_Error out; out.id = *id; - if (indexing) { + if (has_entry) { out.error.code = lsErrorCodes::ServerNotInitialized; - out.error.message = absolute_path + " is being indexed."; + out.error.message = absolute_path + " is being indexed"; } else { out.error.code = lsErrorCodes::InternalError; out.error.message = "Unable to find file " + absolute_path; } + LOG_S(INFO) << out.error.message; pipeline::WriteStdout(kMethodType_Unknown, out); } diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 3efcae500..8aa99f8ba 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -61,7 +61,9 @@ struct Handler_cclsInfo : BaseMessageHandler { out.result.db.types = db->types.size(); out.result.db.vars = db->vars.size(); out.result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; - out.result.project.entries = project->entries.size(); + out.result.project.entries = 0; + for (auto &[_, folder] : project->root2folder) + out.result.project.entries += folder.entries.size(); pipeline::WriteStdout(cclsInfo, out); } }; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cd9d378e0..a7e6bd41f 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -176,8 +176,17 @@ struct lsServerCapabilities { struct ExecuteCommandOptions { std::vector commands{std::string(ccls_xref)}; } executeCommandProvider; + struct Workspace { + struct WorkspaceFolders { + bool supported = true; + bool changeNotifications = true; + } workspaceFolders; + } workspace; }; MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands); +MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders, + supported, changeNotifications); +MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace, workspaceFolders); MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, completionProvider, signatureHelpProvider, definitionProvider, implementationProvider, @@ -187,7 +196,7 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, codeLensProvider, documentFormattingProvider, documentRangeFormattingProvider, documentOnTypeFormattingProvider, renameProvider, - documentLinkProvider, executeCommandProvider); + documentLinkProvider, executeCommandProvider, workspace); // Workspace specific client capabilities. struct lsWorkspaceClientCapabilites { @@ -345,6 +354,8 @@ struct lsInitializeParams { // The initial trace setting. If omitted trace is disabled ('off'). lsTrace trace = lsTrace::Off; + + std::vector workspaceFolders; }; void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { @@ -378,7 +389,8 @@ void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) { #endif MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, - initializationOptions, capabilities, trace); + initializationOptions, capabilities, trace, + workspaceFolders); struct lsInitializeError { // Indicates whether the client should retry to send the @@ -484,19 +496,28 @@ struct Handler_Initialize : BaseMessageHandler { // Set project root. EnsureEndsInSlash(project_path); - g_config->projectRoot = project_path; - if (g_config->cacheDirectory.size()) { - // Create two cache directories for files inside and outside of the - // project. - auto len = g_config->projectRoot.size(); - std::string escaped = EscapeFileName(g_config->projectRoot.substr(0, len - 1)); - sys::fs::create_directories(g_config->cacheDirectory + escaped); - sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); + g_config->fallbackFolder = project_path; + for (const lsWorkspaceFolder &wf : request->params.workspaceFolders) { + std::string path = wf.uri.GetPath(); + EnsureEndsInSlash(path); + g_config->workspaceFolders.push_back(path); + LOG_S(INFO) << "add workspace folder " << wf.name << ": " << path; } + if (request->params.workspaceFolders.empty()) + g_config->workspaceFolders.push_back(project_path); + if (g_config->cacheDirectory.size()) + for (const std::string &folder : g_config->workspaceFolders) { + // Create two cache directories for files inside and outside of the + // project. + std::string escaped = + EscapeFileName(folder.substr(0, folder.size() - 1)); + sys::fs::create_directories(g_config->cacheDirectory + escaped); + sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); + } idx::Init(); - - project->Load(project_path); + for (const std::string &folder : g_config->workspaceFolders) + project->Load(folder); // Start indexer threads. Start this after loading the project, as that // may take a long time. Indexer threads will emit status/progress diff --git a/src/messages/workspace_did.cc b/src/messages/workspace_did.cc new file mode 100644 index 000000000..949436f5c --- /dev/null +++ b/src/messages/workspace_did.cc @@ -0,0 +1,108 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "clang_complete.hh" +#include "log.hh" +#include "message_handler.h" +#include "pipeline.hh" +#include "project.h" +#include "working_files.h" + +#include +using namespace ccls; + +namespace { +MethodType didChangeConfiguration = "workspace/didChangeConfiguration", + didChangeWorkspaceFolders = "workspace/didChangeWorkspaceFolders"; + +struct lsDidChangeConfigurationParams { + bool placeholder; +}; +MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); + +struct In_workspaceDidChangeConfiguration : public NotificationInMessage { + MethodType GetMethodType() const override { return didChangeConfiguration; } + lsDidChangeConfigurationParams params; +}; +MAKE_REFLECT_STRUCT(In_workspaceDidChangeConfiguration, params); +REGISTER_IN_MESSAGE(In_workspaceDidChangeConfiguration); + +struct Handler_workspaceDidChangeConfiguration + : BaseMessageHandler { + MethodType GetMethodType() const override { return didChangeConfiguration; } + void Run(In_workspaceDidChangeConfiguration *request) override { + for (const std::string &folder : g_config->workspaceFolders) + project->Load(folder); + + project->Index(working_files, lsRequestId()); + + clang_complete->FlushAllSessions(); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_workspaceDidChangeConfiguration); + +struct lsWorkspaceFoldersChangeEvent { + std::vector added, removed; +}; +MAKE_REFLECT_STRUCT(lsWorkspaceFoldersChangeEvent, added, removed); + +struct In_workspaceDidChangeWorkspaceFolders : public NotificationInMessage { + MethodType GetMethodType() const override { + return didChangeWorkspaceFolders; + } + struct Params { + lsWorkspaceFoldersChangeEvent event; + } params; +}; +MAKE_REFLECT_STRUCT(In_workspaceDidChangeWorkspaceFolders::Params, event); +MAKE_REFLECT_STRUCT(In_workspaceDidChangeWorkspaceFolders, params); +REGISTER_IN_MESSAGE(In_workspaceDidChangeWorkspaceFolders); + +struct Handler_workspaceDidChangeWorkspaceFolders + : BaseMessageHandler { + MethodType GetMethodType() const override { + return didChangeWorkspaceFolders; + } + void Run(In_workspaceDidChangeWorkspaceFolders *request) override { + const auto &event = request->params.event; + for (const lsWorkspaceFolder &wf : event.removed) { + std::string root = wf.uri.GetPath(); + EnsureEndsInSlash(root); + LOG_S(INFO) << "delete workspace folder " << wf.name << ": " << root; + auto it = llvm::find(g_config->workspaceFolders, root); + if (it != g_config->workspaceFolders.end()) { + g_config->workspaceFolders.erase(it); + { + // auto &folder = project->root2folder[path]; + // FIXME delete + } + project->root2folder.erase(root); + } + } + for (const lsWorkspaceFolder &wf : event.added) { + std::string root = wf.uri.GetPath(); + EnsureEndsInSlash(root); + LOG_S(INFO) << "add workspace folder " << wf.name << ": " << root; + g_config->workspaceFolders.push_back(root); + project->Load(root); + } + + project->Index(working_files, lsRequestId()); + + clang_complete->FlushAllSessions(); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_workspaceDidChangeWorkspaceFolders); +} // namespace diff --git a/src/messages/workspace_didChangeConfiguration.cc b/src/messages/workspace_didChangeConfiguration.cc deleted file mode 100644 index 9b9ba474b..000000000 --- a/src/messages/workspace_didChangeConfiguration.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "message_handler.h" -#include "pipeline.hh" -#include "project.h" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "workspace/didChangeConfiguration"; - -struct lsDidChangeConfigurationParams { - bool placeholder; -}; -MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); - -struct In_WorkspaceDidChangeConfiguration : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsDidChangeConfigurationParams params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeConfiguration, params); -REGISTER_IN_MESSAGE(In_WorkspaceDidChangeConfiguration); - -struct Handler_WorkspaceDidChangeConfiguration - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceDidChangeConfiguration *request) override { - project->Load(g_config->projectRoot); - project->Index(working_files, lsRequestId()); - - clang_complete->FlushAllSessions(); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeConfiguration); -} // namespace diff --git a/src/pipeline.cc b/src/pipeline.cc index c61469c04..f230413d7 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -128,18 +128,17 @@ std::string AppendSerializationFormat(const std::string &base) { } std::string GetCachePath(const std::string &source_file) { - std::string cache_file; - auto len = g_config->projectRoot.size(); - if (StartsWith(source_file, g_config->projectRoot)) { - cache_file = EscapeFileName(g_config->projectRoot.substr(0, len - 1)) + '/' + - EscapeFileName(source_file.substr(len)); - } else { - cache_file = '@' + - EscapeFileName(g_config->projectRoot.substr(0, len - 1)) + '/' + - EscapeFileName(source_file); - } - - return g_config->cacheDirectory + cache_file; + for (auto &root : g_config->workspaceFolders) + if (StartsWith(source_file, root)) { + auto len = root.size(); + return g_config->cacheDirectory + + EscapeFileName(root.substr(0, len - 1)) + '/' + + EscapeFileName(source_file.substr(len)); + } + return g_config->cacheDirectory + '@' + + EscapeFileName(g_config->fallbackFolder.substr( + 0, g_config->fallbackFolder.size() - 1)) + + '/' + EscapeFileName(source_file); } std::unique_ptr RawCacheLoad(const std::string &path) { @@ -280,7 +279,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, request.mode != IndexMode::NonInteractive); if (entry.id >= 0) { std::lock_guard lock2(project->mutex_); - project->path_to_entry_index[path] = entry.id; + project->root2folder[entry.root].path2entry_index[path] = entry.id; } } return true; @@ -343,8 +342,9 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, } if (entry.id >= 0) { std::lock_guard lock(project->mutex_); + auto &folder = project->root2folder[entry.root]; for (auto &dep : curr->dependencies) - project->path_to_entry_index[dep.first.val().str()] = entry.id; + folder.path2entry_index[dep.first.val().str()] = entry.id; } } } diff --git a/src/project.cc b/src/project.cc index 1278e1e48..7968b5bbe 100644 --- a/src/project.cc +++ b/src/project.cc @@ -54,7 +54,7 @@ enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; struct ProjectConfig { std::unordered_set quote_dirs; std::unordered_set angle_dirs; - std::string project_dir; + std::string root; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -183,7 +183,7 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { std::vector result; config->mode = ProjectMode::DotCcls; SmallString<256> Path; - sys::path::append(Path, config->project_dir, ".ccls"); + sys::path::append(Path, config->root, ".ccls"); LOG_IF_S(WARNING, !sys::fs::exists(Path) && g_config->clang.extraArgs.empty()) << "ccls has no clang arguments. Use either " "compile_commands.json or .ccls, See ccls README for " @@ -191,9 +191,9 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { std::unordered_map> folder_args; std::vector files; - const std::string &project_dir = config->project_dir; + const std::string &root = config->root; - GetFilesInFolder(project_dir, true /*recursive*/, + GetFilesInFolder(root, true /*recursive*/, true /*add_folder_to_path*/, [&folder_args, &files](const std::string &path) { if (SourceFileLanguage(path) != LanguageId::Unknown) { @@ -211,7 +211,7 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { } }); - auto GetCompilerArgumentForFile = [&project_dir, + auto GetCompilerArgumentForFile = [&root, &folder_args](std::string cur) { while (!(cur = sys::path::parent_path(cur)).empty()) { auto it = folder_args.find(cur); @@ -219,17 +219,18 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { return it->second; std::string normalized = NormalizePath(cur); // Break if outside of the project root. - if (normalized.size() <= project_dir.size() || - normalized.compare(0, project_dir.size(), project_dir) != 0) + if (normalized.size() <= root.size() || + normalized.compare(0, root.size(), root) != 0) break; } - return folder_args[project_dir]; + return folder_args[root]; }; ProjectProcessor proc(config); for (const std::string &file : files) { Project::Entry e; - e.directory = config->project_dir; + e.root = config->root; + e.directory = config->root; e.filename = file; e.args = GetCompilerArgumentForFile(file); if (e.args.empty()) @@ -247,7 +248,7 @@ LoadEntriesFromDirectory(ProjectConfig *project, const std::string &opt_compdb_dir) { // If there is a .ccls file always load using directory listing. SmallString<256> Path; - sys::path::append(Path, project->project_dir, ".ccls"); + sys::path::append(Path, project->root, ".ccls"); if (sys::fs::exists(Path)) return LoadFromDirectoryListing(project); @@ -257,8 +258,7 @@ LoadEntriesFromDirectory(ProjectConfig *project, if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = - opt_compdb_dir.empty() ? project->project_dir : opt_compdb_dir; + comp_db_dir = opt_compdb_dir.empty() ? project->root : opt_compdb_dir; sys::path::append(Path, comp_db_dir, "compile_commands.json"); } else { project->mode = ProjectMode::ExternalCommand; @@ -276,7 +276,7 @@ LoadEntriesFromDirectory(ProjectConfig *project, Reflect(json_writer, *g_config); std::string contents = GetExternalCommandOutput( std::vector{g_config->compilationDatabaseCommand, - project->project_dir}, + project->root}, input.GetString()); FILE *fout = fopen(Path.c_str(), "wb"); fwrite(contents.c_str(), contents.size(), 1, fout); @@ -307,6 +307,8 @@ LoadEntriesFromDirectory(ProjectConfig *project, ProjectProcessor proc(project); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { Project::Entry entry; + entry.root = project->root; + DoPathMapping(entry.root); entry.directory = NormalizePath(Cmd.Directory); DoPathMapping(entry.directory); entry.filename = @@ -342,77 +344,78 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace -void Project::Load(const std::string &root_directory) { +void Project::Load(const std::string &root) { + assert(root.back() == '/'); ProjectConfig project; - project.project_dir = root_directory; - entries = LoadEntriesFromDirectory(&project, - g_config->compilationDatabaseDirectory); - - // Cleanup / postprocess include directories. - quote_include_directories.assign(project.quote_dirs.begin(), - project.quote_dirs.end()); - angle_include_directories.assign(project.angle_dirs.begin(), - project.angle_dirs.end()); - for (std::string &path : quote_include_directories) { + project.root = root; + Folder &folder = root2folder[root]; + + folder.entries = LoadEntriesFromDirectory( + &project, g_config->compilationDatabaseDirectory); + folder.quote_search_list.assign(project.quote_dirs.begin(), + project.quote_dirs.end()); + folder.angle_search_list.assign(project.angle_dirs.begin(), + project.angle_dirs.end()); + for (std::string &path : folder.angle_search_list) { EnsureEndsInSlash(path); - LOG_S(INFO) << "quote_include_dir: " << path; + LOG_S(INFO) << "angle search: " << path; } - for (std::string &path : angle_include_directories) { + for (std::string &path : folder.quote_search_list) { EnsureEndsInSlash(path); - LOG_S(INFO) << "angle_include_dir: " << path; + LOG_S(INFO) << "quote search: " << path; } // Setup project entries. std::lock_guard lock(mutex_); - path_to_entry_index.reserve(entries.size()); - for (size_t i = 0; i < entries.size(); ++i) { - entries[i].id = i; - path_to_entry_index[entries[i].filename] = i; + folder.path2entry_index.reserve(folder.entries.size()); + for (size_t i = 0; i < folder.entries.size(); ++i) { + folder.entries[i].id = i; + folder.path2entry_index[folder.entries[i].filename] = i; } } void Project::SetArgsForFile(const std::vector &args, const std::string &path) { std::lock_guard lock(mutex_); - auto it = path_to_entry_index.find(path); - if (it != path_to_entry_index.end()) { - // The entry already exists in the project, just set the flags. - this->entries[it->second].args = args; - } else { - // Entry wasn't found, so we create a new one. - Entry entry; - entry.is_inferred = false; - entry.filename = path; - entry.args = args; - this->entries.emplace_back(entry); + for (auto &[root, folder] : root2folder) { + auto it = folder.path2entry_index.find(path); + if (it != folder.path2entry_index.end()) { + // The entry already exists in the project, just set the flags. + folder.entries[it->second].args = args; + return; + } } } Project::Entry Project::FindEntry(const std::string &path, bool can_be_inferred) { - { - std::lock_guard lock(mutex_); - auto it = path_to_entry_index.find(path); - if (it != path_to_entry_index.end()) { - Project::Entry &entry = entries[it->second]; + std::lock_guard lock(mutex_); + for (auto &[root, folder] : root2folder) { + auto it = folder.path2entry_index.find(path); + if (it != folder.path2entry_index.end()) { + Project::Entry &entry = folder.entries[it->second]; if (can_be_inferred || entry.filename == path) return entry; } } - // We couldn't find the file. Try to infer it. - // TODO: Cache inferred file in a separate array (using a lock or similar) - Entry *best_entry = nullptr; + Project::Entry result; + const Entry *best_entry = nullptr; int best_score = INT_MIN; - for (Entry &entry : entries) { - int score = ComputeGuessScore(path, entry.filename); - if (score > best_score) { - best_score = score; - best_entry = &entry; + for (auto &[root, folder] : root2folder) { + for (const Entry &entry : folder.entries) { + int score = ComputeGuessScore(path, entry.filename); + if (score > best_score) { + best_score = score; + best_entry = &entry; + } } + if (StartsWith(path, root)) + result.root = root; } + if (result.root.empty()) + result.root = g_config->fallbackFolder; - Project::Entry result; result.is_inferred = true; result.filename = path; if (!best_entry) { @@ -442,18 +445,25 @@ void Project::Index(WorkingFiles *wfiles, lsRequestId id) { auto &gi = g_config->index; GroupMatch match(gi.whitelist, gi.blacklist), match_i(gi.initialWhitelist, gi.initialBlacklist); - for (int i = 0; i < entries.size(); ++i) { - const Project::Entry &entry = entries[i]; - std::string reason; - if (match.IsMatch(entry.filename, &reason) && - match_i.IsMatch(entry.filename, &reason)) { - bool interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - pipeline::Index( - entry.filename, entry.args, - interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); - } else { - LOG_V(1) << "[" << i << "/" << entries.size() << "]: " << reason - << "; skip " << entry.filename; + { + std::lock_guard lock(mutex_); + for (auto &[root, folder] : root2folder) { + int i = 0; + for (const Project::Entry &entry : folder.entries) { + std::string reason; + if (match.IsMatch(entry.filename, &reason) && + match_i.IsMatch(entry.filename, &reason)) { + bool interactive = + wfiles->GetFileByFilename(entry.filename) != nullptr; + pipeline::Index( + entry.filename, entry.args, + interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); + } else { + LOG_V(1) << "[" << i << "/" << folder.entries.size() << "]: " << reason + << "; skip " << entry.filename; + } + i++; + } } } diff --git a/src/project.h b/src/project.h index 59a898556..1cc5eff88 100644 --- a/src/project.h +++ b/src/project.h @@ -28,6 +28,7 @@ struct WorkingFiles; struct Project { struct Entry { + std::string root; std::string directory; std::string filename; std::vector args; @@ -36,14 +37,18 @@ struct Project { int id = -1; }; - // Include directories for "" headers - std::vector quote_include_directories; - // Include directories for <> headers - std::vector angle_include_directories; + struct Folder { + std::string name; + // Include directories for <> headers + std::vector angle_search_list; + // Include directories for "" headers + std::vector quote_search_list; + std::vector entries; + std::unordered_map path2entry_index; + }; - std::vector entries; std::mutex mutex_; - std::unordered_map path_to_entry_index; + std::unordered_map root2folder; // Loads a project for the given |directory|. // From ac2d921ab91d04ce22fdb9f7de8ece42c80d5902 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Wed, 10 Oct 2018 06:36:39 +0800 Subject: [PATCH 256/378] Fix additionalTextEdits -> textEdit hack for VS Code (#89) * Fix additionalTextEdits -> textEdit hack for VS Code Visual Studio Code filters the completion result according to textEdit.range and filterText, if the textEdit.range overlaps with existing text, we have to include it in filterText, otherwise it would be filtered out. * Fix has_open_paren in FilterCandidates --- src/messages/textDocument_completion.cc | 56 ++++++++++++------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 5558c8061..ab57ff5eb 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -155,9 +155,20 @@ template char *tofixedbase64(T input, char *out) { // when given 1000+ completion items. void FilterCandidates(Out_TextDocumentComplete *complete_response, const std::string &complete_text, lsPosition begin_pos, - lsPosition end_pos, bool has_open_paren) { + lsPosition end_pos, const std::string &buffer_line) { + assert(begin_pos.line == end_pos.line); auto &items = complete_response->result.items; + // People usually does not want to insert snippets or parenthesis when + // changing function or type names, e.g. "str.|()" or "std::|". + bool has_open_paren = false; + for (int c = end_pos.character; c < buffer_line.size(); ++c) { + if (buffer_line[c] == '(' || buffer_line[c] == '<') + has_open_paren = true; + if (!isspace(buffer_line[c])) + break; + } + auto finalize = [&]() { int max_num = g_config->completion.maxNum; if (items.size() > max_num) { @@ -167,14 +178,21 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response, for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; - if (has_open_paren) - item.textEdit.newText = item.label; + if (has_open_paren && item.filterText) + item.textEdit.newText = item.filterText.value(); // https://github.com/Microsoft/language-server-protocol/issues/543 // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; if (edits.size() && edits[0].range.end == begin_pos) { - item.textEdit.range.start = edits[0].range.start; + lsPosition start = edits[0].range.start, end = edits[0].range.end; + item.textEdit.range.start = start; item.textEdit.newText = edits[0].newText + item.textEdit.newText; + if (start.line == begin_pos.line && item.filterText) { + item.filterText = + buffer_line.substr(start.character, + end.character - start.character) + + item.filterText.value(); + } edits.erase(edits.begin()); } // Compatibility @@ -229,27 +247,6 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response, finalize(); } -// Returns true if position is an points to a '(' character in |lines|. Skips -// whitespace. -bool IsOpenParenOrAngle(const std::vector &lines, - const lsPosition &position) { - auto [c, l] = position; - while (l < lines.size()) { - const auto &line = lines[l]; - if (c >= line.size()) - return false; - if (line[c] == '(' || line[c] == '<') - return true; - if (!isspace(line[c])) - break; - if (++c >= line.size()) { - c = 0; - l++; - } - } - return false; -} - lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { case CXCursor_UnexposedDecl: @@ -562,7 +559,6 @@ struct Handler_TextDocumentCompletion params.position, &completion_text, &end_pos); ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); - bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos); if (preprocess.ok && preprocess.keyword.compare("include") == 0) { Out_TextDocumentComplete out; @@ -580,14 +576,14 @@ struct Handler_TextDocumentCompletion begin_pos.character = 0; end_pos.character = (int)buffer_line.size(); FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos, - has_open_paren); + buffer_line); DecorateIncludePaths(preprocess.match, &out.result.items); pipeline::WriteStdout(kMethodType, out); } else { std::string path = params.textDocument.uri.GetPath(); CompletionManager::OnComplete callback = - [completion_text, path, begin_pos, end_pos, has_open_paren, - id = request->id](CodeCompleteConsumer *OptConsumer) { + [completion_text, path, begin_pos, end_pos, + id = request->id, buffer_line](CodeCompleteConsumer *OptConsumer) { if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); @@ -596,7 +592,7 @@ struct Handler_TextDocumentCompletion out.result.items = Consumer->ls_items; FilterCandidates(&out, completion_text, begin_pos, end_pos, - has_open_paren); + buffer_line); pipeline::WriteStdout(kMethodType, out); if (!Consumer->from_cache) { cache.WithLock([&]() { From c5ae521d36a0cd05b5df7ddd2e03ab23b68e8270 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 9 Oct 2018 22:29:51 -0700 Subject: [PATCH 257/378] Namespace: improve indexer and don't trace bases in $ccls/member --- src/indexer.cc | 13 +++++++++++-- src/messages/ccls_member.cc | 16 +++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index e4356146c..341376306 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -734,8 +734,17 @@ class IndexDataConsumer : public index::IndexDataConsumer { // spell, extent, comments use OrigD while most others use adjusted |D|. const Decl *OrigD = ASTNode.OrigD; - const DeclContext *SemDC = OrigD->getDeclContext(); - const DeclContext *LexDC = ASTNode.ContainerDC; + const DeclContext *SemDC = OrigD->getDeclContext()->getRedeclContext(); + const DeclContext *LexDC = ASTNode.ContainerDC->getRedeclContext(); + { + const NamespaceDecl *ND; + while ((ND = dyn_cast(cast(SemDC))) && + ND->isAnonymousNamespace()) + SemDC = ND->getDeclContext()->getRedeclContext(); + while ((ND = dyn_cast(cast(LexDC))) && + ND->isAnonymousNamespace()) + LexDC = ND->getDeclContext()->getRedeclContext(); + } Role role = static_cast(Roles); db->language = LanguageId((int)db->language | (int)GetDeclLanguage(D)); diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index 47241aad1..b5ae481b6 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -145,14 +145,16 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, type = stack.back(); stack.pop_back(); const auto *def = type->AnyDef(); - if (!def) continue; - for (Usr usr : def->bases) { - auto &type1 = m->db->Type(usr); - if (type1.def.size()) { - seen.insert(type1.usr); - stack.push_back(&type1); + if (!def) + continue; + if (def->kind != lsSymbolKind::Namespace) + for (Usr usr : def->bases) { + auto &type1 = m->db->Type(usr); + if (type1.def.size()) { + seen.insert(type1.usr); + stack.push_back(&type1); + } } - } if (def->alias_of) { const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); Out_CclsMember::Entry entry1; From 51081c3cd259398e9b578fe4714060e257b36faf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 10 Oct 2018 09:52:41 -0700 Subject: [PATCH 258/378] Add namespace alias clang::vfs = llvm::vfs to adapt D52783 vfs::x should be written as llvm::vfs::x to work around a [namepace.udir] bug before GCC 8 when namespace alias is used --- src/clang_complete.cc | 38 ++++++++++++++++++++------------------ src/clang_complete.hh | 4 ++-- src/clang_tu.cc | 2 +- src/clang_tu.hh | 9 ++++++++- src/indexer.cc | 2 +- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 32ef2ef7b..317d09086 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -84,20 +84,21 @@ lsTextEdit ToTextEdit(const clang::SourceManager &SM, } struct PreambleStatCache { - llvm::StringMap> Cache; + llvm::StringMap> Cache; - void Update(Twine Path, ErrorOr S) { + void Update(Twine Path, ErrorOr S) { Cache.try_emplace(Path.str(), std::move(S)); } - IntrusiveRefCntPtr - Producer(IntrusiveRefCntPtr FS) { - struct VFS : vfs::ProxyFileSystem { + IntrusiveRefCntPtr + Producer(IntrusiveRefCntPtr FS) { + struct VFS : llvm::vfs::ProxyFileSystem { PreambleStatCache &Cache; - VFS(IntrusiveRefCntPtr FS, PreambleStatCache &Cache) + VFS(IntrusiveRefCntPtr FS, + PreambleStatCache &Cache) : ProxyFileSystem(std::move(FS)), Cache(Cache) {} - llvm::ErrorOr> + llvm::ErrorOr> openFileForRead(const Twine &Path) override { auto File = getUnderlyingFS().openFileForRead(Path); if (!File || !*File) @@ -105,7 +106,7 @@ struct PreambleStatCache { Cache.Update(Path, File->get()->status()); return File; } - llvm::ErrorOr status(const Twine &Path) override { + llvm::ErrorOr status(const Twine &Path) override { auto S = getUnderlyingFS().status(Path); Cache.Update(Path, S); return S; @@ -114,14 +115,14 @@ struct PreambleStatCache { return new VFS(std::move(FS), *this); } - IntrusiveRefCntPtr - Consumer(IntrusiveRefCntPtr FS) { - struct VFS : vfs::ProxyFileSystem { + IntrusiveRefCntPtr + Consumer(IntrusiveRefCntPtr FS) { + struct VFS : llvm::vfs::ProxyFileSystem { const PreambleStatCache &Cache; - VFS(IntrusiveRefCntPtr FS, + VFS(IntrusiveRefCntPtr FS, const PreambleStatCache &Cache) : ProxyFileSystem(std::move(FS)), Cache(Cache) {} - llvm::ErrorOr status(const Twine &Path) override { + llvm::ErrorOr status(const Twine &Path) override { auto I = Cache.Cache.find(Path.str()); if (I != Cache.Cache.end()) return I->getValue(); @@ -271,7 +272,7 @@ class StoreDiags : public DiagnosticConsumer { std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, - IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, + IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, const PreambleData *preamble, const WorkingFiles::Snapshot &snapshot, std::vector> &Bufs) { std::string main = ResolveIfRelative( @@ -319,7 +320,7 @@ bool Parse(CompilerInstance &Clang) { } void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, - IntrusiveRefCntPtr FS, + IntrusiveRefCntPtr FS, const std::string &main, std::unique_ptr stat_cache) { std::shared_ptr OldP = session.GetPreamble(); @@ -364,7 +365,8 @@ void *CompletionPreloadMain(void *manager_) { WorkingFiles::Snapshot snapshot = session->wfiles->AsSnapshot({StripFileType(session->file.filename)}); auto stat_cache = std::make_unique(); - IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); + IntrusiveRefCntPtr FS = + stat_cache->Producer(session->FS); if (std::unique_ptr CI = BuildCompilerInvocation(args, FS)) BuildPreamble(*session, *CI, FS, request.path, std::move(stat_cache)); @@ -402,7 +404,7 @@ void *CompletionMain(void *manager_) { std::shared_ptr session = manager->TryGetSession(path, false); std::shared_ptr preamble = session->GetPreamble(); - IntrusiveRefCntPtr FS = + IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = BuildCompilerInvocation(session->file.args, FS); @@ -482,7 +484,7 @@ void *DiagnosticMain(void *manager_) { std::shared_ptr session = manager->TryGetSession(path, false); std::shared_ptr preamble = session->GetPreamble(); - IntrusiveRefCntPtr FS = + IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = BuildCompilerInvocation(session->file.args, FS); diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 7d610d2d5..822ea6caa 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -63,8 +63,8 @@ struct CompletionSession bool inferred = false; // TODO share - llvm::IntrusiveRefCntPtr FS = - clang::vfs::getRealFileSystem(); + llvm::IntrusiveRefCntPtr FS = + llvm::vfs::getRealFileSystem(); std::shared_ptr PCH; CompletionSession(const Project::Entry &file, WorkingFiles *wfiles, diff --git a/src/clang_tu.cc b/src/clang_tu.cc index d1dd3f021..5392ee524 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -83,7 +83,7 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, std::unique_ptr BuildCompilerInvocation(std::vector args, - IntrusiveRefCntPtr VFS) { + IntrusiveRefCntPtr VFS) { std::string save = "-resource-dir=" + g_config->clang.resourceDir; args.push_back(save.c_str()); IntrusiveRefCntPtr Diags( diff --git a/src/clang_tu.hh b/src/clang_tu.hh index 96325466f..30d0f464f 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -22,6 +22,13 @@ limitations under the License. #include #include +#if LLVM_VERSION_MAJOR < 8 +// D52783 Lift VFS from clang to llvm +namespace llvm { +namespace vfs = clang::vfs; +} +#endif + std::string PathFromFileEntry(const clang::FileEntry &file); Range FromCharSourceRange(const clang::SourceManager &SM, @@ -39,6 +46,6 @@ Range FromTokenRange(const clang::SourceManager &SM, std::unique_ptr BuildCompilerInvocation(std::vector args, - llvm::IntrusiveRefCntPtr VFS); + llvm::IntrusiveRefCntPtr VFS); const char *ClangBuiltinTypeName(int); diff --git a/src/indexer.cc b/src/indexer.cc index 341376306..1b9aaac12 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1225,7 +1225,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, const std::vector> &remapped, bool &ok) { ok = true; auto PCH = std::make_shared(); - llvm::IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); + llvm::IntrusiveRefCntPtr FS = llvm::vfs::getRealFileSystem(); std::shared_ptr CI = BuildCompilerInvocation(args, FS); // e.g. .s if (!CI) From f5816e3be301041865ebfc5611758b514ba1795d Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Thu, 11 Oct 2018 04:32:59 +0800 Subject: [PATCH 259/378] Fix hierarchical document symbol 1. Fixed a bug on building document symbol tree: As sym2ds was updated in place, nested funcs/types may be moved into children of another lsDocumentSymbol before itself got processed. 2. Namespaces only have declarations, in the old implementation it wasn't included in the result, making the result less hierarchical. This commit fixes this by including the declarations of a symbol if no definitions found. --- src/indexer.h | 3 +- src/messages/textDocument_documentSymbol.cc | 142 +++++++++++--------- 2 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/indexer.h b/src/indexer.h index 8f26822cc..3783996fc 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -211,7 +211,8 @@ struct VarDef : NameMixin { return spell && (parent_kind == lsSymbolKind::Function || parent_kind == lsSymbolKind::Method || - parent_kind == lsSymbolKind::StaticMethod) && + parent_kind == lsSymbolKind::StaticMethod || + parent_kind == lsSymbolKind::Constructor) && storage == clang::SC_None; } diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index ec9fed12e..cc2535eb1 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -76,11 +76,16 @@ struct Out_HierarchicalDocumentSymbol }; MAKE_REFLECT_STRUCT(Out_HierarchicalDocumentSymbol, jsonrpc, id, result); -bool IgnoreType(const QueryType::Def *def) { +template +bool Ignore(const Def *def) { + return false; +} +template <> +bool Ignore(const QueryType::Def *def) { return !def || def->kind == lsSymbolKind::TypeParameter; } - -bool IgnoreVar(const QueryVar::Def *def) { +template<> +bool Ignore(const QueryVar::Def *def) { return !def || def->is_local(); } @@ -112,92 +117,101 @@ struct Handler_TextDocumentDocumentSymbol std::sort(out.result.begin(), out.result.end()); pipeline::WriteStdout(kMethodType, out); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { - std::unordered_map< - SymbolIdx, std::pair>> - sym2ds; + std::unordered_map> sym2ds; + std::vector> funcs; + std::vector> types; for (auto [sym, refcnt] : symbol2refcnt) { if (refcnt <= 0) continue; auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); if (!r.second) continue; - auto &kv = r.first->second; - kv.second = std::make_unique(); - lsDocumentSymbol &ds = *kv.second; + auto &ds = r.first->second; + ds = std::make_unique(); + const void *def_ptr = nullptr; WithEntity(db, sym, [&](const auto &entity) { auto *def = entity.AnyDef(); if (!def) return; - ds.name = def->Name(false); - ds.detail = def->Name(true); + ds->name = def->Name(false); + ds->detail = def->Name(true); + + // Try to find a definition with spell first. + const void *candidate_def_ptr = nullptr; for (auto &def : entity.def) - if (def.file_id == file_id) { + if (def.file_id == file_id && !Ignore(&def)) { + ds->kind = def.kind; + if (def.kind == lsSymbolKind::Namespace) + candidate_def_ptr = &def; + if (!def.spell) - break; - ds.kind = def.kind; + continue; if (auto ls_range = GetLsRange(wfile, def.spell->extent)) - ds.range = *ls_range; + ds->range = *ls_range; else - break; + continue; if (auto ls_range = GetLsRange(wfile, def.spell->range)) - ds.selectionRange = *ls_range; + ds->selectionRange = *ls_range; else - break; - kv.first = static_cast(&def); + continue; + def_ptr = &def; + break; } + + // Try to find a declaration. + if (!def_ptr && candidate_def_ptr) + for (auto &decl : entity.declarations) + if (decl.file_id == file_id) { + if (auto ls_range = GetLsRange(wfile, decl.extent)) + ds->range = *ls_range; + else + continue; + if (auto ls_range = GetLsRange(wfile, decl.range)) + ds->selectionRange = *ls_range; + else + continue; + def_ptr = candidate_def_ptr; + break; + } }); - if (kv.first && ((sym.kind == SymbolKind::Type && - IgnoreType((const QueryType::Def *)kv.first)) || - (sym.kind == SymbolKind::Var && - IgnoreVar((const QueryVar::Def *)kv.first)))) - kv.first = nullptr; - if (!kv.first) { - kv.second.reset(); + if (!def_ptr) { + ds.reset(); continue; } + if (sym.kind == SymbolKind::Func) + funcs.emplace_back((const QueryFunc::Def *)def_ptr, ds.get()); + else if (sym.kind == SymbolKind::Type) + types.emplace_back((const QueryType::Def *)def_ptr, ds.get()); } - for (auto &[sym, def_ds] : sym2ds) { - if (!def_ds.second) - continue; - lsDocumentSymbol &ds = *def_ds.second; - switch (sym.kind) { - case SymbolKind::Func: { - auto &def = *static_cast(def_ds.first); - for (Usr usr1 : def.vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second.second) - ds.children.push_back(std::move(it->second.second)); - } - break; + + for (auto &[def, ds] : funcs) + for (Usr usr1 : def->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); } - case SymbolKind::Type: { - auto &def = *static_cast(def_ds.first); - for (Usr usr1 : def.funcs) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); - if (it != sym2ds.end() && it->second.second) - ds.children.push_back(std::move(it->second.second)); - } - for (Usr usr1 : def.types) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); - if (it != sym2ds.end() && it->second.second) - ds.children.push_back(std::move(it->second.second)); - } - for (auto [usr1, _] : def.vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second.second) - ds.children.push_back(std::move(it->second.second)); - } - break; + for (auto &[def, ds] : types) { + for (Usr usr1 : def->funcs) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (Usr usr1 : def->types) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); } - default: - break; + for (auto [usr1, _] : def->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); } } Out_HierarchicalDocumentSymbol out; out.id = request->id; - for (auto &[sym, def_ds] : sym2ds) - if (def_ds.second) - out.result.push_back(std::move(def_ds.second)); + for (auto &[_, ds] : sym2ds) + if (ds) + out.result.push_back(std::move(ds)); pipeline::WriteStdout(kMethodType, out); } else { Out_TextDocumentDocumentSymbol out; @@ -207,9 +221,9 @@ struct Handler_TextDocumentDocumentSymbol if (std::optional info = GetSymbolInfo(db, sym, false)) { if ((sym.kind == SymbolKind::Type && - IgnoreType(db->GetType(sym).AnyDef())) || + Ignore(db->GetType(sym).AnyDef())) || (sym.kind == SymbolKind::Var && - IgnoreVar(db->GetVar(sym).AnyDef()))) + Ignore(db->GetVar(sym).AnyDef()))) continue; if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { info->location = *loc; From 61b361320b53f4603ad3d89fe6c890e70097ee9a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 12 Oct 2018 16:25:29 -0700 Subject: [PATCH 260/378] -DSYSTEM_CLANG=off: 6.0.1 -> 7.0.0 --- clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 | 1 - clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 | 1 + .../clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 | 1 - ...clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 | 1 - ...llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 - ...clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 | 1 + .../clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 | 1 + ...llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 + ...llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 + cmake/DownloadAndExtractClang.cmake | 8 +++----- 10 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 create mode 100644 clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 create mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 diff --git a/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 b/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 deleted file mode 100644 index 5d218384a..000000000 --- a/clang_archive_hashes/LLVM-6.0.1-win64.exe.SHA256 +++ /dev/null @@ -1 +0,0 @@ -780276221635aa08120187ffc2c72ff7873dee37f5609455ee7bba6fcdd91d79 \ No newline at end of file diff --git a/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 b/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 new file mode 100644 index 000000000..54bea9e6c --- /dev/null +++ b/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 @@ -0,0 +1 @@ +74b197a3959b0408adf0824be01db8dddfa2f9a967f4085af3fad900ed5fdbf6 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 deleted file mode 100644 index 1d30f273d..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268 diff --git a/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 deleted file mode 100644 index 9a7df3246..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -6d1f67c9e7c3481106d5c9bfcb8a75e3876eb17a446a14c59c13cafd000c21d2 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 deleted file mode 100644 index 671a75e2f..000000000 --- a/clang_archive_hashes/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -7ea204ecd78c39154d72dfc0d4a79f7cce1b2264da2551bb2eef10e266d54d91 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 new file mode 100644 index 000000000..b8a56bfa7 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 @@ -0,0 +1 @@ +95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 new file mode 100644 index 000000000..86f733c96 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 @@ -0,0 +1 @@ +b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 new file mode 100644 index 000000000..bc8306913 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 @@ -0,0 +1 @@ +5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 new file mode 100644 index 000000000..1475a0a85 --- /dev/null +++ b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 @@ -0,0 +1 @@ +69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2 \ No newline at end of file diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake index d7c11755a..9365b1881 100644 --- a/cmake/DownloadAndExtractClang.cmake +++ b/cmake/DownloadAndExtractClang.cmake @@ -6,7 +6,7 @@ # Downloads 7-Zip to extract Clang if it isn't available in the PATH function(download_and_extract_clang CLANG_DOWNLOAD_LOCATION) -set(CLANG_VERSION 6.0.1) +set(CLANG_VERSION 7.0.0) set(CLANG_ARCHIVE_EXT .tar.xz) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) @@ -17,8 +17,6 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - # No Darwin binaries were released for LLVM 6.0.1 - set(CLANG_VERSION 6.0.0) set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) @@ -28,7 +26,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10) + set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd11) endif() @@ -93,7 +91,7 @@ if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) include(DownloadAndExtract7zip) download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION}) find_program(7ZIP_EXECUTABLE - NAMES 7z + NAMES 7z NO_DEFAULT_PATH PATHS ${DOWNLOADED_7ZIP_DIR} ) From 4743124370ad4d6988a55c276b83de1705ae5a7f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 12 Oct 2018 16:36:07 -0700 Subject: [PATCH 261/378] Adapt trunk change and write comments to PCH --- src/clang_complete.cc | 5 +---- src/project.cc | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 317d09086..f689d48a4 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -332,10 +332,7 @@ void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, return; CI.getDiagnosticOpts().IgnoreWarnings = false; CI.getFrontendOpts().SkipFunctionBodies = true; - CI.getLangOpts()->CommentOpts.ParseAllComments = true; -#if LLVM_VERSION_MAJOR >= 7 - CI.getPreprocessorOpts().WriteCommentListToPCH = false; -#endif + CI.getLangOpts()->CommentOpts.ParseAllComments = g_config->index.comments > 1; StoreDiags DC(main); IntrusiveRefCntPtr DE = diff --git a/src/project.cc b/src/project.cc index 7968b5bbe..b1419da82 100644 --- a/src/project.cc +++ b/src/project.cc @@ -136,7 +136,7 @@ struct ProjectProcessor { const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1) return; - const driver::ArgStringList &CCArgs = Jobs.begin()->getArguments(); + const auto &CCArgs = Jobs.begin()->getArguments(); auto CI = std::make_unique(); CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(), From 79352b451c59c159dc0f0a0e1bcb39cdc85cc382 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 13 Oct 2018 23:22:29 -0700 Subject: [PATCH 262/378] Misc changes to project * Better LanguageId detection with clangDriver (e.g. .cu -> types::TY_CUDA) * fallback when there is no .ccls or compile_commands.json Also Hide clangTooling options from --help --- CMakeLists.txt | 1 - src/indexer.h | 2 +- src/language.cc | 45 ------------------------------ src/language.h | 29 ------------------- src/lsp.h | 6 ++++ src/main.cc | 22 +++++++++------ src/messages/textDocument_did.cc | 3 +- src/messages/textDocument_hover.cc | 12 ++++++++ src/project.cc | 45 +++++++++++++++++++----------- src/project.h | 3 ++ 10 files changed, 67 insertions(+), 101 deletions(-) delete mode 100644 src/language.cc delete mode 100644 src/language.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 29a3008fe..7af3eb16a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,7 +188,6 @@ target_sources(ccls PRIVATE src/include_complete.cc src/indexer.cc src/method.cc - src/language.cc src/log.cc src/lsp.cc src/match.cc diff --git a/src/indexer.h b/src/indexer.h index 3783996fc..a23262d40 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -15,7 +15,6 @@ limitations under the License. #pragma once -#include "language.h" #include "lsp.h" #include "lsp_diagnostic.h" #include "maybe.h" @@ -35,6 +34,7 @@ limitations under the License. #include using Usr = uint64_t; +enum class LanguageId; struct SymbolIdx { Usr usr; diff --git a/src/language.cc b/src/language.cc deleted file mode 100644 index ecb3b489f..000000000 --- a/src/language.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "language.h" - -#include "utils.h" - -LanguageId SourceFileLanguage(std::string_view path) { - if (EndsWith(path, ".c")) - return LanguageId::C; - else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc")) - return LanguageId::Cpp; - else if (EndsWith(path, ".mm")) - return LanguageId::ObjCpp; - else if (EndsWith(path, ".m")) - return LanguageId::ObjC; - return LanguageId::Unknown; -} - -const char *LanguageIdentifier(LanguageId lang) { - switch (lang) { - case LanguageId::C: - return "c"; - case LanguageId::Cpp: - return "cpp"; - case LanguageId::ObjC: - return "objective-c"; - case LanguageId::ObjCpp: - return "objective-cpp"; - default: - return ""; - } -} diff --git a/src/language.h b/src/language.h deleted file mode 100644 index d53b79203..000000000 --- a/src/language.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "serializer.h" - -#include - -// Used to identify the language at a file level. The ordering is important, as -// a file previously identified as `C`, will be changed to `Cpp` if it -// encounters a c++ declaration. -enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 }; -MAKE_REFLECT_TYPE_PROXY(LanguageId); - -LanguageId SourceFileLanguage(std::string_view path); -const char *LanguageIdentifier(LanguageId lang); diff --git a/src/lsp.h b/src/lsp.h index aa8029dd9..3b569758c 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -346,3 +346,9 @@ struct Out_LocationList : public lsOutMessage { std::vector result; }; MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result); + +// Used to identify the language at a file level. The ordering is important, as +// a file previously identified as `C`, will be changed to `Cpp` if it +// encounters a c++ declaration. +enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 }; +MAKE_REFLECT_TYPE_PROXY(LanguageId); diff --git a/src/main.cc b/src/main.cc index 66e76f866..7bd175529 100644 --- a/src/main.cc +++ b/src/main.cc @@ -42,17 +42,19 @@ using namespace llvm::cl; std::string g_init_options; namespace { -opt opt_help("h", desc("Alias for -help")); -opt opt_verbose("v", desc("verbosity"), init(0)); +OptionCategory C("ccls options"); + +opt opt_help("h", desc("Alias for -help"), cat(C)); +opt opt_verbose("v", desc("verbosity"), init(0), cat(C)); opt opt_test_index("test-index", ValueOptional, init("!"), - desc("run index tests")); + desc("run index tests"), cat(C)); -opt opt_init("init", desc("extra initialization options")); -opt opt_log_file("log-file", desc("log"), value_desc("filename")); +opt opt_init("init", desc("extra initialization options in JSON"), + cat(C)); +opt opt_log_file("log-file", desc("log"), value_desc("filename"), + cat(C)); opt opt_log_file_append("log-file-append", desc("log"), - value_desc("filename")); - -list opt_extra(Positional, ZeroOrMore, desc("extra")); + value_desc("filename"), cat(C)); void CloseLog() { fclose(ccls::log::file); } @@ -62,6 +64,10 @@ int main(int argc, char **argv) { TraceMe(); sys::PrintStackTraceOnErrorSignal(argv[0]); + for (auto &I : TopLevelSubCommand->OptionsMap) + if (I.second->Category != &C) + I.second->setHiddenFlag(ReallyHidden); + ParseCommandLineOptions(argc, argv, "C/C++/Objective-C language server\n\n" "See more on https://github.com/MaskRay/ccls/wiki"); diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 30bf2acdb..66b170560 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -127,7 +127,8 @@ struct Handler_TextDocumentDidOpen // Submit new index request if it is not a header file or there is no // pending index request. - if (SourceFileLanguage(path) != LanguageId::Unknown || + std::pair lang = lookupExtension(path); + if ((lang.first != LanguageId::Unknown && !lang.second) || !pipeline::pending_index_requests) pipeline::Index(path, args, IndexMode::Normal); diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index a368f846a..d7580fe7a 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -21,6 +21,18 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/hover"; +const char *LanguageIdentifier(LanguageId lang) { + switch (lang) { + // clang-format off + case LanguageId::C: return "c"; + case LanguageId::Cpp: return "cpp"; + case LanguageId::ObjC: return "objective-c"; + case LanguageId::ObjCpp: return "objective-cpp"; + default: return ""; + // clang-format on + } +} + // Returns the hover or detailed name for `sym`, if any. std::pair, std::optional> GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { diff --git a/src/project.cc b/src/project.cc index b1419da82..1bcededa2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -16,7 +16,6 @@ limitations under the License. #include "project.h" #include "filesystem.hh" -#include "language.h" #include "log.hh" #include "match.h" #include "pipeline.hh" @@ -27,6 +26,7 @@ limitations under the License. #include #include +#include #include #include #include @@ -47,6 +47,25 @@ using namespace ccls; using namespace clang; using namespace llvm; +std::pair lookupExtension(std::string_view filename) { + using namespace clang::driver; + auto I = types::lookupTypeForExtension( + sys::path::extension({filename.data(), filename.size()}).substr(1)); + bool header = I == types::TY_CHeader || I == types::TY_CXXHeader || + I == types::TY_ObjCXXHeader; + bool objc = types::isObjC(I); + LanguageId ret; + if (types::isCXX(I)) + ret = objc ? LanguageId::ObjCpp : LanguageId::Cpp; + else if (objc) + ret = LanguageId::ObjC; + else if (I == types::TY_C || I == types::TY_CHeader) + ret = LanguageId::C; + else + ret = LanguageId::Unknown; + return {ret, header}; +} + namespace { enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; @@ -76,7 +95,7 @@ struct ProjectProcessor { // Expand %c %cpp %clang std::vector args; args.reserve(entry.args.size() + g_config->clang.extraArgs.size() + 1); - const LanguageId lang = SourceFileLanguage(entry.filename); + const LanguageId lang = lookupExtension(entry.filename).first; for (const char *arg : entry.args) { if (strncmp(arg, "%c ", 3) == 0) { if (lang == LanguageId::C) @@ -98,7 +117,7 @@ struct ProjectProcessor { size_t hash = std::hash{}(entry.directory); for (auto &arg : args) { if (arg[0] != '-' && EndsWith(arg, base_name)) { - const LanguageId lang = SourceFileLanguage(arg); + LanguageId lang = lookupExtension(arg).first; if (lang != LanguageId::Unknown) { hash_combine(hash, size_t(lang)); continue; @@ -182,12 +201,6 @@ ReadCompilerArgumentsFromFile(const std::string &path) { std::vector LoadFromDirectoryListing(ProjectConfig *config) { std::vector result; config->mode = ProjectMode::DotCcls; - SmallString<256> Path; - sys::path::append(Path, config->root, ".ccls"); - LOG_IF_S(WARNING, !sys::fs::exists(Path) && g_config->clang.extraArgs.empty()) - << "ccls has no clang arguments. Use either " - "compile_commands.json or .ccls, See ccls README for " - "more information."; std::unordered_map> folder_args; std::vector files; @@ -196,7 +209,8 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { GetFilesInFolder(root, true /*recursive*/, true /*add_folder_to_path*/, [&folder_args, &files](const std::string &path) { - if (SourceFileLanguage(path) != LanguageId::Unknown) { + std::pair lang = lookupExtension(path); + if (lang.first != LanguageId::Unknown && !lang.second) { files.push_back(path); } else if (sys::path::filename(path) == ".ccls") { std::vector args = ReadCompilerArgumentsFromFile(path); @@ -247,14 +261,13 @@ std::vector LoadEntriesFromDirectory(ProjectConfig *project, const std::string &opt_compdb_dir) { // If there is a .ccls file always load using directory listing. - SmallString<256> Path; - sys::path::append(Path, project->root, ".ccls"); - if (sys::fs::exists(Path)) + SmallString<256> Path, CclsPath; + sys::path::append(CclsPath, project->root, ".ccls"); + if (sys::fs::exists(CclsPath)) return LoadFromDirectoryListing(project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. std::string comp_db_dir; - Path.clear(); if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. @@ -296,8 +309,8 @@ LoadEntriesFromDirectory(ProjectConfig *project, #endif } if (!CDB) { - LOG_S(WARNING) << "failed to load " << Path.c_str() << " " << err_msg; - return {}; + LOG_S(WARNING) << "no .ccls or compile_commands.json . Consider adding one"; + return LoadFromDirectoryListing(project); } LOG_S(INFO) << "loaded " << Path.c_str(); diff --git a/src/project.h b/src/project.h index 1cc5eff88..90547ba31 100644 --- a/src/project.h +++ b/src/project.h @@ -16,6 +16,7 @@ limitations under the License. #pragma once #include "config.h" +#include "lsp.h" #include "method.h" #include @@ -26,6 +27,8 @@ limitations under the License. struct WorkingFiles; +std::pair lookupExtension(std::string_view filename); + struct Project { struct Entry { std::string root; From fc1db06538a3d5ca31926e98e08231502cc1c9b6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 9 Jan 2019 15:19:17 +0800 Subject: [PATCH 263/378] Add pipeline::{Notify,Reply,ReplyError} and simplify message handling Delete method.{cc,h} Rename $ccls/setSkippedRanges to $ccls/publishSkippedRanges Rename $ccls/publishSemanticHighlighting to $ccls/publishSemanticHighlight; stableId -> id --- CMakeLists.txt | 3 - src/clang_complete.hh | 2 +- src/hierarchy.hh | 15 +- src/indexer.h | 1 - src/lsp.cc | 66 ++++---- src/lsp.h | 150 +++++++++++------- src/lsp_diagnostic.h | 115 -------------- src/match.cc | 11 +- src/message_handler.cc | 96 +++++------ src/message_handler.h | 31 +--- src/messages/ccls_call.cc | 97 +++++------ src/messages/ccls_info.cc | 76 ++++----- src/messages/ccls_inheritance.cc | 133 ++++++++-------- src/messages/ccls_member.cc | 113 ++++++------- src/messages/ccls_navigate.cc | 9 +- src/messages/ccls_reload.cc | 15 +- src/messages/ccls_vars.cc | 21 ++- src/messages/exit.cc | 2 +- src/messages/initialize.cc | 24 +-- src/messages/shutdown.cc | 13 +- src/messages/textDocument_codeAction.cc | 16 +- src/messages/textDocument_codeLens.cc | 31 +--- src/messages/textDocument_completion.cc | 46 +++--- src/messages/textDocument_definition.cc | 21 ++- src/messages/textDocument_did.cc | 20 +-- .../textDocument_documentHighlight.cc | 25 +-- src/messages/textDocument_documentSymbol.cc | 46 ++---- src/messages/textDocument_formatting.cc | 28 ++-- src/messages/textDocument_hover.cc | 39 ++--- src/messages/textDocument_implementation.cc | 64 -------- src/messages/textDocument_references.cc | 19 ++- src/messages/textDocument_rename.cc | 26 +-- src/messages/textDocument_signatureHelp.cc | 14 +- src/messages/textDocument_typeDefinition.cc | 13 +- src/messages/workspace_did.cc | 59 ++++++- .../workspace_didChangeWatchedFiles.cc | 79 --------- src/messages/workspace_symbol.cc | 23 +-- src/method.cc | 55 ------- src/method.h | 59 ------- src/pipeline.cc | 134 +++++++++------- src/pipeline.hh | 20 ++- src/project.h | 1 - src/serializer.cc | 8 +- src/serializer.h | 23 +-- src/serializers/binary.h | 2 + src/serializers/json.h | 2 + src/working_files.cc | 3 +- src/working_files.h | 2 +- 48 files changed, 715 insertions(+), 1156 deletions(-) delete mode 100644 src/lsp_diagnostic.h delete mode 100644 src/messages/textDocument_implementation.cc delete mode 100644 src/messages/workspace_didChangeWatchedFiles.cc delete mode 100644 src/method.cc delete mode 100644 src/method.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7af3eb16a..7c526d72c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,7 +187,6 @@ target_sources(ccls PRIVATE src/main.cc src/include_complete.cc src/indexer.cc - src/method.cc src/log.cc src/lsp.cc src/match.cc @@ -225,12 +224,10 @@ target_sources(ccls PRIVATE src/messages/textDocument_documentHighlight.cc src/messages/textDocument_documentSymbol.cc src/messages/textDocument_hover.cc - src/messages/textDocument_implementation.cc src/messages/textDocument_references.cc src/messages/textDocument_rename.cc src/messages/textDocument_signatureHelp.cc src/messages/textDocument_typeDefinition.cc src/messages/workspace_did.cc - src/messages/workspace_didChangeWatchedFiles.cc src/messages/workspace_symbol.cc ) diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 822ea6caa..e18d1ad8f 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -17,8 +17,8 @@ limitations under the License. #include "clang_tu.hh" #include "lru_cache.h" +#include "lsp.h" #include "lsp_completion.h" -#include "lsp_diagnostic.h" #include "project.h" #include "threaded_queue.h" #include "working_files.h" diff --git a/src/hierarchy.hh b/src/hierarchy.hh index c79cbd0d8..8d997ef1a 100644 --- a/src/hierarchy.hh +++ b/src/hierarchy.hh @@ -21,19 +21,22 @@ limitations under the License. #include template -void FlattenHierarchy(const Node &root, Out_LocationList &out) { +std::vector FlattenHierarchy(const std::optional &root) { + if (!root) + return {}; + std::vector ret; std::queue q; - for (auto &entry : root.children) + for (auto &entry : root->children) q.push(&entry); while (q.size()) { auto *entry = q.front(); q.pop(); if (entry->location.uri.raw_uri.size()) - out.result.push_back({entry->location}); + ret.push_back({entry->location}); for (auto &entry1 : entry->children) q.push(&entry1); } - std::sort(out.result.begin(), out.result.end()); - out.result.erase(std::unique(out.result.begin(), out.result.end()), - out.result.end()); + std::sort(ret.begin(), ret.end()); + ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); + return ret; } diff --git a/src/indexer.h b/src/indexer.h index a23262d40..510ce3046 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -16,7 +16,6 @@ limitations under the License. #pragma once #include "lsp.h" -#include "lsp_diagnostic.h" #include "maybe.h" #include "position.h" #include "serializer.h" diff --git a/src/lsp.cc b/src/lsp.cc index 6fac3d6c0..cce5b00b3 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -18,10 +18,45 @@ limitations under the License. #include "log.hh" #include "serializers/json.h" -#include +#include #include +MethodType kMethodType_Exit = "exit"; + +void Reflect(Reader &visitor, lsRequestId &value) { + if (visitor.IsInt64()) { + value.type = lsRequestId::kInt; + value.value = int(visitor.GetInt64()); + } else if (visitor.IsInt()) { + value.type = lsRequestId::kInt; + value.value = visitor.GetInt(); + } else if (visitor.IsString()) { + value.type = lsRequestId::kString; + value.value = atoll(visitor.GetString()); + } else { + value.type = lsRequestId::kNone; + value.value = -1; + } +} + +void Reflect(Writer &visitor, lsRequestId &value) { + switch (value.type) { + case lsRequestId::kNone: + visitor.Null(); + break; + case lsRequestId::kInt: + visitor.Int(value.value); + break; + case lsRequestId::kString: + auto s = std::to_string(value.value); + visitor.String(s.c_str(), s.length()); + break; + } +} + +InMessage::~InMessage() {} + MessageRegistry *MessageRegistry::instance_ = nullptr; lsTextDocumentIdentifier @@ -145,29 +180,6 @@ MessageRegistry *MessageRegistry::instance() { return instance_; } -lsBaseOutMessage::~lsBaseOutMessage() = default; - -void lsBaseOutMessage::Write(std::ostream &out) { - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer{&writer}; - ReflectWriter(json_writer); - - out << "Content-Length: " << output.GetSize() << "\r\n\r\n" - << output.GetString(); - out.flush(); -} - -void lsResponseError::Write(Writer &visitor) { - auto &value = *this; - int code2 = static_cast(this->code); - - visitor.StartObject(); - REFLECT_MEMBER2("code", code2); - REFLECT_MEMBER(message); - visitor.EndObject(); -} - lsDocumentUri lsDocumentUri::FromPath(const std::string &path) { lsDocumentUri result; result.SetPath(path); @@ -272,9 +284,3 @@ void Reflect(Writer &visitor, lsMarkedString &value) { Reflect(visitor, value.value); } } - -std::string Out_ShowLogMessage::method() { - if (display_type == DisplayType::Log) - return "window/logMessage"; - return "window/showMessage"; -} diff --git a/src/lsp.h b/src/lsp.h index 3b569758c..9b0b800e1 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -16,13 +16,42 @@ limitations under the License. #pragma once #include "config.h" -#include "method.h" #include "serializer.h" #include "utils.h" #include #include +using MethodType = const char *; +extern MethodType kMethodType_Exit; + +struct lsRequestId { + // The client can send the request id as an int or a string. We should output + // the same format we received. + enum Type { kNone, kInt, kString }; + Type type = kNone; + + int value = -1; + + bool Valid() const { return type != kNone; } +}; +void Reflect(Reader &visitor, lsRequestId &value); +void Reflect(Writer &visitor, lsRequestId &value); + +struct InMessage { + virtual ~InMessage(); + + virtual MethodType GetMethodType() const = 0; + virtual lsRequestId GetRequestId() const { return {}; } +}; + +struct NotificationMessage : InMessage {}; + +struct RequestMessage : public InMessage { + lsRequestId id; + lsRequestId GetRequestId() const override { return id; } +}; + #define REGISTER_IN_MESSAGE(type) \ static MessageRegistryRegister type##message_handler_instance_; @@ -53,45 +82,38 @@ template struct MessageRegistryRegister { } }; -struct lsBaseOutMessage { - virtual ~lsBaseOutMessage(); - virtual void ReflectWriter(Writer &) = 0; - - // Send the message to the language client by writing it to stdout. - void Write(std::ostream &out); -}; - -template struct lsOutMessage : lsBaseOutMessage { - // All derived types need to reflect on the |jsonrpc| member. - std::string jsonrpc = "2.0"; - - void ReflectWriter(Writer &writer) override { - Reflect(writer, static_cast(*this)); - } +enum class lsErrorCodes { + // Defined by JSON RPC + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + serverErrorStart = -32099, + serverErrorEnd = -32000, + ServerNotInitialized = -32002, + UnknownErrorCode = -32001, + + // Defined by the protocol. + RequestCancelled = -32800, }; +MAKE_REFLECT_TYPE_PROXY(lsErrorCodes); struct lsResponseError { - enum class lsErrorCodes : int { - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, - serverErrorStart = -32099, - serverErrorEnd = -32000, - ServerNotInitialized = -32002, - UnknownErrorCode = -32001, - RequestCancelled = -32800, - }; - + // A number indicating the error type that occurred. lsErrorCodes code; - // Short description. + + // A string providing a short description of the error. std::string message; - void Write(Writer &visitor); + // A Primitive or Structured value that contains additional + // information about the error. Can be omitted. + // std::optional data; }; +MAKE_REFLECT_STRUCT(lsResponseError, code, message); -constexpr std::string_view ccls_xref("ccls.xref"); +constexpr char ccls_xref[] = "ccls.xref"; +constexpr char window_showMessage[] = "window/showMessage"; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -317,35 +339,55 @@ MAKE_REFLECT_STRUCT(lsWorkspaceFolder, uri, name); enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; MAKE_REFLECT_TYPE_PROXY(lsMessageType) -struct Out_ShowLogMessageParams { - lsMessageType type = lsMessageType::Error; - std::string message; +enum class lsDiagnosticSeverity { + // Reports an error. + Error = 1, + // Reports a warning. + Warning = 2, + // Reports an information. + Information = 3, + // Reports a hint. + Hint = 4 }; -MAKE_REFLECT_STRUCT(Out_ShowLogMessageParams, type, message); +MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity); + +struct lsDiagnostic { + // The range at which the message applies. + lsRange range; -struct Out_ShowLogMessage : public lsOutMessage { - enum class DisplayType { Show, Log }; - DisplayType display_type = DisplayType::Show; + // The diagnostic's severity. Can be omitted. If omitted it is up to the + // client to interpret diagnostics as error, warning, info or hint. + std::optional severity; + + // The diagnostic's code. Can be omitted. + int code = 0; + + // A human-readable string describing the source of this + // diagnostic, e.g. 'typescript' or 'super lint'. + std::string source = "ccls"; + + // The diagnostic's message. + std::string message; - std::string method(); - Out_ShowLogMessageParams params; + // Non-serialized set of fixits. + std::vector fixits_; }; +MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message); -template -void Reflect(TVisitor &visitor, Out_ShowLogMessage &value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - std::string method = value.method(); - REFLECT_MEMBER2("method", method); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +struct lsPublishDiagnosticsParams { + // The URI for which diagnostic information is reported. + lsDocumentUri uri; -struct Out_LocationList : public lsOutMessage { - lsRequestId id; - std::vector result; + // An array of diagnostic information items. + std::vector diagnostics; +}; +MAKE_REFLECT_STRUCT(lsPublishDiagnosticsParams, uri, diagnostics); + +struct lsShowMessageParams { + lsMessageType type = lsMessageType::Error; + std::string message; }; -MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message); // Used to identify the language at a file level. The ordering is important, as // a file previously identified as `C`, will be changed to `Cpp` if it diff --git a/src/lsp_diagnostic.h b/src/lsp_diagnostic.h deleted file mode 100644 index 7e9c7a8e5..000000000 --- a/src/lsp_diagnostic.h +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "lsp.h" - -enum class lsDiagnosticSeverity { - // Reports an error. - Error = 1, - // Reports a warning. - Warning = 2, - // Reports an information. - Information = 3, - // Reports a hint. - Hint = 4 -}; -MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity); - -struct lsDiagnostic { - // The range at which the message applies. - lsRange range; - - // The diagnostic's severity. Can be omitted. If omitted it is up to the - // client to interpret diagnostics as error, warning, info or hint. - std::optional severity; - - // The diagnostic's code. Can be omitted. - int code = 0; - - // A human-readable string describing the source of this - // diagnostic, e.g. 'typescript' or 'super lint'. - std::string source = "ccls"; - - // The diagnostic's message. - std::string message; - - // Non-serialized set of fixits. - std::vector fixits_; -}; -MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message); - -enum class lsErrorCodes { - // Defined by JSON RPC - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, - serverErrorStart = -32099, - serverErrorEnd = -32000, - ServerNotInitialized = -32002, - UnknownErrorCode = -32001, - - // Defined by the protocol. - RequestCancelled = -32800, -}; -MAKE_REFLECT_TYPE_PROXY(lsErrorCodes); -struct Out_Error : public lsOutMessage { - struct lsResponseError { - // A number indicating the error type that occurred. - lsErrorCodes code; - - // A string providing a short description of the error. - std::string message; - - // A Primitive or Structured value that contains additional - // information about the error. Can be omitted. - // std::optional data; - }; - - lsRequestId id; - - // The error object in case a request fails. - lsResponseError error; -}; -MAKE_REFLECT_STRUCT(Out_Error::lsResponseError, code, message); -MAKE_REFLECT_STRUCT(Out_Error, jsonrpc, id, error); - -// Diagnostics -struct Out_TextDocumentPublishDiagnostics - : public lsOutMessage { - struct Params { - // The URI for which diagnostic information is reported. - lsDocumentUri uri; - - // An array of diagnostic information items. - std::vector diagnostics; - }; - - Params params; -}; -template -void Reflect(TVisitor &visitor, Out_TextDocumentPublishDiagnostics &value) { - std::string method = "textDocument/publishDiagnostics"; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER2("method", method); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} -MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, uri, - diagnostics); diff --git a/src/match.cc b/src/match.cc index b86dfd902..1ecdff284 100644 --- a/src/match.cc +++ b/src/match.cc @@ -30,12 +30,11 @@ std::optional Matcher::Create(const std::string &search) { ); return m; } catch (const std::exception &e) { - Out_ShowLogMessage out; - out.display_type = Out_ShowLogMessage::DisplayType::Show; - out.params.type = lsMessageType::Error; - out.params.message = - "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); - pipeline::WriteStdout(kMethodType_Unknown, out); + lsShowMessageParams params; + params.type = lsMessageType::Error; + params.message = + "failed to parse EMCAScript regex " + search + " : " + e.what(); + pipeline::Notify(window_showMessage, params); return std::nullopt; } } diff --git a/src/message_handler.cc b/src/message_handler.cc index ddffa25c7..088099c27 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -30,23 +30,36 @@ MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); namespace { -struct Out_CclsSetSkippedRanges - : public lsOutMessage { - struct Params { - lsDocumentUri uri; - std::vector skippedRanges; - }; - std::string method = "$ccls/setSkippedRanges"; - Params params; +struct CclsSemanticHighlightSymbol { + int id = 0; + lsSymbolKind parentKind; + lsSymbolKind kind; + uint8_t storage; + std::vector> ranges; + + // `lsRanges` is used to compute `ranges`. + std::vector lsRanges; +}; + +struct CclsSemanticHighlightParams { + lsDocumentUri uri; + std::vector symbols; }; -MAKE_REFLECT_STRUCT(Out_CclsSetSkippedRanges::Params, uri, skippedRanges); -MAKE_REFLECT_STRUCT(Out_CclsSetSkippedRanges, jsonrpc, method, params); +MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, + ranges, lsRanges); +MAKE_REFLECT_STRUCT(CclsSemanticHighlightParams, uri, symbols); + +struct CclsSetSkippedRangesParams { + lsDocumentUri uri; + std::vector skippedRanges; +}; +MAKE_REFLECT_STRUCT(CclsSetSkippedRangesParams, uri, skippedRanges); struct ScanLineEvent { lsPosition pos; lsPosition end_pos; // Second key when there is a tie for insertion events. int id; - Out_CclsPublishSemanticHighlighting::Symbol *symbol; + CclsSemanticHighlightSymbol *symbol; bool operator<(const ScanLineEvent &other) const { // See the comments below when insertion/deletion events are inserted. if (!(pos == other.pos)) @@ -68,7 +81,6 @@ MessageHandler::MessageHandler() { message_handlers->push_back(this); } -// static std::vector *MessageHandler::message_handlers = nullptr; bool FindFileOrFail(DB *db, Project *project, std::optional id, @@ -98,46 +110,40 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, } if (id) { - Out_Error out; - out.id = *id; + lsResponseError err; if (has_entry) { - out.error.code = lsErrorCodes::ServerNotInitialized; - out.error.message = absolute_path + " is being indexed"; + err.code = lsErrorCodes::ServerNotInitialized; + err.message = absolute_path + " is being indexed"; } else { - out.error.code = lsErrorCodes::InternalError; - out.error.message = "Unable to find file " + absolute_path; + err.code = lsErrorCodes::InternalError; + err.message = "unable to find " + absolute_path; } - LOG_S(INFO) << out.error.message; - pipeline::WriteStdout(kMethodType_Unknown, out); + pipeline::ReplyError(*id, err); } return false; } -void EmitSkippedRanges(WorkingFile *working_file, - const std::vector &skipped_ranges) { - Out_CclsSetSkippedRanges out; - out.params.uri = lsDocumentUri::FromPath(working_file->filename); - for (Range skipped : skipped_ranges) { - std::optional ls_skipped = GetLsRange(working_file, skipped); - if (ls_skipped) - out.params.skippedRanges.push_back(*ls_skipped); - } - pipeline::WriteStdout(kMethodType_CclsPublishSkippedRanges, out); +void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) { + CclsSetSkippedRangesParams params; + params.uri = lsDocumentUri::FromPath(wfile->filename); + for (Range skipped : file.def->skipped_ranges) + if (auto ls_skipped = GetLsRange(wfile, skipped)) + params.skippedRanges.push_back(*ls_skipped); + pipeline::Notify("$ccls/publishSkippedRanges", params); } -void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { +void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { static GroupMatch match(g_config->highlight.whitelist, g_config->highlight.blacklist); - assert(file->def); + assert(file.def); if (wfile->buffer_content.size() > g_config->highlight.largeFileSize || - !match.IsMatch(file->def->path)) + !match.IsMatch(file.def->path)) return; // Group symbols together. - std::unordered_map - grouped_symbols; - for (auto [sym, refcnt] : file->symbol2refcnt) { + std::unordered_map grouped_symbols; + for (auto [sym, refcnt] : file.symbol2refcnt) { if (refcnt <= 0) continue; std::string_view detailed_name; lsSymbolKind parent_kind = lsSymbolKind::Unknown; @@ -217,8 +223,8 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { if (it != grouped_symbols.end()) { it->second.lsRanges.push_back(*loc); } else { - Out_CclsPublishSemanticHighlighting::Symbol symbol; - symbol.stableId = idx; + CclsSemanticHighlightSymbol symbol; + symbol.id = idx; symbol.parentKind = parent_kind; symbol.kind = kind; symbol.storage = storage; @@ -232,7 +238,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { std::vector events; int id = 0; for (auto &entry : grouped_symbols) { - Out_CclsPublishSemanticHighlighting::Symbol &symbol = entry.second; + CclsSemanticHighlightSymbol &symbol = entry.second; for (auto &loc : symbol.lsRanges) { // For ranges sharing the same start point, the one with leftmost end // point comes first. @@ -267,13 +273,11 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { deleted[~events[i].id] = 1; } - Out_CclsPublishSemanticHighlighting out; - out.params.uri = lsDocumentUri::FromPath(wfile->filename); + CclsSemanticHighlightParams params; + params.uri = lsDocumentUri::FromPath(wfile->filename); // Transform lsRange into pair (offset pairs) if (!g_config->highlight.lsRanges) { - std::vector< - std::pair> - scratch; + std::vector> scratch; for (auto &entry : grouped_symbols) { for (auto &range : entry.second.lsRanges) scratch.emplace_back(range, &entry.second); @@ -315,6 +319,6 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) { for (auto &entry : grouped_symbols) if (entry.second.ranges.size() || entry.second.lsRanges.size()) - out.params.symbols.push_back(std::move(entry.second)); - pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); + params.symbols.push_back(std::move(entry.second)); + pipeline::Notify("$ccls/publishSemanticHighlight", params); } diff --git a/src/message_handler.h b/src/message_handler.h index 33bbb6f3e..bac5d3ea3 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -16,7 +16,6 @@ limitations under the License. #pragma once #include "lsp.h" -#include "method.h" #include "query.h" #include @@ -35,30 +34,6 @@ struct DB; struct WorkingFile; struct WorkingFiles; -struct Out_CclsPublishSemanticHighlighting - : public lsOutMessage { - struct Symbol { - int stableId = 0; - lsSymbolKind parentKind; - lsSymbolKind kind; - uint8_t storage; - std::vector> ranges; - - // `lsRanges` is used to compute `ranges`. - std::vector lsRanges; - }; - struct Params { - lsDocumentUri uri; - std::vector symbols; - }; - std::string method = "$ccls/publishSemanticHighlighting"; - Params params; -}; -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId, - parentKind, kind, storage, ranges, lsRanges); -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols); -MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, - params); // Usage: // @@ -103,8 +78,6 @@ bool FindFileOrFail(DB *db, Project *project, std::optional id, const std::string &absolute_path, QueryFile **out_query_file, int *out_file_id = nullptr); -void EmitSkippedRanges(WorkingFile *working_file, - const std::vector &skipped_ranges); +void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file); -void EmitSemanticHighlighting(DB *db, WorkingFile *working_file, - QueryFile *file); +void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 46477987d..fa049a771 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -38,7 +38,7 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct In_CclsCall : public RequestInMessage { +struct In_cclsCall : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -62,34 +62,29 @@ struct In_CclsCall : public RequestInMessage { }; Params params; }; -MAKE_REFLECT_STRUCT(In_CclsCall::Params, textDocument, position, id, - callee, callType, qualified, levels, hierarchy); -MAKE_REFLECT_STRUCT(In_CclsCall, id, params); -REGISTER_IN_MESSAGE(In_CclsCall); - -struct Out_CclsCall : public lsOutMessage { - struct Entry { - Usr usr; - std::string id; - std::string_view name; - lsLocation location; - CallType callType = CallType::Direct; - int numChildren; - // Empty if the |levels| limit is reached. - std::vector children; - bool operator==(const Entry &o) const { return location == o.location; } - bool operator<(const Entry &o) const { return location < o.location; } - }; - - lsRequestId id; - std::optional result; +MAKE_REFLECT_STRUCT(In_cclsCall::Params, textDocument, position, id, callee, + callType, qualified, levels, hierarchy); +MAKE_REFLECT_STRUCT(In_cclsCall, id, params); +REGISTER_IN_MESSAGE(In_cclsCall); + +struct Out_cclsCall { + Usr usr; + std::string id; + std::string_view name; + lsLocation location; + CallType callType = CallType::Direct; + int numChildren; + // Empty if the |levels| limit is reached. + std::vector children; + bool operator==(const Out_cclsCall &o) const { + return location == o.location; + } + bool operator<(const Out_cclsCall &o) const { return location < o.location; } }; -MAKE_REFLECT_STRUCT(Out_CclsCall::Entry, id, name, location, callType, - numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCall, jsonrpc, id, - result); +MAKE_REFLECT_STRUCT(Out_cclsCall, id, name, location, callType, numChildren, + children); -bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, +bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, CallType call_type, bool qualified, int levels) { const QueryFunc &func = m->db->Func(entry->usr); const QueryFunc::Def *def = func.AnyDef(); @@ -99,7 +94,7 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, auto handle = [&](SymbolRef sym, int file_id, CallType call_type1) { entry->numChildren++; if (levels > 0) { - Out_CclsCall::Entry entry1; + Out_cclsCall entry1; entry1.id = std::to_string(sym.usr); entry1.usr = sym.usr; if (auto loc = GetLsLocation(m->db, m->working_files, @@ -179,17 +174,17 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee, return true; } -struct Handler_CclsCall : BaseMessageHandler { +struct Handler_cclsCall : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional - BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified, - int levels) { + std::optional BuildInitial(Usr root_usr, bool callee, + CallType call_type, bool qualified, + int levels) { const auto *def = db->Func(root_usr).AnyDef(); if (!def) return {}; - Out_CclsCall::Entry entry; + Out_cclsCall entry; entry.id = std::to_string(root_usr); entry.usr = root_usr; entry.callType = CallType::Direct; @@ -202,25 +197,22 @@ struct Handler_CclsCall : BaseMessageHandler { return entry; } - void Run(In_CclsCall *request) override { + void Run(In_cclsCall *request) override { auto ¶ms = request->params; - Out_CclsCall out; - out.id = request->id; - + std::optional result; if (params.id.size()) { try { params.usr = std::stoull(params.id); } catch (...) { return; } - Out_CclsCall::Entry entry; - entry.id = std::to_string(params.usr); - entry.usr = params.usr; - entry.callType = CallType::Direct; + result.emplace(); + result->id = std::to_string(params.usr); + result->usr = params.usr; + result->callType = CallType::Direct; if (db->HasFunc(params.usr)) - Expand(this, &entry, params.callee, params.callType, params.qualified, + Expand(this, &*result, params.callee, params.callType, params.qualified, params.levels); - out.result = std::move(entry); } else { QueryFile *file; if (!FindFileOrFail(db, project, request->id, @@ -231,24 +223,21 @@ struct Handler_CclsCall : BaseMessageHandler { for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, params.position)) { if (sym.kind == SymbolKind::Func) { - out.result = BuildInitial(sym.usr, params.callee, params.callType, - params.qualified, params.levels); + result = BuildInitial(sym.usr, params.callee, params.callType, + params.qualified, params.levels); break; } } } - if (params.hierarchy) { - pipeline::WriteStdout(kMethodType, out); - return; + if (params.hierarchy) + pipeline::Reply(request->id, result); + else { + auto out = FlattenHierarchy(result); + pipeline::Reply(request->id, out); } - Out_LocationList out1; - out1.id = request->id; - if (out.result) - FlattenHierarchy(*out.result, out1); - pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsCall); +REGISTER_MESSAGE_HANDLER(Handler_cclsCall); } // namespace diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 8aa99f8ba..4e4766bb4 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -25,51 +25,46 @@ MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, namespace { MethodType cclsInfo = "$ccls/info", fileInfo = "$ccls/fileInfo"; -struct In_cclsInfo : public RequestInMessage { +struct In_cclsInfo : public RequestMessage { MethodType GetMethodType() const override { return cclsInfo; } }; MAKE_REFLECT_STRUCT(In_cclsInfo, id); REGISTER_IN_MESSAGE(In_cclsInfo); -struct Out_cclsInfo : public lsOutMessage { - lsRequestId id; - struct Result { - struct DB { - int files, funcs, types, vars; - } db; - struct Pipeline { - int pendingIndexRequests; - } pipeline; - struct Project { - int entries; - } project; - } result; +struct Out_cclsInfo { + struct DB { + int files, funcs, types, vars; + } db; + struct Pipeline { + int pendingIndexRequests; + } pipeline; + struct Project { + int entries; + } project; }; -MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::DB, files, funcs, types, vars); -MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::Pipeline, pendingIndexRequests); -MAKE_REFLECT_STRUCT(Out_cclsInfo::Result::Project, entries); -MAKE_REFLECT_STRUCT(Out_cclsInfo::Result, db, pipeline, project); -MAKE_REFLECT_STRUCT(Out_cclsInfo, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars); +MAKE_REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests); +MAKE_REFLECT_STRUCT(Out_cclsInfo::Project, entries); +MAKE_REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project); struct Handler_cclsInfo : BaseMessageHandler { MethodType GetMethodType() const override { return cclsInfo; } void Run(In_cclsInfo *request) override { - Out_cclsInfo out; - out.id = request->id; - out.result.db.files = db->files.size(); - out.result.db.funcs = db->funcs.size(); - out.result.db.types = db->types.size(); - out.result.db.vars = db->vars.size(); - out.result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; - out.result.project.entries = 0; + Out_cclsInfo result; + result.db.files = db->files.size(); + result.db.funcs = db->funcs.size(); + result.db.types = db->types.size(); + result.db.vars = db->vars.size(); + result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; + result.project.entries = 0; for (auto &[_, folder] : project->root2folder) - out.result.project.entries += folder.entries.size(); - pipeline::WriteStdout(cclsInfo, out); + result.project.entries += folder.entries.size(); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_cclsInfo); -struct In_cclsFileInfo : public RequestInMessage { +struct In_cclsFileInfo : public RequestMessage { MethodType GetMethodType() const override { return fileInfo; } struct Params { lsTextDocumentIdentifier textDocument; @@ -79,12 +74,6 @@ MAKE_REFLECT_STRUCT(In_cclsFileInfo::Params, textDocument); MAKE_REFLECT_STRUCT(In_cclsFileInfo, id, params); REGISTER_IN_MESSAGE(In_cclsFileInfo); -struct Out_cclsFileInfo : public lsOutMessage { - lsRequestId id; - QueryFile::Def result; -}; -MAKE_REFLECT_STRUCT(Out_cclsFileInfo, jsonrpc, id, result); - struct Handler_cclsFileInfo : BaseMessageHandler { MethodType GetMethodType() const override { return fileInfo; } void Run(In_cclsFileInfo *request) override { @@ -93,15 +82,14 @@ struct Handler_cclsFileInfo : BaseMessageHandler { request->params.textDocument.uri.GetPath(), &file)) return; - Out_cclsFileInfo out; - out.id = request->id; + QueryFile::Def result; // Expose some fields of |QueryFile::Def|. - out.result.path = file->def->path; - out.result.args = file->def->args; - out.result.language = file->def->language; - out.result.includes = file->def->includes; - out.result.skipped_ranges = file->def->skipped_ranges; - pipeline::WriteStdout(fileInfo, out); + result.path = file->def->path; + result.args = file->def->args; + result.language = file->def->language; + result.includes = file->def->includes; + result.skipped_ranges = file->def->skipped_ranges; + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_cclsFileInfo); diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 0ed235850..cfd2203b2 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -22,9 +22,10 @@ using namespace ccls; #include namespace { -MethodType kMethodType = "$ccls/inheritance"; +MethodType kMethodType = "$ccls/inheritance", + implementation = "textDocument/implementation"; -struct In_CclsInheritance : public RequestInMessage { +struct In_cclsInheritance : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // If id+kind are specified, expand a node; otherwise textDocument+position @@ -44,39 +45,32 @@ struct In_CclsInheritance : public RequestInMessage { } params; }; -MAKE_REFLECT_STRUCT(In_CclsInheritance::Params, textDocument, position, - id, kind, derived, qualified, levels, hierarchy); -MAKE_REFLECT_STRUCT(In_CclsInheritance, id, params); -REGISTER_IN_MESSAGE(In_CclsInheritance); - -struct Out_CclsInheritance - : public lsOutMessage { - struct Entry { - Usr usr; - std::string id; - SymbolKind kind; - std::string_view name; - lsLocation location; - // For unexpanded nodes, this is an upper bound because some entities may be - // undefined. If it is 0, there are no members. - int numChildren; - // Empty if the |levels| limit is reached. - std::vector children; - }; - lsRequestId id; - std::optional result; +MAKE_REFLECT_STRUCT(In_cclsInheritance::Params, textDocument, position, id, + kind, derived, qualified, levels, hierarchy); +MAKE_REFLECT_STRUCT(In_cclsInheritance, id, params); +REGISTER_IN_MESSAGE(In_cclsInheritance); + +struct Out_cclsInheritance { + Usr usr; + std::string id; + SymbolKind kind; + std::string_view name; + lsLocation location; + // For unexpanded nodes, this is an upper bound because some entities may be + // undefined. If it is 0, there are no members. + int numChildren; + // Empty if the |levels| limit is reached. + std::vector children; }; -MAKE_REFLECT_STRUCT(Out_CclsInheritance::Entry, id, kind, name, - location, numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritance, jsonrpc, - id, result); +MAKE_REFLECT_STRUCT(Out_cclsInheritance, id, kind, name, location, numChildren, + children); -bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry, - bool derived, bool qualified, int levels); +bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived, + bool qualified, int levels); template -bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry, - bool derived, bool qualified, int levels, Q &entity) { +bool ExpandHelper(MessageHandler *m, Out_cclsInheritance *entry, bool derived, + bool qualified, int levels, Q &entity) { const auto *def = entity.AnyDef(); if (def) { entry->name = def->Name(qualified); @@ -97,7 +91,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry, for (auto usr : entity.derived) { if (!seen.insert(usr).second) continue; - Out_CclsInheritance::Entry entry1; + Out_cclsInheritance entry1; entry1.id = std::to_string(usr); entry1.usr = usr; entry1.kind = entry->kind; @@ -112,7 +106,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry, for (auto usr : def->bases) { if (!seen.insert(usr).second) continue; - Out_CclsInheritance::Entry entry1; + Out_cclsInheritance entry1; entry1.id = std::to_string(usr); entry1.usr = usr; entry1.kind = entry->kind; @@ -126,8 +120,8 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry, return true; } -bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry, - bool derived, bool qualified, int levels) { +bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived, + bool qualified, int levels) { if (entry->kind == SymbolKind::Func) return ExpandHelper(m, entry, derived, qualified, levels, m->db->Func(entry->usr)); @@ -136,13 +130,12 @@ bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry, m->db->Type(entry->usr)); } -struct Handler_CclsInheritance - : BaseMessageHandler { +struct Handler_cclsInheritance : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional - BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) { - Out_CclsInheritance::Entry entry; + std::optional BuildInitial(SymbolRef sym, bool derived, + bool qualified, int levels) { + Out_cclsInheritance entry; entry.id = std::to_string(sym.usr); entry.usr = sym.usr; entry.kind = sym.kind; @@ -150,25 +143,24 @@ struct Handler_CclsInheritance return entry; } - void Run(In_CclsInheritance *request) override { + void Run(In_cclsInheritance *request) override { auto ¶ms = request->params; - Out_CclsInheritance out; - out.id = request->id; - + std::optional result; if (params.id.size()) { try { params.usr = std::stoull(params.id); } catch (...) { return; } - Out_CclsInheritance::Entry entry; - entry.id = std::to_string(params.usr); - entry.usr = params.usr; - entry.kind = params.kind; - if (((entry.kind == SymbolKind::Func && db->HasFunc(entry.usr)) || - (entry.kind == SymbolKind::Type && db->HasType(entry.usr))) && - Expand(this, &entry, params.derived, params.qualified, params.levels)) - out.result = std::move(entry); + result.emplace(); + result->id = std::to_string(params.usr); + result->usr = params.usr; + result->kind = params.kind; + if (!(((params.kind == SymbolKind::Func && db->HasFunc(params.usr)) || + (params.kind == SymbolKind::Type && db->HasType(params.usr))) && + Expand(this, &*result, params.derived, params.qualified, + params.levels))) + result.reset(); } else { QueryFile *file; if (!FindFileOrFail(db, project, request->id, @@ -178,23 +170,38 @@ struct Handler_CclsInheritance for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { - out.result = BuildInitial(sym, params.derived, params.qualified, - params.levels); + result = BuildInitial(sym, params.derived, params.qualified, + params.levels); break; } } - if (params.hierarchy) { - pipeline::WriteStdout(kMethodType, out); - return; + if (params.hierarchy) + pipeline::Reply(request->id, result); + else { + auto out = FlattenHierarchy(result); + pipeline::Reply(request->id, out); } - Out_LocationList out1; - out1.id = request->id; - if (out.result) - FlattenHierarchy(*out.result, out1); - pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsInheritance); +REGISTER_MESSAGE_HANDLER(Handler_cclsInheritance); +struct In_textDocumentImplementation : public RequestMessage { + MethodType GetMethodType() const override { return implementation; } + lsTextDocumentPositionParams params; +}; +MAKE_REFLECT_STRUCT(In_textDocumentImplementation, id, params); +REGISTER_IN_MESSAGE(In_textDocumentImplementation); + +struct Handler_textDocumentImplementation + : BaseMessageHandler { + MethodType GetMethodType() const override { return implementation; } + void Run(In_textDocumentImplementation *request) override { + In_cclsInheritance request1; + request1.params.textDocument = request->params.textDocument; + request1.params.position = request->params.position; + Handler_cclsInheritance().Run(&request1); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_textDocumentImplementation); } // namespace diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index b5ae481b6..a6d35d012 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -30,7 +30,7 @@ using namespace clang; namespace { MethodType kMethodType = "$ccls/member"; -struct In_CclsMember : public RequestInMessage { +struct In_cclsMember : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { @@ -52,42 +52,36 @@ struct In_CclsMember : public RequestInMessage { } params; }; -MAKE_REFLECT_STRUCT(In_CclsMember::Params, textDocument, position, id, +MAKE_REFLECT_STRUCT(In_cclsMember::Params, textDocument, position, id, qualified, levels, kind, hierarchy); -MAKE_REFLECT_STRUCT(In_CclsMember, id, params); -REGISTER_IN_MESSAGE(In_CclsMember); +MAKE_REFLECT_STRUCT(In_cclsMember, id, params); +REGISTER_IN_MESSAGE(In_cclsMember); -struct Out_CclsMember : public lsOutMessage { - struct Entry { - Usr usr; - std::string id; - std::string_view name; - std::string fieldName; - lsLocation location; - // For unexpanded nodes, this is an upper bound because some entities may be - // undefined. If it is 0, there are no members. - int numChildren = 0; - // Empty if the |levels| limit is reached. - std::vector children; - }; - lsRequestId id; - std::optional result; +struct Out_cclsMember { + Usr usr; + std::string id; + std::string_view name; + std::string fieldName; + lsLocation location; + // For unexpanded nodes, this is an upper bound because some entities may be + // undefined. If it is 0, there are no members. + int numChildren = 0; + // Empty if the |levels| limit is reached. + std::vector children; }; -MAKE_REFLECT_STRUCT(Out_CclsMember::Entry, id, name, fieldName, - location, numChildren, children); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMember, jsonrpc, id, - result); +MAKE_REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren, + children); -bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, - bool qualified, int levels, SymbolKind memberKind); +bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, + int levels, SymbolKind memberKind); // Add a field to |entry| which is a Func/Type. -void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, - const QueryVar &var, int64_t offset, bool qualified, int levels) { +void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var, + int64_t offset, bool qualified, int levels) { const QueryVar::Def *def1 = var.AnyDef(); if (!def1) return; - Out_CclsMember::Entry entry1; + Out_cclsMember entry1; // With multiple inheritance, the offset is incorrect. if (offset >= 0) { if (offset / 8 < 10) @@ -124,8 +118,8 @@ void DoField(MessageHandler *m, Out_CclsMember::Entry *entry, } // Expand a type node by adding members recursively to it. -bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, - bool qualified, int levels, SymbolKind memberKind) { +bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, + int levels, SymbolKind memberKind) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(int(entry->usr)); return true; @@ -157,7 +151,7 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, } if (def->alias_of) { const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); - Out_CclsMember::Entry entry1; + Out_cclsMember entry1; entry1.id = std::to_string(def->alias_of); entry1.usr = def->alias_of; if (def1 && def1->spell) { @@ -187,7 +181,7 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, if (seen1.insert(usr).second) { QueryFunc &func1 = m->db->Func(usr); if (const QueryFunc::Def *def1 = func1.AnyDef()) { - Out_CclsMember::Entry entry1; + Out_cclsMember entry1; entry1.fieldName = def1->Name(false); if (def1->spell) { if (auto loc = @@ -208,7 +202,7 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, if (seen1.insert(usr).second) { QueryType &type1 = m->db->Type(usr); if (const QueryType::Def *def1 = type1.AnyDef()) { - Out_CclsMember::Entry entry1; + Out_cclsMember entry1; entry1.fieldName = def1->Name(false); if (def1->spell) { if (auto loc = @@ -239,12 +233,12 @@ bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry, return true; } -struct Handler_CclsMember - : BaseMessageHandler { +struct Handler_cclsMember : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - std::optional - BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels, SymbolKind memberKind) { + std::optional BuildInitial(SymbolKind kind, Usr root_usr, + bool qualified, int levels, + SymbolKind memberKind) { switch (kind) { default: return {}; @@ -253,7 +247,7 @@ struct Handler_CclsMember if (!def) return {}; - Out_CclsMember::Entry entry; + Out_cclsMember entry; // Not type, |id| is invalid. entry.name = def->Name(qualified); if (def->spell) { @@ -273,7 +267,7 @@ struct Handler_CclsMember if (!def) return {}; - Out_CclsMember::Entry entry; + Out_cclsMember entry; entry.id = std::to_string(root_usr); entry.usr = root_usr; if (def->spell) { @@ -287,24 +281,22 @@ struct Handler_CclsMember } } - void Run(In_CclsMember *request) override { + void Run(In_cclsMember *request) override { auto ¶ms = request->params; - Out_CclsMember out; - out.id = request->id; - + std::optional result; if (params.id.size()) { try { params.usr = std::stoull(params.id); } catch (...) { return; } - Out_CclsMember::Entry entry; - entry.id = std::to_string(params.usr); - entry.usr = params.usr; + result.emplace(); + result->id = std::to_string(params.usr); + result->usr = params.usr; // entry.name is empty as it is known by the client. - if (db->HasType(entry.usr) && - Expand(this, &entry, params.qualified, params.levels, params.kind)) - out.result = std::move(entry); + if (!(db->HasType(params.usr) && Expand(this, &*result, params.qualified, + params.levels, params.kind))) + result.reset(); } else { QueryFile *file; if (!FindFileOrFail(db, project, request->id, @@ -316,14 +308,14 @@ struct Handler_CclsMember switch (sym.kind) { case SymbolKind::Func: case SymbolKind::Type: - out.result = BuildInitial(sym.kind, sym.usr, params.qualified, - params.levels, params.kind); + result = BuildInitial(sym.kind, sym.usr, params.qualified, + params.levels, params.kind); break; case SymbolKind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); if (def && def->type) - out.result = BuildInitial(SymbolKind::Type, def->type, - params.qualified, params.levels, params.kind); + result = BuildInitial(SymbolKind::Type, def->type, params.qualified, + params.levels, params.kind); break; } default: @@ -333,17 +325,14 @@ struct Handler_CclsMember } } - if (params.hierarchy) { - pipeline::WriteStdout(kMethodType, out); - return; + if (params.hierarchy) + pipeline::Reply(request->id, result); + else { + auto out = FlattenHierarchy(result); + pipeline::Reply(request->id, out); } - Out_LocationList out1; - out1.id = request->id; - if (out.result) - FlattenHierarchy(*out.result, out1); - pipeline::WriteStdout(kMethodType, out1); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsMember); +REGISTER_MESSAGE_HANDLER(Handler_cclsMember); } // namespace diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 7a0fbb2d5..9e73ec063 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -21,7 +21,7 @@ using namespace ccls; namespace { MethodType kMethodType = "$ccls/navigate"; -struct In_CclsNavigate : public RequestInMessage { +struct In_CclsNavigate : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; @@ -100,15 +100,14 @@ struct Handler_CclsNavigate : BaseMessageHandler { res = sym.range; break; } - Out_LocationList out; - out.id = request->id; + std::vector result; if (res) if (auto ls_range = GetLsRange(wfile, *res)) { - lsLocation &ls_loc = out.result.emplace_back(); + lsLocation &ls_loc = result.emplace_back(); ls_loc.uri = params.textDocument.uri; ls_loc.range = *ls_range; } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsNavigate); diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 67b97c258..8a451effb 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -28,7 +28,7 @@ using namespace ccls; namespace { MethodType kMethodType = "$ccls/reload"; -struct In_CclsReload : public NotificationInMessage { +struct In_cclsReload : public NotificationMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { bool dependencies = true; @@ -36,14 +36,13 @@ struct In_CclsReload : public NotificationInMessage { std::vector blacklist; } params; }; -MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist, - blacklist); -MAKE_REFLECT_STRUCT(In_CclsReload, params); -REGISTER_IN_MESSAGE(In_CclsReload); +MAKE_REFLECT_STRUCT(In_cclsReload::Params, dependencies, whitelist, blacklist); +MAKE_REFLECT_STRUCT(In_cclsReload, params); +REGISTER_IN_MESSAGE(In_cclsReload); -struct Handler_CclsReload : BaseMessageHandler { +struct Handler_cclsReload : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsReload *request) override { + void Run(In_cclsReload *request) override { const auto ¶ms = request->params; // Send index requests for every file. if (params.whitelist.empty() && params.blacklist.empty()) { @@ -91,5 +90,5 @@ struct Handler_CclsReload : BaseMessageHandler { } } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsReload); +REGISTER_MESSAGE_HANDLER(Handler_cclsReload); } // namespace diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index ac2f24c78..ca37d8718 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -21,7 +21,7 @@ using namespace ccls; namespace { MethodType kMethodType = "$ccls/vars"; -struct In_CclsVars : public RequestInMessage { +struct In_cclsVars : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params : lsTextDocumentPositionParams { // 1: field @@ -30,14 +30,14 @@ struct In_CclsVars : public RequestInMessage { unsigned kind = ~0u; } params; }; -MAKE_REFLECT_STRUCT(In_CclsVars::Params, textDocument, position, kind); -MAKE_REFLECT_STRUCT(In_CclsVars, id, params); -REGISTER_IN_MESSAGE(In_CclsVars); +MAKE_REFLECT_STRUCT(In_cclsVars::Params, textDocument, position, kind); +MAKE_REFLECT_STRUCT(In_cclsVars, id, params); +REGISTER_IN_MESSAGE(In_cclsVars); -struct Handler_CclsVars : BaseMessageHandler { +struct Handler_cclsVars : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsVars *request) override { + void Run(In_cclsVars *request) override { auto ¶ms = request->params; QueryFile *file; if (!FindFileOrFail(db, project, request->id, @@ -47,8 +47,7 @@ struct Handler_CclsVars : BaseMessageHandler { WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList out; - out.id = request->id; + std::vector result; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, params.position)) { Usr usr = sym.usr; @@ -63,14 +62,14 @@ struct Handler_CclsVars : BaseMessageHandler { [[fallthrough]]; } case SymbolKind::Type: - out.result = GetLsLocations( + result = GetLsLocations( db, working_files, GetVarDeclarations(db, db->Type(usr).instances, params.kind)); break; } } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; -REGISTER_MESSAGE_HANDLER(Handler_CclsVars); +REGISTER_MESSAGE_HANDLER(Handler_cclsVars); } // namespace diff --git a/src/messages/exit.cc b/src/messages/exit.cc index ce016d02a..fd8ccb9a4 100644 --- a/src/messages/exit.cc +++ b/src/messages/exit.cc @@ -16,7 +16,7 @@ limitations under the License. #include "message_handler.h" namespace { -struct In_Exit : public NotificationInMessage { +struct In_Exit : public NotificationMessage { MethodType GetMethodType() const override { return kMethodType_Exit; } }; MAKE_REFLECT_EMPTY_STRUCT(In_Exit); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index a7e6bd41f..810ffb852 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -400,7 +400,7 @@ struct lsInitializeError { }; MAKE_REFLECT_STRUCT(lsInitializeError, retry); -struct In_InitializeRequest : public RequestInMessage { +struct In_InitializeRequest : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsInitializeParams params; @@ -408,15 +408,10 @@ struct In_InitializeRequest : public RequestInMessage { MAKE_REFLECT_STRUCT(In_InitializeRequest, id, params); REGISTER_IN_MESSAGE(In_InitializeRequest); -struct Out_InitializeResponse : public lsOutMessage { - struct InitializeResult { - lsServerCapabilities capabilities; - }; - lsRequestId id; - InitializeResult result; +struct lsInitializeResult { + lsServerCapabilities capabilities; }; -MAKE_REFLECT_STRUCT(Out_InitializeResponse::InitializeResult, capabilities); -MAKE_REFLECT_STRUCT(Out_InitializeResponse, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(lsInitializeResult, capabilities); void *Indexer(void *arg_) { MessageHandler *h; @@ -486,13 +481,10 @@ struct Handler_Initialize : BaseMessageHandler { // Send initialization before starting indexers, so we don't send a // status update too early. - // TODO: query request->params.capabilities.textDocument and support - // only things the client supports. - - Out_InitializeResponse out; - out.id = request->id; - - pipeline::WriteStdout(kMethodType, out); + { + lsInitializeResult result; + pipeline::Reply(request->id, result); + } // Set project root. EnsureEndsInSlash(project_path); diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index 8f480f08d..9f9a0dba0 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -20,24 +20,17 @@ using namespace ccls; namespace { MethodType kMethodType = "shutdown"; -struct In_Shutdown : public RequestInMessage { +struct In_Shutdown : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } }; MAKE_REFLECT_STRUCT(In_Shutdown, id); REGISTER_IN_MESSAGE(In_Shutdown); -struct Out_Shutdown : public lsOutMessage { - lsRequestId id; - JsonNull result; -}; -MAKE_REFLECT_STRUCT(Out_Shutdown, jsonrpc, id, result); - struct Handler_Shutdown : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_Shutdown *request) override { - Out_Shutdown out; - out.id = request->id; - pipeline::WriteStdout(kMethodType, out); + JsonNull result; + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_Shutdown); diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc index ac5564b3d..b84d546ee 100644 --- a/src/messages/textDocument_codeAction.cc +++ b/src/messages/textDocument_codeAction.cc @@ -21,7 +21,7 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/codeAction"; -struct In_TextDocumentCodeAction : public RequestInMessage { +struct In_TextDocumentCodeAction : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } // Contains additional diagnostic information about the context in which @@ -54,13 +54,6 @@ struct lsCodeAction { }; MAKE_REFLECT_STRUCT(lsCodeAction, title, kind, edit); -struct Out_TextDocumentCodeAction - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result); - struct Handler_TextDocumentCodeAction : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -71,20 +64,19 @@ struct Handler_TextDocumentCodeAction working_files->GetFileByFilename(params.textDocument.uri.GetPath()); if (!wfile) return; - Out_TextDocumentCodeAction out; - out.id = request->id; + std::vector result; std::vector diagnostics; working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); for (lsDiagnostic &diag : diagnostics) if (diag.fixits_.size()) { - lsCodeAction &cmd = out.result.emplace_back(); + lsCodeAction &cmd = result.emplace_back(); cmd.title = "FixIt: " + diag.message; auto &edit = cmd.edit.documentChanges.emplace_back(); edit.textDocument.uri = params.textDocument.uri; edit.textDocument.version = wfile->version; edit.edits = diag.fixits_; } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index 2045250a0..dd2d41eb2 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -48,12 +48,6 @@ struct Cmd_xref { }; MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); -struct Out_xref : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_xref, jsonrpc, id, result); - template std::string ToString(T &v) { rapidjson::StringBuffer output; @@ -69,7 +63,7 @@ struct CommonCodeLensParams { WorkingFile *wfile; }; -struct In_TextDocumentCodeLens : public RequestInMessage { +struct In_TextDocumentCodeLens : public RequestMessage { MethodType GetMethodType() const override { return codeLens; } struct Params { lsTextDocumentIdentifier textDocument; @@ -79,20 +73,12 @@ MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens::Params, textDocument); MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens, id, params); REGISTER_IN_MESSAGE(In_TextDocumentCodeLens); -struct Out_TextDocumentCodeLens - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result); - struct Handler_TextDocumentCodeLens : BaseMessageHandler { MethodType GetMethodType() const override { return codeLens; } void Run(In_TextDocumentCodeLens *request) override { auto ¶ms = request->params; - Out_TextDocumentCodeLens out; - out.id = request->id; + std::vector result; std::string path = params.textDocument.uri.GetPath(); QueryFile *file; @@ -107,7 +93,7 @@ struct Handler_TextDocumentCodeLens std::optional range = GetLsRange(wfile, use.range); if (!range) return; - lsCodeLens &code_lens = out.result.emplace_back(); + lsCodeLens &code_lens = result.emplace_back(); code_lens.range = *range; code_lens.command = lsCommand(); code_lens.command->command = std::string(ccls_xref); @@ -178,12 +164,12 @@ struct Handler_TextDocumentCodeLens }; } - pipeline::WriteStdout(codeLens, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); -struct In_WorkspaceExecuteCommand : public RequestInMessage { +struct In_WorkspaceExecuteCommand : public RequestMessage { MethodType GetMethodType() const override { return executeCommand; } lsCommand params; }; @@ -203,12 +189,11 @@ struct Handler_WorkspaceExecuteCommand if (params.command == ccls_xref) { Cmd_xref cmd; Reflect(json_reader, cmd); - Out_xref out; - out.id = request->id; + std::vector result; auto Map = [&](auto &&uses) { for (auto &use : uses) if (auto loc = GetLsLocation(db, working_files, use)) - out.result.push_back(std::move(*loc)); + result.push_back(std::move(*loc)); }; switch (cmd.kind) { case SymbolKind::Func: { @@ -247,7 +232,7 @@ struct Handler_WorkspaceExecuteCommand default: break; } - pipeline::WriteStdout(executeCommand, out); + pipeline::Reply(request->id, result); } } }; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index ab57ff5eb..e5a625236 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -66,28 +66,21 @@ struct lsCompletionParams : lsTextDocumentPositionParams { }; MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); -struct In_TextDocumentComplete : public RequestInMessage { +struct In_TextDocumentComplete : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsCompletionParams params; }; MAKE_REFLECT_STRUCT(In_TextDocumentComplete, id, params); REGISTER_IN_MESSAGE(In_TextDocumentComplete); -struct lsTextDocumentCompleteResult { +struct lsCompletionList { // This list it not complete. Further typing should result in recomputing // this list. bool isIncomplete = false; // The completion items. std::vector items; }; -MAKE_REFLECT_STRUCT(lsTextDocumentCompleteResult, isIncomplete, items); - -struct Out_TextDocumentComplete - : public lsOutMessage { - lsRequestId id; - lsTextDocumentCompleteResult result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result); +MAKE_REFLECT_STRUCT(lsCompletionList, isIncomplete, items); void DecorateIncludePaths(const std::smatch &match, std::vector *items) { @@ -153,11 +146,11 @@ template char *tofixedbase64(T input, char *out) { // Pre-filters completion responses before sending to vscode. This results in a // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. -void FilterCandidates(Out_TextDocumentComplete *complete_response, +void FilterCandidates(lsCompletionList &result, const std::string &complete_text, lsPosition begin_pos, lsPosition end_pos, const std::string &buffer_line) { assert(begin_pos.line == end_pos.line); - auto &items = complete_response->result.items; + auto &items = result.items; // People usually does not want to insert snippets or parenthesis when // changing function or type names, e.g. "str.|()" or "std::|". @@ -173,7 +166,7 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response, int max_num = g_config->completion.maxNum; if (items.size() > max_num) { items.resize(max_num); - complete_response->result.isIncomplete = true; + result.isIncomplete = true; } for (auto &item : items) { @@ -497,13 +490,12 @@ struct Handler_TextDocumentCompletion static CompleteConsumerCache> cache; const auto ¶ms = request->params; - Out_TextDocumentComplete out; - out.id = request->id; + lsCompletionList result; std::string path = params.textDocument.uri.GetPath(); WorkingFile *file = working_files->GetFileByFilename(path); if (!file) { - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); return; } @@ -548,7 +540,7 @@ struct Handler_TextDocumentCompletion } if (did_fail_check) { - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); return; } } @@ -561,8 +553,7 @@ struct Handler_TextDocumentCompletion ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); if (preprocess.ok && preprocess.keyword.compare("include") == 0) { - Out_TextDocumentComplete out; - out.id = request->id; + lsCompletionList result; { std::unique_lock lock( include_complete->completion_items_mutex, std::defer_lock); @@ -571,14 +562,14 @@ struct Handler_TextDocumentCompletion std::string quote = preprocess.match[5]; for (auto &item : include_complete->completion_items) if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) - out.result.items.push_back(item); + result.items.push_back(item); } begin_pos.character = 0; end_pos.character = (int)buffer_line.size(); - FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos, + FilterCandidates(result, preprocess.pattern, begin_pos, end_pos, buffer_line); - DecorateIncludePaths(preprocess.match, &out.result.items); - pipeline::WriteStdout(kMethodType, out); + DecorateIncludePaths(preprocess.match, &result.items); + pipeline::Reply(request->id, result); } else { std::string path = params.textDocument.uri.GetPath(); CompletionManager::OnComplete callback = @@ -587,13 +578,12 @@ struct Handler_TextDocumentCompletion if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); - Out_TextDocumentComplete out; - out.id = id; - out.result.items = Consumer->ls_items; + lsCompletionList result; + result.items = Consumer->ls_items; - FilterCandidates(&out, completion_text, begin_pos, end_pos, + FilterCandidates(result, completion_text, begin_pos, end_pos, buffer_line); - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(id, result); if (!Consumer->from_cache) { cache.WithLock([&]() { cache.path = path; diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 2118a64fc..649a02062 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -26,7 +26,7 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/definition"; -struct In_TextDocumentDefinition : public RequestInMessage { +struct In_TextDocumentDefinition : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; @@ -66,9 +66,7 @@ struct Handler_TextDocumentDefinition params.textDocument.uri.GetPath(), &file, &file_id)) return; - Out_LocationList out; - out.id = request->id; - + std::vector result; Maybe on_def; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); lsPosition &ls_pos = params.position; @@ -104,19 +102,18 @@ struct Handler_TextDocumentDefinition uses.push_back(*on_def); } auto locs = GetLsLocations(db, working_files, uses); - out.result.insert(out.result.end(), locs.begin(), locs.end()); + result.insert(result.end(), locs.begin(), locs.end()); } - if (out.result.size()) { - std::sort(out.result.begin(), out.result.end()); - out.result.erase(std::unique(out.result.begin(), out.result.end()), - out.result.end()); + if (result.size()) { + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); } else { Maybe range; // Check #include for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { - out.result.push_back( + result.push_back( lsLocation{lsDocumentUri::FromPath(include.resolved_path)}); range = {{0, 0}, {0, 0}}; break; @@ -177,12 +174,12 @@ struct Handler_TextDocumentDefinition Maybe dr = GetDefinitionSpell(db, best_sym); assert(dr); if (auto loc = GetLsLocation(db, working_files, *dr)) - out.result.push_back(*loc); + result.push_back(*loc); } } } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 66b170560..1c284d002 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -27,7 +27,7 @@ MethodType didClose = "textDocument/didClose"; MethodType didOpen = "textDocument/didOpen"; MethodType didSave = "textDocument/didSave"; -struct In_TextDocumentDidChange : public NotificationInMessage { +struct In_TextDocumentDidChange : public NotificationMessage { MethodType GetMethodType() const override { return didChange; } lsTextDocumentDidChangeParams params; }; @@ -51,7 +51,7 @@ struct Handler_TextDocumentDidChange }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); -struct In_TextDocumentDidClose : public NotificationInMessage { +struct In_TextDocumentDidClose : public NotificationMessage { MethodType GetMethodType() const override { return didClose; } struct Params { lsTextDocumentIdentifier textDocument; @@ -68,19 +68,13 @@ struct Handler_TextDocumentDidClose void Run(In_TextDocumentDidClose *request) override { std::string path = request->params.textDocument.uri.GetPath(); - // Clear any diagnostics for the file. - Out_TextDocumentPublishDiagnostics out; - out.params.uri = request->params.textDocument.uri; - pipeline::WriteStdout(didClose, out); - - // Remove internal state. working_files->OnClose(request->params.textDocument); clang_complete->OnClose(path); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); -struct In_TextDocumentDidOpen : public NotificationInMessage { +struct In_TextDocumentDidOpen : public NotificationMessage { MethodType GetMethodType() const override { return didOpen; } struct Params { @@ -113,9 +107,9 @@ struct Handler_TextDocumentDidOpen QueryFile *file = nullptr; FindFileOrFail(db, project, std::nullopt, path, &file); - if (file && file->def) { - EmitSkippedRanges(working_file, file->def->skipped_ranges); - EmitSemanticHighlighting(db, working_file, file); + if (file) { + EmitSkippedRanges(working_file, *file); + EmitSemanticHighlight(db, working_file, *file); } include_complete->AddFile(working_file->filename); @@ -137,7 +131,7 @@ struct Handler_TextDocumentDidOpen }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); -struct In_TextDocumentDidSave : public NotificationInMessage { +struct In_TextDocumentDidSave : public NotificationMessage { MethodType GetMethodType() const override { return didSave; } struct Params { diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index 337cd6b3a..d0544d547 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -39,20 +39,13 @@ struct lsDocumentHighlight { }; MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); -struct In_TextDocumentDocumentHighlight : public RequestInMessage { +struct In_TextDocumentDocumentHighlight : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight); -struct Out_TextDocumentDocumentHighlight - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result); - struct Handler_TextDocumentDocumentHighlight : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -63,14 +56,12 @@ struct Handler_TextDocumentDocumentHighlight request->params.textDocument.uri.GetPath(), &file, &file_id)) return; - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - Out_TextDocumentDocumentHighlight out; - out.id = request->id; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + std::vector result; - std::vector syms = FindSymbolsAtLocation( - working_file, file, request->params.position, true); + std::vector syms = + FindSymbolsAtLocation(wfile, file, request->params.position, true); for (auto [sym, refcnt] : file->symbol2refcnt) { if (refcnt <= 0) continue; @@ -90,11 +81,11 @@ struct Handler_TextDocumentDocumentHighlight else highlight.kind = lsDocumentHighlight::Text; highlight.role = sym.role; - out.result.push_back(highlight); + result.push_back(highlight); } } - std::sort(out.result.begin(), out.result.end()); - pipeline::WriteStdout(kMethodType, out); + std::sort(result.begin(), result.end()); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index cc2535eb1..43a3b43a8 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -24,7 +24,7 @@ MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); namespace { MethodType kMethodType = "textDocument/documentSymbol"; -struct In_TextDocumentDocumentSymbol : public RequestInMessage { +struct In_TextDocumentDocumentSymbol : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; @@ -40,20 +40,6 @@ MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol::Params, textDocument, all, MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); -struct Out_SimpleDocumentSymbol - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_SimpleDocumentSymbol, jsonrpc, id, result); - -struct Out_TextDocumentDocumentSymbol - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result); - struct lsDocumentSymbol { std::string name; std::string detail; @@ -69,13 +55,6 @@ void Reflect(Writer &vis, std::unique_ptr &v) { Reflect(vis, *v); } -struct Out_HierarchicalDocumentSymbol - : public lsOutMessage { - lsRequestId id; - std::vector> result; -}; -MAKE_REFLECT_STRUCT(Out_HierarchicalDocumentSymbol, jsonrpc, id, result); - template bool Ignore(const Def *def) { return false; @@ -107,15 +86,14 @@ struct Handler_TextDocumentDocumentSymbol const auto &symbol2refcnt = params.all ? file->symbol2refcnt : file->outline2refcnt; if (params.startLine >= 0) { - Out_SimpleDocumentSymbol out; - out.id = request->id; + std::vector result; for (auto [sym, refcnt] : symbol2refcnt) if (refcnt > 0 && params.startLine <= sym.range.start.line && sym.range.start.line <= params.endLine) if (auto loc = GetLsLocation(db, working_files, sym, file_id)) - out.result.push_back(loc->range); - std::sort(out.result.begin(), out.result.end()); - pipeline::WriteStdout(kMethodType, out); + result.push_back(loc->range); + std::sort(result.begin(), result.end()); + pipeline::Reply(request->id, result); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { std::unordered_map> sym2ds; std::vector> funcs; @@ -207,15 +185,13 @@ struct Handler_TextDocumentDocumentSymbol ds->children.push_back(std::move(it->second)); } } - Out_HierarchicalDocumentSymbol out; - out.id = request->id; + std::vector> result; for (auto &[_, ds] : sym2ds) if (ds) - out.result.push_back(std::move(ds)); - pipeline::WriteStdout(kMethodType, out); + result.push_back(std::move(ds)); + pipeline::Reply(request->id, result); } else { - Out_TextDocumentDocumentSymbol out; - out.id = request->id; + std::vector result; for (auto [sym, refcnt] : symbol2refcnt) { if (refcnt <= 0) continue; if (std::optional info = @@ -227,11 +203,11 @@ struct Handler_TextDocumentDocumentSymbol continue; if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { info->location = *loc; - out.result.push_back(*info); + result.push_back(*info); } } } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } } }; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 1676a9b58..a6444c58a 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -36,13 +36,6 @@ struct lsFormattingOptions { }; MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); -struct Out_TextDocumentFormatting - : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentFormatting, jsonrpc, id, result); - llvm::Expected FormatCode(std::string_view code, std::string_view file, tooling::Range Range) { StringRef Code(code.data(), code.size()), File(file.data(), file.size()); @@ -91,20 +84,17 @@ void Format(WorkingFile *wfile, tooling::Range range, lsRequestId id) { auto ReplsOrErr = FormatCode(code, wfile->filename, range); if (ReplsOrErr) { - Out_TextDocumentFormatting out; - out.id = id; - out.result = ReplacementsToEdits(code, *ReplsOrErr); - pipeline::WriteStdout(formatting, out); + auto result = ReplacementsToEdits(code, *ReplsOrErr); + pipeline::Reply(id, result); } else { - Out_Error err; - err.id = id; - err.error.code = lsErrorCodes::UnknownErrorCode; - err.error.message = llvm::toString(ReplsOrErr.takeError()); - pipeline::WriteStdout(kMethodType_Unknown, err); + lsResponseError err; + err.code = lsErrorCodes::UnknownErrorCode; + err.message = llvm::toString(ReplsOrErr.takeError()); + pipeline::ReplyError(id, err); } } -struct In_TextDocumentFormatting : public RequestInMessage { +struct In_TextDocumentFormatting : public RequestMessage { MethodType GetMethodType() const override { return formatting; } struct Params { lsTextDocumentIdentifier textDocument; @@ -132,7 +122,7 @@ struct Handler_TextDocumentFormatting }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); -struct In_TextDocumentOnTypeFormatting : public RequestInMessage { +struct In_TextDocumentOnTypeFormatting : public RequestMessage { MethodType GetMethodType() const override { return onTypeFormatting; } struct Params { lsTextDocumentIdentifier textDocument; @@ -168,7 +158,7 @@ struct Handler_TextDocumentOnTypeFormatting }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentOnTypeFormatting); -struct In_TextDocumentRangeFormatting : public RequestInMessage { +struct In_TextDocumentRangeFormatting : public RequestMessage { MethodType GetMethodType() const override { return rangeFormatting; } struct Params { lsTextDocumentIdentifier textDocument; diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index d7580fe7a..c88368b88 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -70,25 +70,18 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { return {hover, ls_comments}; } -struct In_TextDocumentHover : public RequestInMessage { +struct In_TextDocumentHover : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; MAKE_REFLECT_STRUCT(In_TextDocumentHover, id, params); REGISTER_IN_MESSAGE(In_TextDocumentHover); -struct Out_TextDocumentHover : public lsOutMessage { - struct Result { - std::vector contents; - std::optional range; - }; - - lsRequestId id; - std::optional result; +struct lsHover { + std::vector contents; + std::optional range; }; -MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); -MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, jsonrpc, id, - result); +MAKE_REFLECT_STRUCT(lsHover, contents, range); struct Handler_TextDocumentHover : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } @@ -99,33 +92,27 @@ struct Handler_TextDocumentHover : BaseMessageHandler { params.textDocument.uri.GetPath(), &file)) return; - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - Out_TextDocumentHover out; - out.id = request->id; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsHover result; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { - // Found symbol. Return hover. + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { std::optional ls_range = GetLsRange( working_files->GetFileByFilename(file->def->path), sym.range); if (!ls_range) continue; - auto[hover, comments] = GetHover(db, file->def->language, sym, file->id); + auto [hover, comments] = GetHover(db, file->def->language, sym, file->id); if (comments || hover) { - out.result = Out_TextDocumentHover::Result(); - out.result->range = *ls_range; + result.range = *ls_range; if (comments) - out.result->contents.push_back(*comments); + result.contents.push_back(*comments); if (hover) - out.result->contents.push_back(*hover); + result.contents.push_back(*hover); break; } } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); diff --git a/src/messages/textDocument_implementation.cc b/src/messages/textDocument_implementation.cc deleted file mode 100644 index e2db7078d..000000000 --- a/src/messages/textDocument_implementation.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/implementation"; - -struct In_TextDocumentImplementation : public RequestInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentImplementation, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentImplementation); - -struct Handler_TextDocumentImplementation - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentImplementation *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { - return; - } - - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - Out_LocationList out; - out.id = request->id; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - if (sym.kind == SymbolKind::Type) { - QueryType &type = db->GetType(sym); - out.result = GetLsLocations(db, working_files, - GetTypeDeclarations(db, type.derived)); - break; - } else if (sym.kind == SymbolKind::Func) { - QueryFunc &func = db->GetFunc(sym); - out.result = GetLsLocations(db, working_files, - GetFuncDeclarations(db, func.derived)); - break; - } - } - pipeline::WriteStdout(kMethodType, out); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); -} // namespace diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index e5f2ac5be..07573d56f 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -24,7 +24,7 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/references"; -struct In_TextDocumentReferences : public RequestInMessage { +struct In_TextDocumentReferences : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct lsReferenceContext { bool base = true; @@ -60,11 +60,10 @@ struct Handler_TextDocumentReferences if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - Out_LocationList out; - out.id = request->id; + std::vector result; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); if (!file) { - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); return; } @@ -86,7 +85,7 @@ struct Handler_TextDocumentReferences !(use.role & params.context.excludeRole) && seen_uses.insert(use).second) if (auto loc = GetLsLocation(db, working_files, use)) { - out.result.push_back(*loc); + result.push_back(*loc); } }; WithEntity(db, sym, [&](const auto &entity) { @@ -116,7 +115,7 @@ struct Handler_TextDocumentReferences break; } - if (out.result.empty()) { + if (result.empty()) { // |path| is the #include line. If the cursor is not on such line but line // = 0, // use the current filename. @@ -134,16 +133,16 @@ struct Handler_TextDocumentReferences for (const IndexInclude &include : file1.def->includes) if (include.resolved_path == path) { // Another file |file1| has the same include line. - lsLocation &loc = out.result.emplace_back(); + lsLocation &loc = result.emplace_back(); loc.uri = lsDocumentUri::FromPath(file1.def->path); loc.range.start.line = loc.range.end.line = include.line; break; } } - if ((int)out.result.size() >= g_config->xref.maxNum) - out.result.resize(g_config->xref.maxNum); - pipeline::WriteStdout(kMethodType, out); + if ((int)result.size() >= g_config->xref.maxNum) + result.resize(g_config->xref.maxNum); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index e701e7067..d172e0bf5 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -63,7 +63,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, return edit; } -struct In_TextDocumentRename : public RequestInMessage { +struct In_TextDocumentRename : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { // The document to format. @@ -84,12 +84,6 @@ MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position, MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params); REGISTER_IN_MESSAGE(In_TextDocumentRename); -struct Out_TextDocumentRename : public lsOutMessage { - lsRequestId id; - lsWorkspaceEdit result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result); - struct Handler_TextDocumentRename : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentRename *request) override { @@ -97,25 +91,19 @@ struct Handler_TextDocumentRename : BaseMessageHandler { QueryFile *file; if (!FindFileOrFail(db, project, request->id, request->params.textDocument.uri.GetPath(), &file, - &file_id)) { + &file_id)) return; - } - - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - Out_TextDocumentRename out; - out.id = request->id; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsWorkspaceEdit result; for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - // Found symbol. Return references to rename. - out.result = + FindSymbolsAtLocation(wfile, file, request->params.position)) { + result = BuildWorkspaceEdit(db, working_files, sym, request->params.newName); break; } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index ef501c536..14a9230f9 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -55,20 +55,13 @@ struct lsSignatureHelp { MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, activeParameter); -struct In_TextDocumentSignatureHelp : public RequestInMessage { +struct In_TextDocumentSignatureHelp : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; MAKE_REFLECT_STRUCT(In_TextDocumentSignatureHelp, id, params); REGISTER_IN_MESSAGE(In_TextDocumentSignatureHelp); -struct Out_TextDocumentSignatureHelp - : public lsOutMessage { - lsRequestId id; - lsSignatureHelp result; -}; -MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result); - std::string BuildOptional(const CodeCompletionString &CCS, std::vector &ls_params) { std::string ret; @@ -199,10 +192,7 @@ struct Handler_TextDocumentSignatureHelp if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); - Out_TextDocumentSignatureHelp out; - out.id = id; - out.result = Consumer->ls_sighelp; - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(id, Consumer->ls_sighelp); if (!Consumer->from_cache) { cache.WithLock([&]() { cache.path = path; diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index 812bfe4af..3e931d2e4 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -21,7 +21,7 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/typeDefinition"; -struct In_TextDocumentTypeDefinition : public RequestInMessage { +struct In_TextDocumentTypeDefinition : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } lsTextDocumentPositionParams params; }; @@ -40,18 +40,17 @@ struct Handler_TextDocumentTypeDefinition WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList out; - out.id = request->id; + std::vector result; auto Add = [&](const QueryType &type) { for (const auto &def : type.def) if (def.spell) { if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) - out.result.push_back(*ls_loc); + result.push_back(*ls_loc); } - if (out.result.empty()) + if (result.empty()) for (const DeclRef &dr : type.declarations) if (auto ls_loc = GetLsLocation(db, working_files, dr)) - out.result.push_back(*ls_loc); + result.push_back(*ls_loc); }; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { @@ -75,7 +74,7 @@ struct Handler_TextDocumentTypeDefinition } } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); diff --git a/src/messages/workspace_did.cc b/src/messages/workspace_did.cc index 949436f5c..46ae4cb5f 100644 --- a/src/messages/workspace_did.cc +++ b/src/messages/workspace_did.cc @@ -25,6 +25,7 @@ using namespace ccls; namespace { MethodType didChangeConfiguration = "workspace/didChangeConfiguration", + didChangeWatchedFiles = "workspace/didChangeWatchedFiles", didChangeWorkspaceFolders = "workspace/didChangeWorkspaceFolders"; struct lsDidChangeConfigurationParams { @@ -32,7 +33,7 @@ struct lsDidChangeConfigurationParams { }; MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); -struct In_workspaceDidChangeConfiguration : public NotificationInMessage { +struct In_workspaceDidChangeConfiguration : public NotificationMessage { MethodType GetMethodType() const override { return didChangeConfiguration; } lsDidChangeConfigurationParams params; }; @@ -53,12 +54,66 @@ struct Handler_workspaceDidChangeConfiguration }; REGISTER_MESSAGE_HANDLER(Handler_workspaceDidChangeConfiguration); +enum class lsFileChangeType { + Created = 1, + Changed = 2, + Deleted = 3, +}; +MAKE_REFLECT_TYPE_PROXY(lsFileChangeType); + +struct lsFileEvent { + lsDocumentUri uri; + lsFileChangeType type; +}; +MAKE_REFLECT_STRUCT(lsFileEvent, uri, type); + +struct lsDidChangeWatchedFilesParams { + std::vector changes; +}; +MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes); + +struct In_WorkspaceDidChangeWatchedFiles : public NotificationMessage { + MethodType GetMethodType() const override { return didChangeWatchedFiles; } + lsDidChangeWatchedFilesParams params; +}; +MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeWatchedFiles, params); +REGISTER_IN_MESSAGE(In_WorkspaceDidChangeWatchedFiles); + +struct Handler_WorkspaceDidChangeWatchedFiles + : BaseMessageHandler { + MethodType GetMethodType() const override { return didChangeWatchedFiles; } + void Run(In_WorkspaceDidChangeWatchedFiles *request) override { + for (lsFileEvent &event : request->params.changes) { + std::string path = event.uri.GetPath(); + IndexMode mode = working_files->GetFileByFilename(path) + ? IndexMode::Normal + : IndexMode::NonInteractive; + switch (event.type) { + case lsFileChangeType::Created: + case lsFileChangeType::Changed: { + pipeline::Index(path, {}, mode); + if (mode == IndexMode::Normal) + clang_complete->NotifySave(path); + else + clang_complete->OnClose(path); + break; + } + case lsFileChangeType::Deleted: + pipeline::Index(path, {}, mode); + clang_complete->OnClose(path); + break; + } + } + } +}; +REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeWatchedFiles); + struct lsWorkspaceFoldersChangeEvent { std::vector added, removed; }; MAKE_REFLECT_STRUCT(lsWorkspaceFoldersChangeEvent, added, removed); -struct In_workspaceDidChangeWorkspaceFolders : public NotificationInMessage { +struct In_workspaceDidChangeWorkspaceFolders : public NotificationMessage { MethodType GetMethodType() const override { return didChangeWorkspaceFolders; } diff --git a/src/messages/workspace_didChangeWatchedFiles.cc b/src/messages/workspace_didChangeWatchedFiles.cc deleted file mode 100644 index d338cfc8f..000000000 --- a/src/messages/workspace_didChangeWatchedFiles.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "message_handler.h" -#include "pipeline.hh" -#include "project.h" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "workspace/didChangeWatchedFiles"; - -enum class lsFileChangeType { - Created = 1, - Changed = 2, - Deleted = 3, -}; -MAKE_REFLECT_TYPE_PROXY(lsFileChangeType); - -struct lsFileEvent { - lsDocumentUri uri; - lsFileChangeType type; -}; -MAKE_REFLECT_STRUCT(lsFileEvent, uri, type); - -struct lsDidChangeWatchedFilesParams { - std::vector changes; -}; -MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes); - -struct In_WorkspaceDidChangeWatchedFiles : public NotificationInMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsDidChangeWatchedFilesParams params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeWatchedFiles, params); -REGISTER_IN_MESSAGE(In_WorkspaceDidChangeWatchedFiles); - -struct Handler_WorkspaceDidChangeWatchedFiles - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceDidChangeWatchedFiles *request) override { - for (lsFileEvent &event : request->params.changes) { - std::string path = event.uri.GetPath(); - IndexMode mode = working_files->GetFileByFilename(path) - ? IndexMode::Normal - : IndexMode::NonInteractive; - switch (event.type) { - case lsFileChangeType::Created: - case lsFileChangeType::Changed: { - pipeline::Index(path, {}, mode); - if (mode == IndexMode::Normal) - clang_complete->NotifySave(path); - else - clang_complete->OnClose(path); - break; - } - case lsFileChangeType::Deleted: - pipeline::Index(path, {}, mode); - clang_complete->OnClose(path); - break; - } - } - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeWatchedFiles); -} // namespace diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index c9bb43d86..e87d7c6f3 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -54,7 +54,7 @@ bool AddSymbol( return true; } -struct In_WorkspaceSymbol : public RequestInMessage { +struct In_WorkspaceSymbol : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { std::string query; @@ -65,20 +65,11 @@ MAKE_REFLECT_STRUCT(In_WorkspaceSymbol::Params, query); MAKE_REFLECT_STRUCT(In_WorkspaceSymbol, id, params); REGISTER_IN_MESSAGE(In_WorkspaceSymbol); -struct Out_WorkspaceSymbol : public lsOutMessage { - lsRequestId id; - std::vector result; -}; -MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result); - -///// Fuzzy matching struct Handler_WorkspaceSymbol : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_WorkspaceSymbol *request) override { - Out_WorkspaceSymbol out; - out.id = request->id; - + std::vector result; std::string query = request->params.query; // {symbol info, matching detailed_name or short_name, index} @@ -128,20 +119,20 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { std::sort(cands.begin(), cands.end(), [](const auto &l, const auto &r) { return std::get<1>(l) > std::get<1>(r); }); - out.result.reserve(cands.size()); + result.reserve(cands.size()); for (auto &cand : cands) { // Discard awful candidates. if (std::get<1>(cand) <= FuzzyMatcher::kMinScore) break; - out.result.push_back(std::get<0>(cand)); + result.push_back(std::get<0>(cand)); } } else { - out.result.reserve(cands.size()); + result.reserve(cands.size()); for (auto &cand : cands) - out.result.push_back(std::get<0>(cand)); + result.push_back(std::get<0>(cand)); } - pipeline::WriteStdout(kMethodType, out); + pipeline::Reply(request->id, result); } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); diff --git a/src/method.cc b/src/method.cc deleted file mode 100644 index ca55f45aa..000000000 --- a/src/method.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "method.h" - -MethodType kMethodType_Unknown = "$unknown"; -MethodType kMethodType_Exit = "exit"; -MethodType kMethodType_TextDocumentPublishDiagnostics = - "textDocument/publishDiagnostics"; -MethodType kMethodType_CclsPublishSkippedRanges = "$ccls/publishSkippedRanges"; -MethodType kMethodType_CclsPublishSemanticHighlighting = - "$ccls/publishSemanticHighlighting"; - -void Reflect(Reader &visitor, lsRequestId &value) { - if (visitor.IsInt64()) { - value.type = lsRequestId::kInt; - value.value = int(visitor.GetInt64()); - } else if (visitor.IsInt()) { - value.type = lsRequestId::kInt; - value.value = visitor.GetInt(); - } else if (visitor.IsString()) { - value.type = lsRequestId::kString; - value.value = atoll(visitor.GetString()); - } else { - value.type = lsRequestId::kNone; - value.value = -1; - } -} - -void Reflect(Writer &visitor, lsRequestId &value) { - switch (value.type) { - case lsRequestId::kNone: - visitor.Null(); - break; - case lsRequestId::kInt: - visitor.Int(value.value); - break; - case lsRequestId::kString: - auto s = std::to_string(value.value); - visitor.String(s.c_str(), s.length()); - break; - } -} diff --git a/src/method.h b/src/method.h deleted file mode 100644 index 3bf180f4d..000000000 --- a/src/method.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "serializer.h" -#include "utils.h" - -#include - -using MethodType = const char *; -extern MethodType kMethodType_Unknown; -extern MethodType kMethodType_Exit; -extern MethodType kMethodType_TextDocumentPublishDiagnostics; -extern MethodType kMethodType_CclsPublishSkippedRanges; -extern MethodType kMethodType_CclsPublishSemanticHighlighting; - -struct lsRequestId { - // The client can send the request id as an int or a string. We should output - // the same format we received. - enum Type { kNone, kInt, kString }; - Type type = kNone; - - int value = -1; - - bool Valid() const { return type != kNone; } -}; -void Reflect(Reader &visitor, lsRequestId &value); -void Reflect(Writer &visitor, lsRequestId &value); - -struct InMessage { - virtual ~InMessage() = default; - - virtual MethodType GetMethodType() const = 0; - virtual lsRequestId GetRequestId() const = 0; -}; - -struct RequestInMessage : public InMessage { - // number or string, actually no null - lsRequestId id; - lsRequestId GetRequestId() const override { return id; } -}; - -// NotificationInMessage does not have |id|. -struct NotificationInMessage : public InMessage { - lsRequestId GetRequestId() const override { return lsRequestId(); } -}; diff --git a/src/pipeline.cc b/src/pipeline.cc index f230413d7..62fd4d211 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -26,6 +26,9 @@ limitations under the License. #include "platform.h" #include "project.h" #include "query_utils.h" +#include "serializers/json.h" + +#include #include #include @@ -76,18 +79,13 @@ struct Index_Request { int64_t ts = tick++; }; -struct Stdout_Request { - MethodType method; - std::string content; -}; - MultiQueueWaiter *main_waiter; MultiQueueWaiter *indexer_waiter; MultiQueueWaiter *stdout_waiter; ThreadedQueue> *on_request; ThreadedQueue *index_request; ThreadedQueue *on_indexed; -ThreadedQueue *for_stdout; +ThreadedQueue *for_stdout; struct InMemoryIndexFile { std::string content; @@ -299,11 +297,10 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (!ok) { if (request.id.Valid()) { - Out_Error out; - out.id = request.id; - out.error.code = lsErrorCodes::InternalError; - out.error.message = "Failed to index " + path_to_index; - pipeline::WriteStdout(kMethodType_Unknown, out); + lsResponseError err; + err.code = lsErrorCodes::InternalError; + err.message = "failed to index " + path_to_index; + pipeline::ReplyError(request.id, err); } return true; } @@ -363,7 +360,7 @@ void Init() { index_request = new ThreadedQueue(indexer_waiter); stdout_waiter = new MultiQueueWaiter; - for_stdout = new ThreadedQueue(stdout_waiter); + for_stdout = new ThreadedQueue(stdout_waiter); } void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, @@ -383,8 +380,8 @@ void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { std::string filename = LowerPathIfInsensitive(f->filename); if (db->name2file_id.find(filename) == db->name2file_id.end()) continue; - QueryFile *file = &db->files[db->name2file_id[filename]]; - EmitSemanticHighlighting(db, f.get(), file); + QueryFile &file = db->files[db->name2file_id[filename]]; + EmitSemanticHighlight(db, f.get(), file); } return; } @@ -403,8 +400,9 @@ void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { // request.path wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content : def_u.second); - EmitSkippedRanges(wfile, def_u.first.skipped_ranges); - EmitSemanticHighlighting(db, wfile, &db->files[update->file_id]); + QueryFile &file = db->files[update->file_id]; + EmitSkippedRanges(wfile, file); + EmitSemanticHighlight(db, wfile, file); } } } @@ -414,21 +412,20 @@ void LaunchStdin() { set_thread_name("stdin"); while (true) { std::unique_ptr message; - std::optional err = + std::optional error = MessageRegistry::instance()->ReadMessageFromStdin(&message); // Message parsing can fail if we don't recognize the method. - if (err) { + if (error) { // The message may be partially deserialized. // Emit an error ResponseMessage if |id| is available. if (message) { lsRequestId id = message->GetRequestId(); if (id.Valid()) { - Out_Error out; - out.id = id; - out.error.code = lsErrorCodes::InvalidParams; - out.error.message = std::move(*err); - WriteStdout(kMethodType_Unknown, out); + lsResponseError err; + err.code = lsErrorCodes::InvalidParams; + err.message = std::move(*error); + ReplyError(id, err); } } continue; @@ -453,20 +450,12 @@ void LaunchStdout() { set_thread_name("stdout"); while (true) { - std::vector messages = for_stdout->DequeueAll(); - if (messages.empty()) { - stdout_waiter->Wait(for_stdout); - continue; - } - - for (auto &message : messages) { -#ifdef _WIN32 - fwrite(message.content.c_str(), message.content.size(), 1, stdout); - fflush(stdout); -#else - write(1, message.content.c_str(), message.content.size()); -#endif + std::vector messages = for_stdout->DequeueAll(); + for (auto &s : messages) { + llvm::outs() << "Content-Length: " << s.size() << "\r\n\r\n" << s; + llvm::outs().flush(); } + stdout_waiter->Wait(for_stdout); } }) .detach(); @@ -480,20 +469,17 @@ void MainLoop() { CompletionManager clang_complete( &project, &working_files, [&](std::string path, std::vector diagnostics) { - Out_TextDocumentPublishDiagnostics out; - out.params.uri = lsDocumentUri::FromPath(path); - out.params.diagnostics = diagnostics; - ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, - out); + lsPublishDiagnosticsParams params; + params.uri = lsDocumentUri::FromPath(path); + params.diagnostics = diagnostics; + Notify("textDocument/publishDiagnostics", params); }, [](lsRequestId id) { if (id.Valid()) { - Out_Error out; - out.id = id; - out.error.code = lsErrorCodes::InternalError; - out.error.message = "Dropping completion request; a newer request " - "has come in that will be serviced instead."; - pipeline::WriteStdout(kMethodType_Unknown, out); + lsResponseError err; + err.code = lsErrorCodes::InternalError; + err.message = "drop older completion request"; + ReplyError(id, err); } }); @@ -566,14 +552,54 @@ std::optional LoadIndexedContent(const std::string &path) { return ReadContent(GetCachePath(path)); } -void WriteStdout(MethodType method, lsBaseOutMessage &response) { - std::ostringstream sstream; - response.Write(sstream); +void Notify(const char *method, const std::function &fn) { + rapidjson::StringBuffer output; + rapidjson::Writer w(output); + w.StartObject(); + w.Key("jsonrpc"); + w.String("2.0"); + w.Key("method"); + w.String(method); + w.Key("params"); + JsonWriter writer(&w); + fn(writer); + w.EndObject(); + for_stdout->PushBack(output.GetString()); +} + +static void Reply(lsRequestId id, const char *key, + const std::function &fn) { + rapidjson::StringBuffer output; + rapidjson::Writer w(output); + w.StartObject(); + w.Key("jsonrpc"); + w.String("2.0"); + w.Key("id"); + switch (id.type) { + case lsRequestId::kNone: + w.Null(); + break; + case lsRequestId::kInt: + w.Int(id.value); + break; + case lsRequestId::kString: + auto s = std::to_string(id.value); + w.String(s.c_str(), s.length()); + break; + } + w.Key(key); + JsonWriter writer(&w); + fn(writer); + w.EndObject(); + for_stdout->PushBack(output.GetString()); +} + +void Reply(lsRequestId id, const std::function &fn) { + Reply(id, "result", fn); +} - Stdout_Request out; - out.content = sstream.str(); - out.method = method; - for_stdout->PushBack(std::move(out)); +void ReplyError(lsRequestId id, const std::function &fn) { + Reply(id, "error", fn); } } // namespace ccls::pipeline diff --git a/src/pipeline.hh b/src/pipeline.hh index b4cc514b6..e0adc9694 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,7 +1,6 @@ #pragma once -#include "lsp_diagnostic.h" -#include "method.h" +#include "lsp.h" #include "query.h" #include @@ -15,7 +14,6 @@ struct GroupMatch; struct VFS; struct Project; struct WorkingFiles; -struct lsBaseOutMessage; struct VFS { struct State { @@ -52,6 +50,20 @@ void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {}); std::optional LoadIndexedContent(const std::string& path); -void WriteStdout(MethodType method, lsBaseOutMessage &response); + +void Notify(const char *method, const std::function &fn); +template void Notify(const char *method, T &result) { + Notify(method, [&](Writer &w) { Reflect(w, result); }); +} + +void Reply(lsRequestId id, const std::function &fn); +template void Reply(lsRequestId id, T &result) { + Reply(id, [&](Writer &w) { Reflect(w, result); }); +} + +void ReplyError(lsRequestId id, const std::function &fn); +template void ReplyError(lsRequestId id, T &result) { + ReplyError(id, [&](Writer &w) { Reflect(w, result); }); +} } // namespace pipeline } // namespace ccls diff --git a/src/project.h b/src/project.h index 90547ba31..d3786aa21 100644 --- a/src/project.h +++ b/src/project.h @@ -17,7 +17,6 @@ limitations under the License. #include "config.h" #include "lsp.h" -#include "method.h" #include #include diff --git a/src/serializer.cc b/src/serializer.cc index 5c9730ea4..8c813430b 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -32,7 +32,13 @@ using namespace llvm; bool gTestOutputMode = false; -//// Elementary types +Reader::~Reader() {} +BinaryReader::~BinaryReader() {} +JsonReader::~JsonReader() {} + +Writer::~Writer() {} +BinaryWriter::~BinaryWriter() {} +JsonWriter::~JsonWriter() {} void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); } void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); } diff --git a/src/serializer.h b/src/serializer.h index 5e05a4756..ae111444d 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -38,11 +38,10 @@ class StringRef; enum class SerializeFormat { Binary, Json }; struct JsonNull {}; -struct mandatory_optional_tag {}; class Reader { public: - virtual ~Reader() {} + virtual ~Reader(); virtual SerializeFormat Format() const = 0; virtual bool IsBool() = 0; @@ -72,7 +71,7 @@ class Reader { class Writer { public: - virtual ~Writer() {} + virtual ~Writer(); virtual SerializeFormat Format() const = 0; virtual void Null() = 0; @@ -97,8 +96,6 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) -#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ - ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) #define MAKE_REFLECT_TYPE_PROXY(type_name) \ @@ -115,8 +112,6 @@ struct IndexFile; } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); -#define _MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ - REFLECT_MEMBER_MANDATORY_OPTIONAL(name); #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ template void Reflect(TVisitor &visitor, type &value) { \ @@ -131,13 +126,6 @@ struct IndexFile; REFLECT_MEMBER_END(); \ } -#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ - template void Reflect(TVisitor &visitor, type &value) { \ - REFLECT_MEMBER_START(); \ - MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ - REFLECT_MEMBER_END(); \ - } - // clang-format off // Config has many fields, we need to support at least its number of fields. #define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N @@ -268,13 +256,6 @@ void ReflectMember(Writer &visitor, const char *name, Maybe &value) { } } -template -void ReflectMember(Writer &visitor, const char *name, T &value, - mandatory_optional_tag) { - visitor.Key(name); - Reflect(visitor, value); -} - template void Reflect(Reader &vis, std::pair &v) { vis.Member("L", [&]() { Reflect(vis, v.first); }); diff --git a/src/serializers/binary.h b/src/serializers/binary.h index a1c9266fa..7a1e478cc 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -46,6 +46,7 @@ class BinaryReader : public Reader { public: BinaryReader(std::string_view buf) : p_(buf.data()) {} + virtual ~BinaryReader(); SerializeFormat Format() const override { return SerializeFormat::Binary; } bool IsBool() override { return true; } @@ -110,6 +111,7 @@ class BinaryWriter : public Writer { void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); } public: + virtual ~BinaryWriter(); SerializeFormat Format() const override { return SerializeFormat::Binary; } std::string Take() { return std::move(buf_); } diff --git a/src/serializers/json.h b/src/serializers/json.h index fb3751bc2..e987902f0 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -26,6 +26,7 @@ class JsonReader : public Reader { public: JsonReader(rapidjson::GenericValue> *m) : m_(m) {} + virtual ~JsonReader(); SerializeFormat Format() const override { return SerializeFormat::Json; } rapidjson::GenericValue> &m() { return *m_; } @@ -95,6 +96,7 @@ class JsonWriter : public Writer { public: JsonWriter(rapidjson::Writer *m) : m_(m) {} + virtual ~JsonWriter(); SerializeFormat Format() const override { return SerializeFormat::Json; } rapidjson::Writer &m() { return *m_; } diff --git a/src/working_files.cc b/src/working_files.cc index 319a887e0..f3ec44f89 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -315,6 +315,8 @@ void WorkingFile::ComputeLineMapping() { std::optional WorkingFile::GetBufferPosFromIndexPos(int line, int *column, bool is_end) { + if (line == (int)index_lines.size() && !*column) + return buffer_content.size(); if (line < 0 || line >= (int)index_lines.size()) { LOG_S(WARNING) << "bad index_line (got " << line << ", expected [0, " << index_lines.size() << ")) in " << filename; @@ -329,7 +331,6 @@ std::optional WorkingFile::GetBufferPosFromIndexPos(int line, int *column, std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int *column, bool is_end) { - // See GetBufferLineFromIndexLine for additional comments. if (line < 0 || line >= (int)buffer_lines.size()) return std::nullopt; diff --git a/src/working_files.h b/src/working_files.h index caa001fd3..1767789e4 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "lsp_diagnostic.h" +#include "lsp.h" #include "utils.h" #include From cb7ed9415d536a04563766279b88579ac33bfcd5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 14 Oct 2018 23:33:24 -0700 Subject: [PATCH 264/378] Add ExtentRef; merge symbol2refcnt and outline2refcnt Fix hierarchical document symbol for namespaces when there are multiple declarations. --- src/indexer.h | 9 ++ src/messages/ccls_call.cc | 19 +-- src/messages/ccls_navigate.cc | 54 ++++----- src/messages/textDocument_codeLens.cc | 41 +++---- src/messages/textDocument_documentSymbol.cc | 121 +++++++++----------- src/query.cc | 28 ++--- src/query.h | 20 ++-- 7 files changed, 136 insertions(+), 156 deletions(-) diff --git a/src/indexer.h b/src/indexer.h index 510ce3046..ab80f642d 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -63,6 +63,15 @@ struct SymbolRef { }; MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role); +struct ExtentRef : SymbolRef { + Range extent; + std::tuple ToTuple() const { + return std::make_tuple(range, usr, kind, role, extent); + } + bool operator==(const ExtentRef &o) const { return ToTuple() == o.ToTuple(); } +}; +MAKE_HASHABLE(ExtentRef, t.range, t.usr, t.kind, t.role, t.extent); + struct Ref { Range range; Role role; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index fa049a771..46e992a9f 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -114,15 +114,16 @@ bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, } else { for (Use use : func.uses) { const QueryFile &file1 = m->db->files[use.file_id]; - Maybe best_sym; - for (auto [sym, refcnt] : file1.outline2refcnt) - if (refcnt > 0 && sym.kind == SymbolKind::Func && - sym.range.start <= use.range.start && - use.range.end <= sym.range.end && - (!best_sym || best_sym->range.start < sym.range.start)) - best_sym = sym; - if (best_sym) - handle(*best_sym, use.file_id, call_type); + Maybe best; + for (auto [sym, refcnt] : file1.symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && + sym.kind == SymbolKind::Func && + sym.extent.start <= use.range.start && + use.range.end <= sym.extent.end && + (!best || best->extent.start < sym.extent.start)) + best = sym; + if (best) + handle(*best, use.file_id, call_type); } } }; diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 9e73ec063..d5468c088 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -55,49 +55,49 @@ struct Handler_CclsNavigate : BaseMessageHandler { switch (params.direction[0]) { case 'D': { Maybe parent; - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && sym.range.start <= pos && pos < sym.range.end && - (!parent || parent->start < sym.range.start)) - parent = sym.range; - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && pos < sym.range.start && - (!parent || sym.range.end <= parent->end) && - (!res || sym.range.start < res->start)) - res = sym.range; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && + pos < sym.extent.end && (!parent || parent->start < sym.extent.start)) + parent = sym.extent; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && pos < sym.extent.start && + (!parent || sym.extent.end <= parent->end) && + (!res || sym.extent.start < res->start)) + res = sym.extent; break; } case 'L': - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && sym.range.end <= pos && - (!res || (res->end == sym.range.end ? sym.range.start < res->start - : res->end < sym.range.end))) - res = sym.range; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.end <= pos && + (!res || (res->end == sym.extent.end ? sym.extent.start < res->start + : res->end < sym.extent.end))) + res = sym.extent; break; case 'R': { Maybe parent; - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && sym.range.start <= pos && pos < sym.range.end && - (!parent || parent->start < sym.range.start)) - parent = sym.range; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && + pos < sym.extent.end && (!parent || parent->start < sym.extent.start)) + parent = sym.extent; if (parent && parent->start.line == pos.line && pos < parent->end) { pos = parent->end; if (pos.column) pos.column--; } - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && pos < sym.range.start && + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && pos < sym.extent.start && (!res || - (sym.range.start == res->start ? res->end < sym.range.end - : sym.range.start < res->start))) - res = sym.range; + (sym.extent.start == res->start ? res->end < sym.extent.end + : sym.extent.start < res->start))) + res = sym.extent; break; } case 'U': default: - for (auto [sym, refcnt] : file->outline2refcnt) - if (refcnt > 0 && sym.range.start < pos && pos < sym.range.end && - (!res || res->start < sym.range.start)) - res = sym.range; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.start < pos && + pos < sym.extent.end && (!res || res->start < sym.extent.start)) + res = sym.extent; break; } std::vector result; diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc index dd2d41eb2..d07895579 100644 --- a/src/messages/textDocument_codeLens.cc +++ b/src/messages/textDocument_codeLens.cc @@ -86,15 +86,15 @@ struct Handler_TextDocumentCodeLens return; WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - auto Add = [&](const char *singular, Cmd_xref show, Use use, int num, + auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, bool force_display = false) { if (!num && !force_display) return; - std::optional range = GetLsRange(wfile, use.range); - if (!range) + std::optional ls_range = GetLsRange(wfile, range); + if (!ls_range) return; lsCodeLens &code_lens = result.emplace_back(); - code_lens.range = *range; + code_lens.range = *ls_range; code_lens.command = lsCommand(); code_lens.command->command = std::string(ccls_xref); bool plural = num > 1 && singular[strlen(singular) - 1] != 'd'; @@ -103,19 +103,10 @@ struct Handler_TextDocumentCodeLens code_lens.command->arguments.push_back(ToString(show)); }; - auto ToSpell = [&](SymbolRef sym, int file_id) -> Use { - Maybe def = GetDefinitionSpell(db, sym); - if (def && def->file_id == file_id && - def->range.start.line == sym.range.start.line) - return *def; - return {{sym.range, sym.role}, file_id}; - }; - std::unordered_set seen; - for (auto [sym, refcnt] : file->outline2refcnt) { - if (refcnt <= 0 || !seen.insert(sym.range).second) + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid() || !seen.insert(sym.range).second) continue; - Use use = ToSpell(sym, file->id); switch (sym.kind) { case SymbolKind::Func: { QueryFunc &func = db->GetFunc(sym); @@ -124,28 +115,28 @@ struct Handler_TextDocumentCodeLens continue; std::vector base_uses = GetUsesForAllBases(db, func); std::vector derived_uses = GetUsesForAllDerived(db, func); - Add("ref", {sym.usr, SymbolKind::Func, "uses"}, use, func.uses.size(), - base_uses.empty()); + Add("ref", {sym.usr, SymbolKind::Func, "uses"}, sym.range, + func.uses.size(), base_uses.empty()); if (base_uses.size()) - Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, use, + Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, sym.range, base_uses.size()); if (derived_uses.size()) - Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, use, + Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, sym.range, derived_uses.size()); if (base_uses.empty()) - Add("base", {sym.usr, SymbolKind::Func, "bases"}, use, + Add("base", {sym.usr, SymbolKind::Func, "bases"}, sym.range, def->bases.size()); - Add("derived", {sym.usr, SymbolKind::Func, "derived"}, use, + Add("derived", {sym.usr, SymbolKind::Func, "derived"}, sym.range, func.derived.size()); break; } case SymbolKind::Type: { QueryType &type = db->GetType(sym); - Add("ref", {sym.usr, SymbolKind::Type, "uses"}, use, type.uses.size(), + Add("ref", {sym.usr, SymbolKind::Type, "uses"}, sym.range, type.uses.size(), true); - Add("derived", {sym.usr, SymbolKind::Type, "derived"}, use, + Add("derived", {sym.usr, SymbolKind::Type, "derived"}, sym.range, type.derived.size()); - Add("var", {sym.usr, SymbolKind::Type, "instances"}, use, + Add("var", {sym.usr, SymbolKind::Type, "instances"}, sym.range, type.instances.size()); break; } @@ -154,7 +145,7 @@ struct Handler_TextDocumentCodeLens const QueryVar::Def *def = var.AnyDef(); if (!def || (def->is_local() && !g_config->codeLens.localVariables)) continue; - Add("ref", {sym.usr, SymbolKind::Var, "uses"}, use, var.uses.size(), + Add("ref", {sym.usr, SymbolKind::Var, "uses"}, sym.range, var.uses.size(), def->kind != lsSymbolKind::Macro); break; } diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_documentSymbol.cc index 43a3b43a8..f9c9fa12d 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_documentSymbol.cc @@ -83,12 +83,11 @@ struct Handler_TextDocumentDocumentSymbol if (!wfile) return; - const auto &symbol2refcnt = - params.all ? file->symbol2refcnt : file->outline2refcnt; if (params.startLine >= 0) { std::vector result; - for (auto [sym, refcnt] : symbol2refcnt) - if (refcnt > 0 && params.startLine <= sym.range.start.line && + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && (params.all || sym.extent.Valid()) && + params.startLine <= sym.range.start.line && sym.range.start.line <= params.endLine) if (auto loc = GetLsLocation(db, working_files, sym, file_id)) result.push_back(loc->range); @@ -96,95 +95,75 @@ struct Handler_TextDocumentDocumentSymbol pipeline::Reply(request->id, result); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { std::unordered_map> sym2ds; - std::vector> funcs; - std::vector> types; - for (auto [sym, refcnt] : symbol2refcnt) { - if (refcnt <= 0) + std::vector, lsDocumentSymbol *>> + funcs, types; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid()) continue; auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); if (!r.second) continue; auto &ds = r.first->second; ds = std::make_unique(); - const void *def_ptr = nullptr; - WithEntity(db, sym, [&](const auto &entity) { + std::vector def_ptrs; + WithEntity(db, sym, [&, sym = sym](const auto &entity) { auto *def = entity.AnyDef(); if (!def) return; ds->name = def->Name(false); ds->detail = def->Name(true); + if (auto ls_range = GetLsRange(wfile, sym.range)) { + ds->selectionRange = *ls_range; + ds->range = ds->selectionRange; + if (sym.extent.Valid()) + if (auto ls_range1 = GetLsRange(wfile, sym.extent)) + ds->range = *ls_range1; + } - // Try to find a definition with spell first. - const void *candidate_def_ptr = nullptr; for (auto &def : entity.def) if (def.file_id == file_id && !Ignore(&def)) { ds->kind = def.kind; - if (def.kind == lsSymbolKind::Namespace) - candidate_def_ptr = &def; - - if (!def.spell) - continue; - if (auto ls_range = GetLsRange(wfile, def.spell->extent)) - ds->range = *ls_range; - else - continue; - if (auto ls_range = GetLsRange(wfile, def.spell->range)) - ds->selectionRange = *ls_range; - else - continue; - def_ptr = &def; - break; + if (def.spell || def.kind == lsSymbolKind::Namespace) + def_ptrs.push_back(&def); } - - // Try to find a declaration. - if (!def_ptr && candidate_def_ptr) - for (auto &decl : entity.declarations) - if (decl.file_id == file_id) { - if (auto ls_range = GetLsRange(wfile, decl.extent)) - ds->range = *ls_range; - else - continue; - if (auto ls_range = GetLsRange(wfile, decl.range)) - ds->selectionRange = *ls_range; - else - continue; - def_ptr = candidate_def_ptr; - break; - } }); - if (!def_ptr) { + if (def_ptrs.empty() || !(params.all || sym.role & Role::Definition || + ds->kind == lsSymbolKind::Namespace)) { ds.reset(); continue; } if (sym.kind == SymbolKind::Func) - funcs.emplace_back((const QueryFunc::Def *)def_ptr, ds.get()); + funcs.emplace_back(std::move(def_ptrs), ds.get()); else if (sym.kind == SymbolKind::Type) - types.emplace_back((const QueryType::Def *)def_ptr, ds.get()); + types.emplace_back(std::move(def_ptrs), ds.get()); } - for (auto &[def, ds] : funcs) - for (Usr usr1 : def->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (auto &[def, ds] : types) { - for (Usr usr1 : def->funcs) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (Usr usr1 : def->types) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (auto [usr1, _] : def->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); + for (auto &[def_ptrs, ds] : funcs) + for (const void *def_ptr : def_ptrs) + for (Usr usr1 : ((const QueryFunc::Def *)def_ptr)->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (auto &[def_ptrs, ds] : types) + for (const void *def_ptr : def_ptrs) { + auto *def = (const QueryType::Def *)def_ptr; + for (Usr usr1 : def->funcs) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (Usr usr1 : def->types) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (auto [usr1, _] : def->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } } - } std::vector> result; for (auto &[_, ds] : sym2ds) if (ds) @@ -192,8 +171,10 @@ struct Handler_TextDocumentDocumentSymbol pipeline::Reply(request->id, result); } else { std::vector result; - for (auto [sym, refcnt] : symbol2refcnt) { - if (refcnt <= 0) continue; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid() || + !(params.all || sym.role & Role::Definition)) + continue; if (std::optional info = GetSymbolInfo(db, sym, false)) { if ((sym.kind == SymbolKind::Type && diff --git a/src/query.cc b/src/query.cc index c81b8827e..19889465f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -236,7 +236,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { SymbolKind kind, Use &use, int delta) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; - SymbolRef sym{use.range, usr, kind, use.role}; + ExtentRef sym{{use.range, usr, kind, use.role}}; int &v = files[use.file_id].symbol2refcnt[sym]; v += delta; assert(v >= 0); @@ -245,9 +245,14 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { }; auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, SymbolKind kind, DeclRef &dr, int delta) { - Ref(lid2fid, usr, kind, dr, delta); - files[dr.file_id] - .outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta; + dr.file_id = + dr.file_id == -1 ? u->file_id : lid2fid.find(dr.file_id)->second; + ExtentRef sym{{dr.range, usr, kind, dr.role}, dr.extent}; + int &v = files[dr.file_id].symbol2refcnt[sym]; + v += delta; + assert(v >= 0); + if (!v) + files[dr.file_id].symbol2refcnt.erase(sym); }; auto UpdateUses = @@ -381,9 +386,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++; - files[def.spell->file_id].outline2refcnt[{ - def.spell->extent, u.first, SymbolKind::Func, def.spell->role}]++; + {def.spell->range, u.first, SymbolKind::Func, def.spell->role}, + def.spell->extent}]++; } auto R = func_usr.try_emplace({u.first}, func_usr.size()); @@ -405,9 +409,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++; - files[def.spell->file_id].outline2refcnt[{ - def.spell->extent, u.first, SymbolKind::Type, def.spell->role}]++; + {def.spell->range, u.first, SymbolKind::Type, def.spell->role}, + def.spell->extent}]++; } auto R = type_usr.try_emplace({u.first}, type_usr.size()); if (R.second) @@ -428,9 +431,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++; - files[def.spell->file_id].outline2refcnt[{ - def.spell->extent, u.first, SymbolKind::Var, def.spell->role}]++; + {def.spell->range, u.first, SymbolKind::Var, def.spell->role}, + def.spell->extent}]++; } auto R = var_usr.try_emplace({u.first}, var_usr.size()); if (R.second) diff --git a/src/query.h b/src/query.h index d968a3a6b..9ba3898b3 100644 --- a/src/query.h +++ b/src/query.h @@ -22,17 +22,13 @@ limitations under the License. #include namespace llvm { -template <> struct DenseMapInfo { - static inline SymbolRef getEmptyKey() { return {}; } - static inline SymbolRef getTombstoneKey() { - SymbolRef ret{}; - ret.usr = -1; - return ret; - } - static unsigned getHashValue(SymbolRef sym) { - return std::hash()(sym); +template <> struct DenseMapInfo { + static inline ExtentRef getEmptyKey() { return {}; } + static inline ExtentRef getTombstoneKey() { return {{Range(), Usr(-1)}}; } + static unsigned getHashValue(ExtentRef sym) { + return std::hash()(sym); } - static bool isEqual(SymbolRef l, SymbolRef r) { return l == r; } + static bool isEqual(ExtentRef l, ExtentRef r) { return l == r; } }; } @@ -53,8 +49,8 @@ struct QueryFile { int id = -1; std::optional def; - llvm::DenseMap symbol2refcnt; - llvm::DenseMap outline2refcnt; + // `extent` is valid => declaration; invalid => regular reference + llvm::DenseMap symbol2refcnt; }; template struct QueryEntity { From 87ea7d244d6530b527f89c547c4fa1484b735aa0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Oct 2018 01:26:13 -0700 Subject: [PATCH 265/378] Simplify --- src/include_complete.cc | 16 ++-- src/indexer.h | 1 - src/lsp.h | 36 +++++++++ .../textDocument_documentHighlight.cc | 1 - src/platform_posix.cc | 75 ++----------------- src/symbol.h | 55 -------------- 6 files changed, 47 insertions(+), 137 deletions(-) delete mode 100644 src/symbol.h diff --git a/src/include_complete.cc b/src/include_complete.cc index c75398495..72931c313 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -84,20 +84,15 @@ bool TrimPath(Project *project, std::string &path) { } lsCompletionItem BuildCompletionItem(const std::string &path, - bool use_angle_brackets, bool is_stl) { + bool use_angle_brackets) { lsCompletionItem item; item.label = ElideLongPath(path); item.detail = path; // the include path, used in de-duplicating item.textEdit.newText = path; item.insertTextFormat = lsInsertTextFormat::PlainText; item.use_angle_brackets_ = use_angle_brackets; - if (is_stl) { - item.kind = lsCompletionItemKind::Module; - item.priority_ = 2; - } else { - item.kind = lsCompletionItemKind::File; - item.priority_ = 1; - } + item.kind = lsCompletionItemKind::File; + item.priority_ = 0; return item; } @@ -166,8 +161,7 @@ void IncludeComplete::AddFile(const std::string &path) { std::string trimmed_path = path; bool use_angle_brackets = TrimPath(project_, trimmed_path); - lsCompletionItem item = - BuildCompletionItem(trimmed_path, use_angle_brackets, false /*is_stl*/); + lsCompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets); std::unique_lock lock(completion_items_mutex, std::defer_lock); if (is_scanning) @@ -196,7 +190,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, CompletionCandidate candidate; candidate.absolute_path = directory + path; candidate.completion_item = - BuildCompletionItem(path, use_angle_brackets, false /*is_stl*/); + BuildCompletionItem(path, use_angle_brackets); results.push_back(candidate); }); diff --git a/src/indexer.h b/src/indexer.h index ab80f642d..1c4051096 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -19,7 +19,6 @@ limitations under the License. #include "maybe.h" #include "position.h" #include "serializer.h" -#include "symbol.h" #include "utils.h" #include diff --git a/src/lsp.h b/src/lsp.h index 9b0b800e1..b8b3e7ca2 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -220,6 +220,14 @@ enum class lsSymbolKind : uint8_t { }; MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); +struct lsSymbolInformation { + std::string_view name; + lsSymbolKind kind; + lsLocation location; + std::optional containerName; +}; +MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); + struct lsTextDocumentIdentifier { lsDocumentUri uri; }; @@ -394,3 +402,31 @@ MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message); // encounters a c++ declaration. enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 }; MAKE_REFLECT_TYPE_PROXY(LanguageId); + +// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in +// front of others. +enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; +MAKE_REFLECT_TYPE_PROXY(SymbolKind); + +enum class Role : uint16_t { + None = 0, + Declaration = 1 << 0, + Definition = 1 << 1, + Reference = 1 << 2, + Read = 1 << 3, + Write = 1 << 4, + Call = 1 << 5, + Dynamic = 1 << 6, + Address = 1 << 7, + Implicit = 1 << 8, + All = (1 << 9) - 1, +}; +MAKE_REFLECT_TYPE_PROXY(Role); + +inline uint16_t operator&(Role lhs, Role rhs) { + return uint16_t(lhs) & uint16_t(rhs); +} + +inline Role operator|(Role lhs, Role rhs) { + return Role(uint16_t(lhs) | uint16_t(rhs)); +} diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc index d0544d547..b96deb9c8 100644 --- a/src/messages/textDocument_documentHighlight.cc +++ b/src/messages/textDocument_documentHighlight.cc @@ -16,7 +16,6 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -#include "symbol.h" #include using namespace ccls; diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ed2f92dfc..fbbd07493 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -39,78 +39,15 @@ limitations under the License. #include #endif -#include - -namespace { - -// Returns the canonicalized absolute pathname, without expanding symbolic -// links. This is a variant of realpath(2), C++ rewrite of -// https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c -std::optional RealPathNotExpandSymlink(std::string path) { - if (path.empty()) { - errno = EINVAL; - return std::nullopt; - } - if (path[0] == '\0') { - errno = ENOENT; - return std::nullopt; - } - - // Do not use PATH_MAX because it is tricky on Linux. - // See https://eklitzke.org/path-max-is-tricky - char tmp[1024]; - std::string resolved; - size_t i = 0; - struct stat sb; - if (path[0] == '/') { - resolved = "/"; - i = 1; - } else { - if (!getcwd(tmp, sizeof tmp)) - return std::nullopt; - resolved = tmp; - } - - while (i < path.size()) { - auto j = path.find('/', i); - if (j == std::string::npos) - j = path.size(); - auto next_token = path.substr(i, j - i); - i = j + 1; - if (resolved.back() != '/') - resolved += '/'; - if (next_token.empty() || next_token == ".") { - // Handle consequential slashes and "." - continue; - } else if (next_token == "..") { - // Strip the last path component except when it is single "/" - if (resolved.size() > 1) - resolved.resize(resolved.rfind('/', resolved.size() - 2) + 1); - continue; - } - // Append the next path component. - // Here we differ from realpath(3), we use stat(2) instead of - // lstat(2) because we do not want to resolve symlinks. - resolved += next_token; - if (stat(resolved.c_str(), &sb) != 0) - return std::nullopt; - if (!S_ISDIR(sb.st_mode) && j < path.size()) { - errno = ENOTDIR; - return std::nullopt; - } - } +#include +#include - // Remove trailing slash except when a single "/". - if (resolved.size() > 1 && resolved.back() == '/') - resolved.pop_back(); - return resolved; -} - -} // namespace +#include std::string NormalizePath(const std::string &path) { - std::optional resolved = RealPathNotExpandSymlink(path); - return resolved ? *resolved : path; + llvm::SmallString<256> P(path); + llvm::sys::path::remove_dots(P, true); + return {P.data(), P.size()}; } void FreeUnusedMemory() { diff --git a/src/symbol.h b/src/symbol.h deleted file mode 100644 index beec82b8b..000000000 --- a/src/symbol.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "lsp.h" -#include "serializer.h" - -// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in -// front of others. -enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; -MAKE_REFLECT_TYPE_PROXY(SymbolKind); - -enum class Role : uint16_t { - None = 0, - Declaration = 1 << 0, - Definition = 1 << 1, - Reference = 1 << 2, - Read = 1 << 3, - Write = 1 << 4, - Call = 1 << 5, - Dynamic = 1 << 6, - Address = 1 << 7, - Implicit = 1 << 8, - All = (1 << 9) - 1, -}; -MAKE_REFLECT_TYPE_PROXY(Role); - -inline uint16_t operator&(Role lhs, Role rhs) { - return uint16_t(lhs) & uint16_t(rhs); -} - -inline Role operator|(Role lhs, Role rhs) { - return Role(uint16_t(lhs) | uint16_t(rhs)); -} - -struct lsSymbolInformation { - std::string_view name; - lsSymbolKind kind; - lsLocation location; - std::optional containerName; -}; -MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); From 119a05597d3ab337c1482724c666c81f60eaf453 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 18 Oct 2018 22:11:43 -0700 Subject: [PATCH 266/378] Improve extent of definition/declaration; uniquify typeDefinition --- src/clang_tu.cc | 47 ++++++++++++--------- src/clang_tu.hh | 5 +++ src/indexer.cc | 13 +++--- src/messages/ccls_navigate.cc | 24 ++++++----- src/messages/textDocument_typeDefinition.cc | 2 + 5 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 5392ee524..c2a69155c 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -40,47 +40,56 @@ std::string PathFromFileEntry(const FileEntry &file) { return ret; } +static Position Decomposed2LineAndCol(const SourceManager &SM, + std::pair I) { + int l = SM.getLineNumber(I.first, I.second) - 1, + c = SM.getColumnNumber(I.first, I.second) - 1; + return {(int16_t)std::min(l, INT16_MAX), (int16_t)std::min(c, INT16_MAX)}; +} + Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts, CharSourceRange R, llvm::sys::fs::UniqueID *UniqueID) { SourceLocation BLoc = R.getBegin(), ELoc = R.getEnd(); - std::pair BInfo = SM.getDecomposedLoc(BLoc); - std::pair EInfo = SM.getDecomposedLoc(ELoc); + std::pair BInfo = SM.getDecomposedLoc(BLoc), + EInfo = SM.getDecomposedLoc(ELoc); if (R.isTokenRange()) EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts); - unsigned l0 = SM.getLineNumber(BInfo.first, BInfo.second) - 1, - c0 = SM.getColumnNumber(BInfo.first, BInfo.second) - 1, - l1 = SM.getLineNumber(EInfo.first, EInfo.second) - 1, - c1 = SM.getColumnNumber(EInfo.first, EInfo.second) - 1; - if (l0 > INT16_MAX) - l0 = 0; - if (c0 > INT16_MAX) - c0 = 0; - if (l1 > INT16_MAX) - l1 = 0; - if (c1 > INT16_MAX) - c1 = 0; if (UniqueID) { if (const FileEntry *F = SM.getFileEntryForID(BInfo.first)) *UniqueID = F->getUniqueID(); else *UniqueID = llvm::sys::fs::UniqueID(0, 0); } - return {{int16_t(l0), int16_t(c0)}, {int16_t(l1), int16_t(c1)}}; + return {Decomposed2LineAndCol(SM, BInfo), Decomposed2LineAndCol(SM, EInfo)}; } -Range FromCharRange(const SourceManager &SM, const LangOptions &LangOpts, +Range FromCharRange(const SourceManager &SM, const LangOptions &Lang, SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { - return FromCharSourceRange(SM, LangOpts, CharSourceRange::getCharRange(R), + return FromCharSourceRange(SM, Lang, CharSourceRange::getCharRange(R), UniqueID); } -Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, +Range FromTokenRange(const SourceManager &SM, const LangOptions &Lang, SourceRange R, llvm::sys::fs::UniqueID *UniqueID) { - return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R), + return FromCharSourceRange(SM, Lang, CharSourceRange::getTokenRange(R), UniqueID); } +Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang, + SourceRange R, const FileEntry *FE, Range range) { + auto I = SM.getDecomposedLoc(SM.getExpansionLoc(R.getBegin())); + if (SM.getFileEntryForID(I.first) == FE) + range.start = Decomposed2LineAndCol(SM, I); + SourceLocation L = SM.getExpansionLoc(R.getEnd()); + I = SM.getDecomposedLoc(L); + if (SM.getFileEntryForID(I.first) == FE) { + I.second += Lexer::MeasureTokenLength(L, SM, Lang); + range.end = Decomposed2LineAndCol(SM, I); + } + return range; +} + std::unique_ptr BuildCompilerInvocation(std::vector args, IntrusiveRefCntPtr VFS) { diff --git a/src/clang_tu.hh b/src/clang_tu.hh index 30d0f464f..78c0d31a0 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -44,6 +44,11 @@ Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); +Range FromTokenRangeDefaulted(const clang::SourceManager &SM, + const clang::LangOptions &Lang, + clang::SourceRange R, const clang::FileEntry *FE, + Range range); + std::unique_ptr BuildCompilerInvocation(std::vector args, llvm::IntrusiveRefCntPtr VFS); diff --git a/src/indexer.cc b/src/indexer.cc index 1b9aaac12..125bb95ca 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -785,19 +785,18 @@ class IndexDataConsumer : public index::IndexDataConsumer { Usr usr = GetUsr(D, &info); auto do_def_decl = [&](auto *entity) { + Use use{{loc, role}, lid}; if (is_def) { SourceRange R = OrigD->getSourceRange(); - entity->def.spell = { - Use{{loc, role}, lid}, - R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc}; + entity->def.spell = {use, + FromTokenRangeDefaulted(SM, Lang, R, FE, loc)}; GetSymbolKind(cast(SemDC), entity->def.parent_kind); } else if (is_decl) { - DeclRef &dr = entity->declarations.emplace_back(); - static_cast(dr) = {{loc, role}, lid}; SourceRange R = OrigD->getSourceRange(); - dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc; + entity->declarations.push_back( + {use, FromTokenRangeDefaulted(SM, Lang, R, FE, loc)}); } else { - entity->uses.push_back({{loc, role}, lid}); + entity->uses.push_back(use); return; } if (entity->def.comments[0] == '\0' && g_config->index.comments) diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index d5468c088..0af052a8a 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -33,6 +33,18 @@ MAKE_REFLECT_STRUCT(In_CclsNavigate::Params, textDocument, position, direction); MAKE_REFLECT_STRUCT(In_CclsNavigate, id, params); REGISTER_IN_MESSAGE(In_CclsNavigate); +Maybe FindParent(QueryFile *file, Position pos) { + Maybe parent; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && + pos < sym.extent.end && + (!parent || (parent->start == sym.extent.start + ? parent->end < sym.extent.end + : parent->start < sym.extent.start))) + parent = sym.extent; + return parent; +} + struct Handler_CclsNavigate : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_CclsNavigate *request) override { @@ -54,11 +66,7 @@ struct Handler_CclsNavigate : BaseMessageHandler { Maybe res; switch (params.direction[0]) { case 'D': { - Maybe parent; - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && - pos < sym.extent.end && (!parent || parent->start < sym.extent.start)) - parent = sym.extent; + Maybe parent = FindParent(file, pos); for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && pos < sym.extent.start && (!parent || sym.extent.end <= parent->end) && @@ -74,11 +82,7 @@ struct Handler_CclsNavigate : BaseMessageHandler { res = sym.extent; break; case 'R': { - Maybe parent; - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && - pos < sym.extent.end && (!parent || parent->start < sym.extent.start)) - parent = sym.extent; + Maybe parent = FindParent(file, pos); if (parent && parent->start.line == pos.line && pos < parent->end) { pos = parent->end; if (pos.column) diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index 3e931d2e4..76a25c49c 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -74,6 +74,8 @@ struct Handler_TextDocumentTypeDefinition } } + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); pipeline::Reply(request->id, result); } }; From ce1c7ec76a0a8df308066daf994e732b8ceaab37 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 19 Oct 2018 10:00:15 -0700 Subject: [PATCH 267/378] Improve DeducedType --- src/indexer.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 125bb95ca..30f103f71 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -565,9 +565,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { T = BD->getType(); binding = true; } - auto BT = GetBaseType(T, false); - if (!BT.isNull() && - (binding || BT.getUnqualifiedType()->getAs())) { + if (!T.isNull() && (binding || T->getContainedDeducedType())) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP = GetDefaultPolicy(); From 283d88727103fb7c60fddc59809435237ca51f47 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 22 Oct 2018 22:01:10 -0700 Subject: [PATCH 268/378] Add command line option -index=root to index without starting language server --- src/main.cc | 26 +++++++++++----- src/messages/initialize.cc | 62 +++++++++++--------------------------- src/pipeline.cc | 33 ++++++++++++++++++++ src/pipeline.hh | 1 + 4 files changed, 70 insertions(+), 52 deletions(-) diff --git a/src/main.cc b/src/main.cc index 7bd175529..74fd89c01 100644 --- a/src/main.cc +++ b/src/main.cc @@ -23,6 +23,7 @@ limitations under the License. #include #include +#include #include #include #include @@ -49,6 +50,9 @@ opt opt_verbose("v", desc("verbosity"), init(0), cat(C)); opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests"), cat(C)); +opt opt_index("index", + desc("standalone mode: index a project and exit"), + value_desc("root"), cat(C)); opt opt_init("init", desc("extra initialization options in JSON"), cat(C)); opt opt_log_file("log-file", desc("log"), value_desc("filename"), @@ -130,14 +134,20 @@ int main(int argc, char **argv) { sys::ChangeStdinToBinary(); sys::ChangeStdoutToBinary(); - // The thread that reads from stdin and dispatchs commands to the main - // thread. - pipeline::LaunchStdin(); - // The thread that writes responses from the main thread to stdout. - pipeline::LaunchStdout(); - // Main thread which also spawns indexer threads upon the "initialize" - // request. - pipeline::MainLoop(); + if (opt_index.size()) { + SmallString<256> Root(opt_index); + sys::fs::make_absolute(Root); + pipeline::Standalone(Root.str()); + } else { + // The thread that reads from stdin and dispatchs commands to the main + // thread. + pipeline::LaunchStdin(); + // The thread that writes responses from the main thread to stdout. + pipeline::LaunchStdout(); + // Main thread which also spawns indexer threads upon the "initialize" + // request. + pipeline::MainLoop(); + } } return 0; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 810ffb852..402a635bf 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -322,25 +322,13 @@ struct lsClientCapabilities { MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); struct lsInitializeParams { - // The process Id of the parent process that started - // the server. Is null if the process has not been started by another process. - // If the parent process is not alive then the server should exit (see exit - // notification) its process. - std::optional processId; - - // The rootPath of the workspace. Is null - // if no folder is open. - // - // @deprecated in favour of rootUri. - std::optional rootPath; - // The rootUri of the workspace. Is null if no // folder is open. If both `rootPath` and `rootUri` are set // `rootUri` wins. std::optional rootUri; // User provided initialization options. - std::optional initializationOptions; + Config initializationOptions; // The capabilities provided by the client (editor or tool) lsClientCapabilities capabilities; @@ -372,33 +360,8 @@ void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { value = lsInitializeParams::lsTrace::Verbose; } -#if 0 // unused -void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) { - switch (value) { - case lsInitializeParams::lsTrace::Off: - writer.String("off"); - break; - case lsInitializeParams::lsTrace::Messages: - writer.String("messages"); - break; - case lsInitializeParams::lsTrace::Verbose: - writer.String("verbose"); - break; - } -} -#endif - -MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, - initializationOptions, capabilities, trace, - workspaceFolders); - -struct lsInitializeError { - // Indicates whether the client should retry to send the - // initilize request after showing the message provided - // in the ResponseError. - bool retry; -}; -MAKE_REFLECT_STRUCT(lsInitializeError, retry); +MAKE_REFLECT_STRUCT(lsInitializeParams, rootUri, initializationOptions, + capabilities, trace, workspaceFolders); struct In_InitializeRequest : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -438,10 +401,7 @@ struct Handler_Initialize : BaseMessageHandler { << params.rootUri->raw_uri; { - if (params.initializationOptions) - g_config = new Config(*params.initializationOptions); - else - g_config = new Config; + g_config = new Config(params.initializationOptions); rapidjson::Document reader; reader.Parse(g_init_options.c_str()); if (!reader.HasParseError()) { @@ -531,3 +491,17 @@ struct Handler_Initialize : BaseMessageHandler { }; REGISTER_MESSAGE_HANDLER(Handler_Initialize); } // namespace + +void StandaloneInitialize(const std::string &root, Project &project, + WorkingFiles &wfiles, VFS &vfs, + IncludeComplete &complete) { + Handler_Initialize handler; + handler.project = &project; + handler.working_files = &wfiles; + handler.vfs = &vfs; + handler.include_complete = &complete; + + In_InitializeRequest request; + request.params.rootUri = lsDocumentUri::FromPath(root); + handler.Run(&request); +} diff --git a/src/pipeline.cc b/src/pipeline.cc index 62fd4d211..ed674646b 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -30,6 +30,7 @@ limitations under the License. #include +#include #include #include using namespace llvm; @@ -42,6 +43,9 @@ using namespace llvm; #include #endif +void StandaloneInitialize(const std::string &, Project &, WorkingFiles &, VFS &, + IncludeComplete &); + void VFS::Clear() { std::lock_guard lock(mutex); state.clear(); @@ -535,6 +539,35 @@ void MainLoop() { } } +void Standalone(const std::string &root) { + Project project; + WorkingFiles wfiles; + VFS vfs; + IncludeComplete complete(&project); + StandaloneInitialize(root, project, wfiles, vfs, complete); + bool tty = sys::Process::StandardOutIsDisplayed(); + + if (tty) { + int entries = 0; + for (auto &[_, folder] : project.root2folder) + entries += folder.entries.size(); + printf("entries: %5d\n", entries); + } + while (1) { + (void)on_indexed->DequeueAll(); + int pending = pending_index_requests; + if (tty) { + printf("\rpending: %5d", pending); + fflush(stdout); + } + if (!pending) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + if (tty) + puts(""); +} + void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id) { pending_index_requests++; diff --git a/src/pipeline.hh b/src/pipeline.hh index e0adc9694..112e8bb9c 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -45,6 +45,7 @@ void LaunchStdout(); void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, WorkingFiles *wfiles); void MainLoop(); +void Standalone(const std::string &root); void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {}); From 32a658ad24226ce085c8f368029a41e8c889ca00 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 23 Oct 2018 09:51:50 -0700 Subject: [PATCH 269/378] Fix textDocument/implementation --- src/messages/ccls_inheritance.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index cfd2203b2..132fad219 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -197,10 +197,17 @@ struct Handler_textDocumentImplementation : BaseMessageHandler { MethodType GetMethodType() const override { return implementation; } void Run(In_textDocumentImplementation *request) override { + Handler_cclsInheritance handler; + handler.db = db; + handler.project = project; + handler.working_files = working_files; + In_cclsInheritance request1; + request1.id = request->id; request1.params.textDocument = request->params.textDocument; request1.params.position = request->params.position; - Handler_cclsInheritance().Run(&request1); + request1.params.derived = true; + handler.Run(&request1); } }; REGISTER_MESSAGE_HANDLER(Handler_textDocumentImplementation); From 16c2e0643b259d891a420f23de9e0353edf37f1e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 23 Oct 2018 10:09:32 -0700 Subject: [PATCH 270/378] Deprioritize completion items with additionTextEdits --- src/messages/textDocument_completion.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index e5a625236..4e83cc8f4 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -227,6 +227,10 @@ void FilterCandidates(lsCompletionList &result, items.end()); std::sort(items.begin(), items.end(), [](const lsCompletionItem &lhs, const lsCompletionItem &rhs) { + int t = int(lhs.additionalTextEdits.size() - + rhs.additionalTextEdits.size()); + if (t) + return t < 0; if (lhs.score_ != rhs.score_) return lhs.score_ > rhs.score_; if (lhs.priority_ != rhs.priority_) From c0c7cfed8d9c6bd6fb278c54ac77593c2620dcf5 Mon Sep 17 00:00:00 2001 From: David F Date: Wed, 24 Oct 2018 05:09:27 +0200 Subject: [PATCH 271/378] Fix broken link in README.md (#101) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a0c70fa5..81d25dc5f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery), is a C/C++/Objective-C language server. * code completion (with both signature help and snippets) - * [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDcument_references.cc), and other cross references + * [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDocument_references.cc), and other cross references * cross reference extensions: `$ccls/call` `$ccls/inheritance` `$ccls/member` `$ccls/vars` ... * formatting * hierarchies: [call (caller/callee) hierarchy](src/messages/ccls_call.cc), [inheritance (base/derived) hierarchy](src/messages/ccls_inheritance.cc), [member hierarchy](src/messages/ccls_member.cc) From 1d67a40ce8939d1ac9d7b2a6ea17398c87ec6829 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 23 Oct 2018 20:48:12 -0700 Subject: [PATCH 272/378] Implement textDocument/foldingRange --- CMakeLists.txt | 1 + src/messages/initialize.cc | 4 +- src/messages/textDocument_foldingRange.cc | 73 +++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/messages/textDocument_foldingRange.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c526d72c..a16583e31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,6 +220,7 @@ target_sources(ccls PRIVATE src/messages/textDocument_completion.cc src/messages/textDocument_definition.cc src/messages/textDocument_did.cc + src/messages/textDocument_foldingRange.cc src/messages/textDocument_formatting.cc src/messages/textDocument_documentHighlight.cc src/messages/textDocument_documentSymbol.cc diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 402a635bf..5ba01c1cd 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -172,6 +172,7 @@ struct lsServerCapabilities { bool renameProvider = true; // The server provides document link support. lsDocumentLinkOptions documentLinkProvider; + bool foldingRangeProvider = true; // The server provides execute command support. struct ExecuteCommandOptions { std::vector commands{std::string(ccls_xref)}; @@ -196,7 +197,8 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, codeLensProvider, documentFormattingProvider, documentRangeFormattingProvider, documentOnTypeFormattingProvider, renameProvider, - documentLinkProvider, executeCommandProvider, workspace); + documentLinkProvider, foldingRangeProvider, + executeCommandProvider, workspace); // Workspace specific client capabilities. struct lsWorkspaceClientCapabilites { diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc new file mode 100644 index 000000000..ea86ba27e --- /dev/null +++ b/src/messages/textDocument_foldingRange.cc @@ -0,0 +1,73 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "message_handler.h" +#include "pipeline.hh" +#include "project.h" +#include "query_utils.h" +#include "working_files.h" + +namespace ccls { +namespace { +MethodType foldingRange = "textDocument/foldingRange"; + +struct In_textDocumentFoldingRange : public RequestMessage { + MethodType GetMethodType() const override { return foldingRange; } + struct Params { + lsTextDocumentIdentifier textDocument; + } params; +}; +MAKE_REFLECT_STRUCT(In_textDocumentFoldingRange::Params, textDocument); +MAKE_REFLECT_STRUCT(In_textDocumentFoldingRange, id, params); +REGISTER_IN_MESSAGE(In_textDocumentFoldingRange); + +struct FoldingRange { + int startLine, startCharacter, endLine, endCharacter; + std::string kind = "region"; +}; +MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, endCharacter, kind); + +struct Handler_textDocumentFoldingRange + : BaseMessageHandler { + MethodType GetMethodType() const override { return foldingRange; } + void Run(In_textDocumentFoldingRange *request) override { + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + request->params.textDocument.uri.GetPath(), &file, + nullptr)) + return; + WorkingFile *wfile = + working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::vector result; + std::optional ls_range; + + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && + (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) && + (ls_range = GetLsRange(wfile, sym.extent))) { + FoldingRange &fold = result.emplace_back(); + fold.startLine = ls_range->start.line; + fold.startCharacter = ls_range->start.character; + fold.endLine = ls_range->end.line; + fold.endCharacter = ls_range->end.character; + } + pipeline::Reply(request->id, result); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_textDocumentFoldingRange); +} // namespace +} // namespace ccls From 6e19a5964e32d83c1b4e0423b257306e842631d8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 24 Oct 2018 18:03:57 -0700 Subject: [PATCH 273/378] Implement textDocument/documentLink --- CMakeLists.txt | 3 +- src/messages/initialize.cc | 25 +--- ...mentSymbol.cc => textDocument_document.cc} | 127 ++++++++++++++++-- .../textDocument_documentHighlight.cc | 91 ------------- 4 files changed, 119 insertions(+), 127 deletions(-) rename src/messages/{textDocument_documentSymbol.cc => textDocument_document.cc} (60%) delete mode 100644 src/messages/textDocument_documentHighlight.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index a16583e31..5c6bdbcdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,8 +222,7 @@ target_sources(ccls PRIVATE src/messages/textDocument_did.cc src/messages/textDocument_foldingRange.cc src/messages/textDocument_formatting.cc - src/messages/textDocument_documentHighlight.cc - src/messages/textDocument_documentSymbol.cc + src/messages/textDocument_document.cc src/messages/textDocument_hover.cc src/messages/textDocument_references.cc src/messages/textDocument_rename.cc diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 5ba01c1cd..c51a86ff3 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -74,12 +74,6 @@ struct lsDocumentOnTypeFormattingOptions { MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); -// Document link options -struct lsDocumentLinkOptions { - // Document links have a resolve provider as well. - bool resolveProvider = false; -}; -MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider); // Save options. struct lsSaveOptions { @@ -144,34 +138,22 @@ struct lsServerCapabilities { lsCompletionOptions completionProvider; // The server provides signature help support. lsSignatureHelpOptions signatureHelpProvider; - // The server provides goto definition support. bool definitionProvider = true; - // The server provides Goto Type Definition support. bool typeDefinitionProvider = true; - // The server provides Goto Implementation support. bool implementationProvider = true; - // The server provides find references support. bool referencesProvider = true; - // The server provides document highlight support. bool documentHighlightProvider = true; - // The server provides document symbol support. bool documentSymbolProvider = true; - // The server provides workspace symbol support. bool workspaceSymbolProvider = true; - // The server provides code actions. bool codeActionProvider = true; - // The server provides code lens. lsCodeLensOptions codeLensProvider; - // The server provides document formatting. bool documentFormattingProvider = true; - // The server provides document range formatting. bool documentRangeFormattingProvider = true; - // The server provides document formatting on typing. lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider; - // The server provides rename support. bool renameProvider = true; - // The server provides document link support. - lsDocumentLinkOptions documentLinkProvider; + struct DocumentLinkOptions { + bool resolveProvider = true; + } documentLinkProvider; bool foldingRangeProvider = true; // The server provides execute command support. struct ExecuteCommandOptions { @@ -184,6 +166,7 @@ struct lsServerCapabilities { } workspaceFolders; } workspace; }; +MAKE_REFLECT_STRUCT(lsServerCapabilities::DocumentLinkOptions, resolveProvider); MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands); MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders, supported, changeNotifications); diff --git a/src/messages/textDocument_documentSymbol.cc b/src/messages/textDocument_document.cc similarity index 60% rename from src/messages/textDocument_documentSymbol.cc rename to src/messages/textDocument_document.cc index f9c9fa12d..7dcf7142d 100644 --- a/src/messages/textDocument_documentSymbol.cc +++ b/src/messages/textDocument_document.cc @@ -16,16 +16,116 @@ limitations under the License. #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; -using namespace clang; + +#include MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); +namespace ccls { namespace { -MethodType kMethodType = "textDocument/documentSymbol"; +MethodType documentHighlight = "textDocument/documentHighlight", + documentLink = "textDocument/documentLink", + documentSymbol = "textDocument/documentSymbol"; + +struct lsDocumentHighlight { + enum Kind { Text = 1, Read = 2, Write = 3 }; + + lsRange range; + int kind = 1; + + // ccls extension + Role role = Role::None; + + bool operator<(const lsDocumentHighlight &o) const { + return !(range == o.range) ? range < o.range : kind < o.kind; + } +}; +MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); + +struct In_TextDocumentDocumentHighlight : public RequestMessage { + MethodType GetMethodType() const override { return documentHighlight; } + lsTextDocumentPositionParams params; +}; +MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params); +REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight); + +struct Handler_TextDocumentDocumentHighlight + : BaseMessageHandler { + MethodType GetMethodType() const override { return documentHighlight; } + void Run(In_TextDocumentDocumentHighlight *request) override { + int file_id; + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + request->params.textDocument.uri.GetPath(), &file, + &file_id)) + return; + + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + std::vector result; + + std::vector syms = + FindSymbolsAtLocation(wfile, file, request->params.position, true); + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0) + continue; + Usr usr = sym.usr; + SymbolKind kind = sym.kind; + if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { + return usr == sym1.usr && kind == sym1.kind; + })) + continue; + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + lsDocumentHighlight highlight; + highlight.range = loc->range; + if (sym.role & Role::Write) + highlight.kind = lsDocumentHighlight::Write; + else if (sym.role & Role::Read) + highlight.kind = lsDocumentHighlight::Read; + else + highlight.kind = lsDocumentHighlight::Text; + highlight.role = sym.role; + result.push_back(highlight); + } + } + std::sort(result.begin(), result.end()); + pipeline::Reply(request->id, result); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); + +struct In_textDocumentDocumentLink : public RequestMessage { + MethodType GetMethodType() const override { return documentLink; } + lsTextDocumentPositionParams params; +}; +MAKE_REFLECT_STRUCT(In_textDocumentDocumentLink, id, params); +REGISTER_IN_MESSAGE(In_textDocumentDocumentLink); + +struct lsDocumentLink { + lsRange range; + lsDocumentUri target; +}; +MAKE_REFLECT_STRUCT(lsDocumentLink, range, target); + +struct Handler_textDocumentDocumentLink + : BaseMessageHandler { + MethodType GetMethodType() const override { return documentLink; } + void Run(In_textDocumentDocumentLink *request) override { + QueryFile *file; + if (!FindFileOrFail(db, project, request->id, + request->params.textDocument.uri.GetPath(), &file)) + return; + + std::vector result; + for (const IndexInclude &include : file->def->includes) + result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}}, + lsDocumentUri::FromPath(include.resolved_path)}); + pipeline::Reply(request->id, result); + } +}; +REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentLink); -struct In_TextDocumentDocumentSymbol : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } +struct In_textDocumentDocumentSymbol : public RequestMessage { + MethodType GetMethodType() const override { return documentSymbol; } struct Params { lsTextDocumentIdentifier textDocument; // false: outline; true: all symbols @@ -35,10 +135,10 @@ struct In_TextDocumentDocumentSymbol : public RequestMessage { int endLine = -1; } params; }; -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol::Params, textDocument, all, +MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol::Params, textDocument, all, startLine, endLine); -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol); +MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol, id, params); +REGISTER_IN_MESSAGE(In_textDocumentDocumentSymbol); struct lsDocumentSymbol { std::string name; @@ -68,10 +168,10 @@ bool Ignore(const QueryVar::Def *def) { return !def || def->is_local(); } -struct Handler_TextDocumentDocumentSymbol - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDocumentSymbol *request) override { +struct Handler_textDocumentDocumentSymbol + : BaseMessageHandler { + MethodType GetMethodType() const override { return documentSymbol; } + void Run(In_textDocumentDocumentSymbol *request) override { auto ¶ms = request->params; QueryFile *file; @@ -192,5 +292,6 @@ struct Handler_TextDocumentDocumentSymbol } } }; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); +REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentSymbol); } // namespace +} // namespace ccls diff --git a/src/messages/textDocument_documentHighlight.cc b/src/messages/textDocument_documentHighlight.cc deleted file mode 100644 index b96deb9c8..000000000 --- a/src/messages/textDocument_documentHighlight.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" - -#include -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/documentHighlight"; - -struct lsDocumentHighlight { - enum Kind { Text = 1, Read = 2, Write = 3 }; - - lsRange range; - int kind = 1; - - // ccls extension - Role role = Role::None; - - bool operator<(const lsDocumentHighlight &o) const { - return !(range == o.range) ? range < o.range : kind < o.kind; - } -}; -MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); - -struct In_TextDocumentDocumentHighlight : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight); - -struct Handler_TextDocumentDocumentHighlight - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDocumentHighlight *request) override { - int file_id; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) - return; - - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - std::vector result; - - std::vector syms = - FindSymbolsAtLocation(wfile, file, request->params.position, true); - for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0) - continue; - Usr usr = sym.usr; - SymbolKind kind = sym.kind; - if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { - return usr == sym1.usr && kind == sym1.kind; - })) - continue; - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { - lsDocumentHighlight highlight; - highlight.range = loc->range; - if (sym.role & Role::Write) - highlight.kind = lsDocumentHighlight::Write; - else if (sym.role & Role::Read) - highlight.kind = lsDocumentHighlight::Read; - else - highlight.kind = lsDocumentHighlight::Text; - highlight.role = sym.role; - result.push_back(highlight); - } - } - std::sort(result.begin(), result.end()); - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); -} // namespace From ea1271a84eb7f764abc1eb00d8ccbb0c3487759a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 28 Oct 2018 10:49:31 -0700 Subject: [PATCH 274/378] Refactor message handler and namespace ccls --- CMakeLists.txt | 9 +- src/clang_complete.cc | 3 +- src/clang_complete.hh | 7 +- src/clang_tu.cc | 2 + src/clang_tu.hh | 2 + src/config.cc | 2 +- src/config.h | 4 +- src/filesystem.cc | 2 +- src/fuzzy_match.cc | 4 +- src/fuzzy_match.h | 2 + src/hierarchy.hh | 4 +- src/include_complete.cc | 7 +- src/include_complete.h | 11 +- src/indexer.cc | 9 +- src/indexer.h | 39 +- src/lsp.cc | 139 +------ src/{lsp.h => lsp.hh} | 100 +----- src/lsp_completion.h | 134 ------- src/main.cc | 6 +- src/match.cc | 7 +- src/match.h | 4 +- src/maybe.h | 2 + src/message_handler.cc | 202 +++++++++-- src/message_handler.h | 83 ----- src/message_handler.hh | 265 ++++++++++++++ src/messages/ccls_call.cc | 166 ++++----- src/messages/ccls_info.cc | 86 ++--- src/messages/ccls_inheritance.cc | 178 ++++----- src/messages/ccls_member.cc | 217 +++++------ src/messages/ccls_navigate.cc | 153 ++++---- src/messages/ccls_reload.cc | 86 ++--- src/messages/ccls_vars.cc | 91 ++--- src/messages/exit.cc | 31 -- src/messages/initialize.cc | 227 ++++++------ src/messages/shutdown.cc | 37 -- src/messages/textDocument_code.cc | 234 ++++++++++++ src/messages/textDocument_codeAction.cc | 83 ----- src/messages/textDocument_codeLens.cc | 231 ------------ src/messages/textDocument_completion.cc | 291 +++++++-------- src/messages/textDocument_definition.cc | 289 ++++++++------- src/messages/textDocument_did.cc | 184 +++------- src/messages/textDocument_document.cc | 379 +++++++++----------- src/messages/textDocument_foldingRange.cc | 74 ++-- src/messages/textDocument_formatting.cc | 161 +++------ src/messages/textDocument_hover.cc | 95 ++--- src/messages/textDocument_references.cc | 202 +++++------ src/messages/textDocument_rename.cc | 67 +--- src/messages/textDocument_signatureHelp.cc | 140 +++----- src/messages/textDocument_typeDefinition.cc | 84 ----- src/messages/workspace.cc | 189 ++++++++++ src/messages/workspace_did.cc | 163 --------- src/messages/workspace_symbol.cc | 139 ------- src/pipeline.cc | 130 ++++--- src/pipeline.hh | 5 +- src/position.cc | 4 +- src/position.h | 27 +- src/project.cc | 5 +- src/{project.h => project.hh} | 4 +- src/query.cc | 5 +- src/query.h | 20 +- src/query_utils.cc | 2 + src/query_utils.h | 2 + src/serializer.cc | 5 +- src/{serializer.h => serializer.hh} | 6 +- src/serializers/binary.h | 4 +- src/serializers/json.h | 4 +- src/test.cc | 4 +- src/test.h | 2 + src/threaded_queue.h | 12 +- src/utils.cc | 2 + src/utils.h | 4 +- src/working_files.cc | 6 +- src/working_files.h | 6 +- 73 files changed, 2409 insertions(+), 3176 deletions(-) rename src/{lsp.h => lsp.hh} (75%) delete mode 100644 src/lsp_completion.h delete mode 100644 src/message_handler.h create mode 100644 src/message_handler.hh delete mode 100644 src/messages/exit.cc delete mode 100644 src/messages/shutdown.cc create mode 100644 src/messages/textDocument_code.cc delete mode 100644 src/messages/textDocument_codeAction.cc delete mode 100644 src/messages/textDocument_codeLens.cc delete mode 100644 src/messages/textDocument_typeDefinition.cc create mode 100644 src/messages/workspace.cc delete mode 100644 src/messages/workspace_did.cc delete mode 100644 src/messages/workspace_symbol.cc rename src/{project.h => project.hh} (97%) rename src/{serializer.h => serializer.hh} (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c6bdbcdb..abe0e04b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,11 +212,8 @@ target_sources(ccls PRIVATE src/messages/ccls_navigate.cc src/messages/ccls_reload.cc src/messages/ccls_vars.cc - src/messages/exit.cc src/messages/initialize.cc - src/messages/shutdown.cc - src/messages/textDocument_codeAction.cc - src/messages/textDocument_codeLens.cc + src/messages/textDocument_code.cc src/messages/textDocument_completion.cc src/messages/textDocument_definition.cc src/messages/textDocument_did.cc @@ -227,7 +224,5 @@ target_sources(ccls PRIVATE src/messages/textDocument_references.cc src/messages/textDocument_rename.cc src/messages/textDocument_signatureHelp.cc - src/messages/textDocument_typeDefinition.cc - src/messages/workspace_did.cc - src/messages/workspace_symbol.cc + src/messages/workspace.cc ) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f689d48a4..615162b35 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -574,8 +574,6 @@ std::shared_ptr CompletionSession::GetPreamble() { return preamble; } -} // namespace ccls - CompletionManager::CompletionManager(Project *project, WorkingFiles *working_files, OnDiagnostic on_diagnostic, @@ -685,3 +683,4 @@ void CompletionManager::FlushAllSessions() { preloads.Clear(); sessions.Clear(); } +} // namespace ccls diff --git a/src/clang_complete.hh b/src/clang_complete.hh index e18d1ad8f..3c5145f80 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -17,9 +17,8 @@ limitations under the License. #include "clang_tu.hh" #include "lru_cache.h" -#include "lsp.h" -#include "lsp_completion.h" -#include "project.h" +#include "lsp.hh" +#include "project.hh" #include "threaded_queue.h" #include "working_files.h" @@ -73,7 +72,6 @@ struct CompletionSession std::shared_ptr GetPreamble(); }; -} struct CompletionManager { using OnDiagnostic = std::functionpath == path && this->position == position; } }; +} // namespace ccls diff --git a/src/clang_tu.cc b/src/clang_tu.cc index c2a69155c..2a9b05504 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -24,6 +24,7 @@ limitations under the License. using namespace clang; +namespace ccls { std::string PathFromFileEntry(const FileEntry &file) { StringRef Name = file.tryGetRealPathName(); if (Name.empty()) @@ -253,3 +254,4 @@ const char *ClangBuiltinTypeName(int kind) { return ""; } } +} // namespace ccls diff --git a/src/clang_tu.hh b/src/clang_tu.hh index 78c0d31a0..d88c836e1 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -29,6 +29,7 @@ namespace vfs = clang::vfs; } #endif +namespace ccls { std::string PathFromFileEntry(const clang::FileEntry &file); Range FromCharSourceRange(const clang::SourceManager &SM, @@ -54,3 +55,4 @@ BuildCompilerInvocation(std::vector args, llvm::IntrusiveRefCntPtr VFS); const char *ClangBuiltinTypeName(int); +} // namespace ccls diff --git a/src/config.cc b/src/config.cc index 0d4b9039d..489c87819 100644 --- a/src/config.cc +++ b/src/config.cc @@ -15,9 +15,9 @@ limitations under the License. #include "config.h" +namespace ccls { Config *g_config; -namespace ccls { void DoPathMapping(std::string &arg) { for (const std::string &mapping : g_config->clang.pathMappings) { auto colon = mapping.find(':'); diff --git a/src/config.h b/src/config.h index b358cb673..26574d150 100644 --- a/src/config.h +++ b/src/config.h @@ -15,10 +15,11 @@ limitations under the License. #pragma once -#include "serializer.h" +#include "serializer.hh" #include +namespace ccls { /* The language client plugin needs to send initialization options in the `initialize` request to the ccls language server. @@ -281,6 +282,5 @@ MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, extern Config *g_config; -namespace ccls { void DoPathMapping(std::string &arg); } diff --git a/src/filesystem.cc b/src/filesystem.cc index 613666ade..d2cd1b3ca 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -23,7 +23,7 @@ using namespace llvm; void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix, const std::function &handler) { - EnsureEndsInSlash(folder); + ccls::EnsureEndsInSlash(folder); sys::fs::file_status Status; if (sys::fs::status(folder, Status, true)) return; diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 577f62238..62a8d24f4 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -20,10 +20,11 @@ limitations under the License. #include #include +namespace ccls { +namespace { enum CharClass { Other, Lower, Upper }; enum CharRole { None, Tail, Head }; -namespace { CharClass GetCharClass(int c) { if (islower(c)) return Lower; @@ -145,6 +146,7 @@ int FuzzyMatcher::Match(std::string_view text) { ret = std::max(ret, dp[pat.size() & 1][j][1] - 2 * (n - j)); return ret; } +} // namespace ccls #if 0 TEST_SUITE("fuzzy_match") { diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index 1773775da..9153c6c01 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -19,6 +19,7 @@ limitations under the License. #include #include +namespace ccls { class FuzzyMatcher { public: constexpr static int kMaxPat = 100; @@ -42,3 +43,4 @@ class FuzzyMatcher { int MatchScore(int i, int j, bool last); int MissScore(int j, bool last); }; +} // namespace ccls diff --git a/src/hierarchy.hh b/src/hierarchy.hh index 8d997ef1a..b68a763ba 100644 --- a/src/hierarchy.hh +++ b/src/hierarchy.hh @@ -15,11 +15,12 @@ limitations under the License. #pragma once -#include "lsp.h" +#include "lsp.hh" #include #include +namespace ccls { template std::vector FlattenHierarchy(const std::optional &root) { if (!root) @@ -40,3 +41,4 @@ std::vector FlattenHierarchy(const std::optional &root) { ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); return ret; } +} // namespace ccls diff --git a/src/include_complete.cc b/src/include_complete.cc index 72931c313..b17756648 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -18,15 +18,18 @@ limitations under the License. #include "filesystem.hh" #include "match.h" #include "platform.h" -#include "project.h" +#include "project.hh" #include #include #include + +#include using namespace llvm; #include +namespace ccls { namespace { struct CompletionCandidate { @@ -95,7 +98,6 @@ lsCompletionItem BuildCompletionItem(const std::string &path, item.priority_ = 0; return item; } - } // namespace IncludeComplete::IncludeComplete(Project *project) @@ -210,3 +212,4 @@ IncludeComplete::FindCompletionItemForAbsolutePath( return std::nullopt; return completion_items[it->second]; } +} // namespace ccls diff --git a/src/include_complete.h b/src/include_complete.h index c161388d1..818ed4401 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -15,12 +15,12 @@ limitations under the License. #pragma once -#include "lsp_completion.h" +#include "message_handler.hh" #include #include -#include +namespace ccls { struct GroupMatch; struct Project; @@ -38,18 +38,18 @@ struct IncludeComplete { void InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets); - std::optional + std::optional FindCompletionItemForAbsolutePath(const std::string &absolute_path); // Insert item to |completion_items|. // Update |absolute_path_to_completion_item| and |inserted_paths|. void InsertCompletionItem(const std::string &absolute_path, - lsCompletionItem &&item); + ccls::lsCompletionItem &&item); // Guards |completion_items| when |is_scanning| is true. std::mutex completion_items_mutex; std::atomic is_scanning; - std::vector completion_items; + std::vector completion_items; // Absolute file path to the completion item in |completion_items|. // Keep the one with shortest include path. @@ -62,3 +62,4 @@ struct IncludeComplete { Project *project_; std::unique_ptr match_; }; +} // namespace ccls diff --git a/src/indexer.cc b/src/indexer.cc index 30f103f71..96137b2ad 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -21,7 +21,7 @@ limitations under the License. #include "match.h" #include "pipeline.hh" #include "platform.h" -#include "serializer.h" +#include "serializer.hh" #include #include @@ -38,9 +38,9 @@ limitations under the License. #include #include -using namespace ccls; using namespace clang; +namespace ccls { namespace { constexpr int kInitializerMaxLines = 3; @@ -1209,7 +1209,7 @@ template void Uniquify(std::vector &a) { a.resize(n); } -namespace ccls::idx { +namespace idx { void Init() { multiVersionMatcher = new GroupMatch(g_config->index.multiVersionWhitelist, g_config->index.multiVersionBlacklist); @@ -1358,7 +1358,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, return result; } -} // namespace ccls::idx +} // namespace idx void Reflect(Reader &vis, SymbolRef &v) { if (vis.Format() == SerializeFormat::Json) { @@ -1446,3 +1446,4 @@ void Reflect(Writer &vis, DeclRef &v) { Reflect(vis, v.extent); } } +} // namespace ccls diff --git a/src/indexer.h b/src/indexer.h index 1c4051096..488eb9c09 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -15,10 +15,10 @@ limitations under the License. #pragma once -#include "lsp.h" +#include "lsp.hh" #include "maybe.h" #include "position.h" -#include "serializer.h" +#include "serializer.hh" #include "utils.h" #include @@ -31,6 +31,17 @@ limitations under the License. #include #include +namespace std { +template <> struct hash { + std::size_t operator()(llvm::sys::fs::UniqueID ID) const { + size_t ret = ID.getDevice(); + ccls::hash_combine(ret, ID.getFile()); + return ret; + } +}; +} // namespace std + +namespace ccls { using Usr = uint64_t; enum class LanguageId; @@ -60,7 +71,6 @@ struct SymbolRef { bool operator==(const SymbolRef &o) const { return ToTuple() == o.ToTuple(); } bool Valid() const { return range.Valid(); } }; -MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role); struct ExtentRef : SymbolRef { Range extent; @@ -69,7 +79,6 @@ struct ExtentRef : SymbolRef { } bool operator==(const ExtentRef &o) const { return ToTuple() == o.ToTuple(); } }; -MAKE_HASHABLE(ExtentRef, t.range, t.usr, t.kind, t.role, t.extent); struct Ref { Range range; @@ -93,12 +102,10 @@ struct Use : Ref { return range == o.range && file_id == o.file_id; } }; -MAKE_HASHABLE(Use, t.range, t.file_id) struct DeclRef : Use { Range extent; }; -MAKE_HASHABLE(DeclRef, t.range, t.file_id) void Reflect(Reader &visitor, SymbolRef &value); void Reflect(Writer &visitor, SymbolRef &value); @@ -245,16 +252,6 @@ struct IndexInclude { const char *resolved_path; }; -namespace std { -template <> struct hash { - std::size_t operator()(llvm::sys::fs::UniqueID ID) const { - size_t ret = ID.getDevice(); - hash_combine(ret, ID.getFile()); - return ret; - } -}; -} // namespace std - struct IndexFile { // For both JSON and MessagePack cache files. static const int kMajorVersion; @@ -308,7 +305,7 @@ struct CompletionManager; struct WorkingFiles; struct VFS; -namespace ccls::idx { +namespace idx { void Init(); std::vector> Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, @@ -316,4 +313,10 @@ Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::vector &args, const std::vector> &remapped, bool &ok); -} // namespace ccls::idx +} // namespace idx +} // namespace ccls + +MAKE_HASHABLE(ccls::SymbolRef, t.range, t.usr, t.kind, t.role); +MAKE_HASHABLE(ccls::ExtentRef, t.range, t.usr, t.kind, t.role, t.extent); +MAKE_HASHABLE(ccls::Use, t.range, t.file_id) +MAKE_HASHABLE(ccls::DeclRef, t.range, t.file_id) diff --git a/src/lsp.cc b/src/lsp.cc index cce5b00b3..6a55f1ae2 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -13,17 +13,14 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "lsp.h" +#include "lsp.hh" #include "log.hh" #include "serializers/json.h" -#include - #include -MethodType kMethodType_Exit = "exit"; - +namespace ccls { void Reflect(Reader &visitor, lsRequestId &value) { if (visitor.IsInt64()) { value.type = lsRequestId::kInt; @@ -55,10 +52,6 @@ void Reflect(Writer &visitor, lsRequestId &value) { } } -InMessage::~InMessage() {} - -MessageRegistry *MessageRegistry::instance_ = nullptr; - lsTextDocumentIdentifier lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { lsTextDocumentIdentifier result; @@ -66,120 +59,6 @@ lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { return result; } -// Reads a JsonRpc message. |read| returns the next input character. -std::optional -ReadJsonRpcContentFrom(std::function()> read) { - // Read the content length. It is terminated by the "\r\n" sequence. - int exit_seq = 0; - std::string stringified_content_length; - while (true) { - std::optional opt_c = read(); - if (!opt_c) { - LOG_S(INFO) << "No more input when reading content length header"; - return std::nullopt; - } - char c = *opt_c; - - if (exit_seq == 0 && c == '\r') - ++exit_seq; - if (exit_seq == 1 && c == '\n') - break; - - stringified_content_length += c; - } - const char *kContentLengthStart = "Content-Length: "; - assert(StartsWith(stringified_content_length, kContentLengthStart)); - int content_length = - atoi(stringified_content_length.c_str() + strlen(kContentLengthStart)); - - // There is always a "\r\n" sequence before the actual content. - auto expect_char = [&](char expected) { - std::optional opt_c = read(); - return opt_c && *opt_c == expected; - }; - if (!expect_char('\r') || !expect_char('\n')) { - LOG_S(INFO) << "Unexpected token (expected \\r\\n sequence)"; - return std::nullopt; - } - - // Read content. - std::string content; - content.reserve(content_length); - for (int i = 0; i < content_length; ++i) { - std::optional c = read(); - if (!c) { - LOG_S(INFO) << "No more input when reading content body"; - return std::nullopt; - } - content += *c; - } - - return content; -} - -std::optional ReadCharFromStdinBlocking() { - // We do not use std::cin because it does not read bytes once stuck in - // cin.bad(). We can call cin.clear() but C++ iostream has other annoyance - // like std::{cin,cout} is tied by default, which causes undesired cout flush - // for cin operations. - int c = getchar(); - if (c >= 0) - return c; - return std::nullopt; -} - -std::optional -MessageRegistry::ReadMessageFromStdin(std::unique_ptr *message) { - std::optional content = - ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking); - if (!content) { - LOG_S(ERROR) << "Failed to read JsonRpc input; exiting"; - exit(1); - } - - rapidjson::Document document; - document.Parse(content->c_str(), content->length()); - assert(!document.HasParseError()); - - JsonReader json_reader{&document}; - return Parse(json_reader, message); -} - -std::optional -MessageRegistry::Parse(Reader &visitor, std::unique_ptr *message) { - if (!visitor.HasMember("jsonrpc") || - std::string(visitor["jsonrpc"]->GetString()) != "2.0") { - LOG_S(FATAL) << "Bad or missing jsonrpc version"; - exit(1); - } - - std::string method; - ReflectMember(visitor, "method", method); - - if (allocators.find(method) == allocators.end()) - return std::string("Unable to find registered handler for method '") + - method + "'"; - - Allocator &allocator = allocators[method]; - try { - allocator(visitor, message); - return std::nullopt; - } catch (std::invalid_argument &e) { - // *message is partially deserialized but some field (e.g. |id|) are likely - // available. - return std::string("Fail to parse '") + method + "' " + - static_cast(visitor).GetPath() + ", expected " + - e.what(); - } -} - -MessageRegistry *MessageRegistry::instance() { - if (!instance_) - instance_ = new MessageRegistry(); - - return instance_; -} - lsDocumentUri lsDocumentUri::FromPath(const std::string &path) { lsDocumentUri result; result.SetPath(path); @@ -271,16 +150,4 @@ std::string lsPosition::ToString() const { bool lsTextEdit::operator==(const lsTextEdit &that) { return range == that.range && newText == that.newText; } - -void Reflect(Writer &visitor, lsMarkedString &value) { - // If there is a language, emit a `{language:string, value:string}` object. If - // not, emit a string. - if (value.language) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(language); - REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); - } else { - Reflect(visitor, value.value); - } -} +} // namespace ccls diff --git a/src/lsp.h b/src/lsp.hh similarity index 75% rename from src/lsp.h rename to src/lsp.hh index b8b3e7ca2..c95607775 100644 --- a/src/lsp.h +++ b/src/lsp.hh @@ -16,15 +16,15 @@ limitations under the License. #pragma once #include "config.h" -#include "serializer.h" +#include "serializer.hh" #include "utils.h" +#include + #include #include -using MethodType = const char *; -extern MethodType kMethodType_Exit; - +namespace ccls { struct lsRequestId { // The client can send the request id as an int or a string. We should output // the same format we received. @@ -39,47 +39,10 @@ void Reflect(Reader &visitor, lsRequestId &value); void Reflect(Writer &visitor, lsRequestId &value); struct InMessage { - virtual ~InMessage(); - - virtual MethodType GetMethodType() const = 0; - virtual lsRequestId GetRequestId() const { return {}; } -}; - -struct NotificationMessage : InMessage {}; - -struct RequestMessage : public InMessage { lsRequestId id; - lsRequestId GetRequestId() const override { return id; } -}; - -#define REGISTER_IN_MESSAGE(type) \ - static MessageRegistryRegister type##message_handler_instance_; - -struct MessageRegistry { - static MessageRegistry *instance_; - static MessageRegistry *instance(); - - using Allocator = - std::function *)>; - std::unordered_map allocators; - - std::optional - ReadMessageFromStdin(std::unique_ptr *message); - std::optional Parse(Reader &visitor, - std::unique_ptr *message); -}; - -template struct MessageRegistryRegister { - MessageRegistryRegister() { - T dummy; - std::string method_name = dummy.GetMethodType(); - MessageRegistry::instance()->allocators[method_name] = - [](Reader &visitor, std::unique_ptr *message) { - *message = std::make_unique(); - // Reflect may throw and *message will be partially deserialized. - Reflect(visitor, static_cast(**message)); - }; - } + std::string method; + std::unique_ptr message; + std::unique_ptr document; }; enum class lsErrorCodes { @@ -226,7 +189,6 @@ struct lsSymbolInformation { lsLocation location; std::optional containerName; }; -MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); struct lsTextDocumentIdentifier { lsDocumentUri uri; @@ -242,15 +204,6 @@ struct lsVersionedTextDocumentIdentifier { }; MAKE_REFLECT_STRUCT(lsVersionedTextDocumentIdentifier, uri, version); -struct lsTextDocumentPositionParams { - // The text document. - lsTextDocumentIdentifier textDocument; - - // The position inside the text document. - lsPosition position; -}; -MAKE_REFLECT_STRUCT(lsTextDocumentPositionParams, textDocument, position); - struct lsTextEdit { // The range of the text document to be manipulated. To insert // text into a document create a range where start === end. @@ -301,26 +254,7 @@ struct lsWorkspaceEdit { }; MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges); -// MarkedString can be used to render human readable text. It is either a -// markdown string or a code-block that provides a language and a code snippet. -// The language identifier is sematically equal to the std::optional language -// identifier in fenced code blocks in GitHub issues. See -// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting -// -// The pair of a language and a value is an equivalent to markdown: -// ```${language} -// ${value} -// ``` -// -// Note that markdown strings will be sanitized - that means html will be -// escaped. -struct lsMarkedString { - std::optional language; - std::string value; -}; -void Reflect(Writer &visitor, lsMarkedString &value); - -struct lsTextDocumentContentChangeEvent { +struct TextDocumentContentChangeEvent { // The range of the document that changed. std::optional range; // The length of the range that got replaced. @@ -328,24 +262,21 @@ struct lsTextDocumentContentChangeEvent { // The new text of the range/document. std::string text; }; -MAKE_REFLECT_STRUCT(lsTextDocumentContentChangeEvent, range, rangeLength, text); -struct lsTextDocumentDidChangeParams { +struct TextDocumentDidChangeParam { lsVersionedTextDocumentIdentifier textDocument; - std::vector contentChanges; + std::vector contentChanges; }; -MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, textDocument, - contentChanges); -struct lsWorkspaceFolder { +struct WorkspaceFolder { lsDocumentUri uri; std::string name; }; -MAKE_REFLECT_STRUCT(lsWorkspaceFolder, uri, name); +MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); // Show a message to the user. -enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; -MAKE_REFLECT_TYPE_PROXY(lsMessageType) +enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; +MAKE_REFLECT_TYPE_PROXY(MessageType) enum class lsDiagnosticSeverity { // Reports an error. @@ -392,7 +323,7 @@ struct lsPublishDiagnosticsParams { MAKE_REFLECT_STRUCT(lsPublishDiagnosticsParams, uri, diagnostics); struct lsShowMessageParams { - lsMessageType type = lsMessageType::Error; + MessageType type = MessageType::Error; std::string message; }; MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message); @@ -430,3 +361,4 @@ inline uint16_t operator&(Role lhs, Role rhs) { inline Role operator|(Role lhs, Role rhs) { return Role(uint16_t(lhs) | uint16_t(rhs)); } +} // namespace ccls diff --git a/src/lsp_completion.h b/src/lsp_completion.h deleted file mode 100644 index 0963afd31..000000000 --- a/src/lsp_completion.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once -#include "lsp.h" - -// The kind of a completion entry. -enum class lsCompletionItemKind { - Text = 1, - Method = 2, - Function = 3, - Constructor = 4, - Field = 5, - Variable = 6, - Class = 7, - Interface = 8, - Module = 9, - Property = 10, - Unit = 11, - Value = 12, - Enum = 13, - Keyword = 14, - Snippet = 15, - Color = 16, - File = 17, - Reference = 18, - Folder = 19, - EnumMember = 20, - Constant = 21, - Struct = 22, - Event = 23, - Operator = 24, - TypeParameter = 25, -}; -MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind); - -// Defines whether the insert text in a completion item should be interpreted as -// plain text or a snippet. -enum class lsInsertTextFormat { - // The primary text to be inserted is treated as a plain string. - PlainText = 1, - - // The primary text to be inserted is treated as a snippet. - // - // A snippet can define tab stops and placeholders with `$1`, `$2` - // and `${3:foo}`. `$0` defines the final tab stop, it defaults to - // the end of the snippet. Placeholders with equal identifiers are linked, - // that is typing in one will update others too. - // - // See also: - // https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md - Snippet = 2 -}; -MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat); - -struct lsCompletionItem { - // A set of function parameters. Used internally for signature help. Not sent - // to vscode. - std::vector parameters_; - - // The label of this completion item. By default - // also the text that is inserted when selecting - // this completion. - std::string label; - - // The kind of this completion item. Based of the kind - // an icon is chosen by the editor. - lsCompletionItemKind kind = lsCompletionItemKind::Text; - - // A human-readable string with additional information - // about this item, like type or symbol information. - std::string detail; - - // A human-readable string that represents a doc-comment. - std::optional documentation; - - // Internal information to order candidates. - int score_; - unsigned priority_; - - // Use <> or "" by default as include path. - bool use_angle_brackets_ = false; - - // A string that shoud be used when comparing this item - // with other items. When `falsy` the label is used. - std::string sortText; - - // A string that should be used when filtering a set of - // completion items. When `falsy` the label is used. - std::optional filterText; - - // A string that should be inserted a document when selecting - // this completion. When `falsy` the label is used. - std::string insertText; - - // The format of the insert text. The format applies to both the `insertText` - // property and the `newText` property of a provided `textEdit`. - lsInsertTextFormat insertTextFormat = lsInsertTextFormat::PlainText; - - // An edit which is applied to a document when selecting this completion. When - // an edit is provided the value of `insertText` is ignored. - // - // *Note:* The range of the edit must be a single line range and it must - // contain the position at which completion has been requested. - lsTextEdit textEdit; - - // An std::optional array of additional text edits that are applied when - // selecting this completion. Edits must not overlap with the main edit - // nor with themselves. - std::vector additionalTextEdits; - - // An std::optional command that is executed *after* inserting this - // completion. *Note* that additional modifications to the current document - // should be described with the additionalTextEdits-property. Command command; - - // An data entry field that is preserved on a completion item between - // a completion and a completion resolve request. - // data ? : any -}; -MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation, - sortText, filterText, insertText, insertTextFormat, - textEdit, additionalTextEdits); diff --git a/src/main.cc b/src/main.cc index 74fd89c01..8b728fbee 100644 --- a/src/main.cc +++ b/src/main.cc @@ -16,7 +16,7 @@ limitations under the License. #include "log.hh" #include "pipeline.hh" #include "platform.h" -#include "serializer.h" +#include "serializer.hh" #include "serializers/json.h" #include "test.h" #include "working_files.h" @@ -40,7 +40,9 @@ using namespace ccls; using namespace llvm; using namespace llvm::cl; +namespace ccls { std::string g_init_options; +} namespace { OptionCategory C("ccls options"); @@ -104,7 +106,7 @@ int main(int argc, char **argv) { if (opt_test_index != "!") { language_server = false; - if (!RunIndexTests(opt_test_index, sys::Process::StandardInIsUserInput())) + if (!ccls::RunIndexTests(opt_test_index, sys::Process::StandardInIsUserInput())) return 1; } diff --git a/src/match.cc b/src/match.cc index 1ecdff284..ad83396c0 100644 --- a/src/match.cc +++ b/src/match.cc @@ -15,10 +15,10 @@ limitations under the License. #include "match.h" -#include "lsp.h" +#include "lsp.hh" #include "pipeline.hh" -using namespace ccls; +namespace ccls { std::optional Matcher::Create(const std::string &search) { try { Matcher m; @@ -31,7 +31,7 @@ std::optional Matcher::Create(const std::string &search) { return m; } catch (const std::exception &e) { lsShowMessageParams params; - params.type = lsMessageType::Error; + params.type = MessageType::Error; params.message = "failed to parse EMCAScript regex " + search + " : " + e.what(); pipeline::Notify(window_showMessage, params); @@ -74,3 +74,4 @@ bool GroupMatch::IsMatch(const std::string &value, return true; } +} // namespace ccls diff --git a/src/match.h b/src/match.h index b9114768d..f5ebb976f 100644 --- a/src/match.h +++ b/src/match.h @@ -21,6 +21,7 @@ limitations under the License. #include #include +namespace ccls { struct Matcher { static std::optional Create(const std::string &search); @@ -40,4 +41,5 @@ struct GroupMatch { std::vector whitelist; std::vector blacklist; -}; \ No newline at end of file +}; +} // namespace ccls diff --git a/src/maybe.h b/src/maybe.h index ce20eadd1..e62f27924 100644 --- a/src/maybe.h +++ b/src/maybe.h @@ -19,6 +19,7 @@ limitations under the License. #include +namespace ccls { // Like std::optional, but the stored data is responsible for containing the // empty state. T should define a function `bool T::Valid()`. template class Maybe { @@ -56,3 +57,4 @@ template class Maybe { bool operator==(const Maybe &o) const { return storage == o.storage; } bool operator!=(const Maybe &o) const { return !(*this == o); } }; +} // namespace ccls diff --git a/src/message_handler.cc b/src/message_handler.cc index 088099c27..b4b61a217 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -13,23 +13,55 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "log.hh" #include "match.h" #include "pipeline.hh" -#include "project.h" +#include "project.hh" #include "query_utils.h" -using namespace ccls; +#include "serializers/json.h" using namespace clang; #include -MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); +MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); -namespace { +namespace ccls { +MAKE_REFLECT_STRUCT(EmptyParam, placeholder); +MAKE_REFLECT_STRUCT(TextDocumentParam, textDocument); +MAKE_REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument); +MAKE_REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text); +MAKE_REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges); +MAKE_REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position); +MAKE_REFLECT_STRUCT(RenameParam, textDocument, position, newName); + +// code* +MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); +MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); + +// completion +MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind); +MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter); +MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); + +// formatting +MAKE_REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces); +MAKE_REFLECT_STRUCT(DocumentFormattingParam, textDocument, options); +MAKE_REFLECT_STRUCT(DocumentOnTypeFormattingParam, textDocument, position, + ch, options); +MAKE_REFLECT_STRUCT(DocumentRangeFormattingParam, textDocument, range, options); +// workspace +MAKE_REFLECT_TYPE_PROXY(FileChangeType); +MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type); +MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam, changes); +MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed); +MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event); +MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query); + +namespace { struct CclsSemanticHighlightSymbol { int id = 0; lsSymbolKind parentKind; @@ -55,6 +87,7 @@ struct CclsSetSkippedRangesParams { }; MAKE_REFLECT_STRUCT(CclsSetSkippedRangesParams, uri, skippedRanges); + struct ScanLineEvent { lsPosition pos; lsPosition end_pos; // Second key when there is a tie for insertion events. @@ -73,55 +106,161 @@ struct ScanLineEvent { }; } // namespace -MessageHandler::MessageHandler() { - // Dynamically allocate |message_handlers|, otherwise there will be static - // initialization order races. - if (!message_handlers) - message_handlers = new std::vector(); - message_handlers->push_back(this); +void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Reader &)) { + method2notification[method] = [this, handler](Reader &reader) { + (this->*handler)(reader); + }; +} + +template +void MessageHandler::Bind(const char *method, + void (MessageHandler::*handler)(Param &)) { + method2notification[method] = [this, handler](Reader &reader) { + Param param{}; + Reflect(reader, param); + (this->*handler)(param); + }; } -std::vector *MessageHandler::message_handlers = nullptr; +void MessageHandler::Bind(const char *method, + void (MessageHandler::*handler)(Reader &, + ReplyOnce &)) { + method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) { + (this->*handler)(reader, reply); + }; +} -bool FindFileOrFail(DB *db, Project *project, std::optional id, - const std::string &absolute_path, - QueryFile **out_query_file, int *out_file_id) { - *out_query_file = nullptr; +template +void MessageHandler::Bind(const char *method, + void (MessageHandler::*handler)(Param &, + ReplyOnce &)) { + method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) { + Param param{}; + Reflect(reader, param); + (this->*handler)(param, reply); + }; +} - auto it = db->name2file_id.find(LowerPathIfInsensitive(absolute_path)); +MessageHandler::MessageHandler() { + Bind("$ccls/call", &MessageHandler::ccls_call); + Bind("$ccls/fileInfo", &MessageHandler::ccls_fileInfo); + Bind("$ccls/info", &MessageHandler::ccls_info); + Bind("$ccls/inheritance", &MessageHandler::ccls_inheritance); + Bind("$ccls/member", &MessageHandler::ccls_member); + Bind("$ccls/navigate", &MessageHandler::ccls_navigate); + Bind("$ccls/reload", &MessageHandler::ccls_reload); + Bind("$ccls/vars", &MessageHandler::ccls_vars); + Bind("exit", &MessageHandler::exit); + Bind("initialize", &MessageHandler::initialize); + Bind("shutdown", &MessageHandler::shutdown); + Bind("textDocument/codeAction", &MessageHandler::textDocument_codeAction); + Bind("textDocument/codeLens", &MessageHandler::textDocument_codeLens); + Bind("textDocument/completion", &MessageHandler::textDocument_completion); + Bind("textDocument/definition", &MessageHandler::textDocument_definition); + Bind("textDocument/didChange", &MessageHandler::textDocument_didChange); + Bind("textDocument/didClose", &MessageHandler::textDocument_didClose); + Bind("textDocument/didOpen", &MessageHandler::textDocument_didOpen); + Bind("textDocument/didSave", &MessageHandler::textDocument_didSave); + Bind("textDocument/documentHighlight", + &MessageHandler::textDocument_documentHighlight); + Bind("textDocument/documentLink", &MessageHandler::textDocument_documentLink); + Bind("textDocument/documentSymbol", + &MessageHandler::textDocument_documentSymbol); + Bind("textDocument/foldingRange", &MessageHandler::textDocument_foldingRange); + Bind("textDocument/formatting", &MessageHandler::textDocument_formatting); + Bind("textDocument/hover", &MessageHandler::textDocument_hover); + Bind("textDocument/implementation", + &MessageHandler::textDocument_implementation); + Bind("textDocument/onTypeFormatting", + &MessageHandler::textDocument_onTypeFormatting); + Bind("textDocument/rangeFormatting", + &MessageHandler::textDocument_rangeFormatting); + Bind("textDocument/references", &MessageHandler::textDocument_references); + Bind("textDocument/rename", &MessageHandler::textDocument_rename); + Bind("textDocument/signatureHelp", + &MessageHandler::textDocument_signatureHelp); + Bind("textDocument/typeDefinition", + &MessageHandler::textDocument_typeDefinition); + Bind("workspace/didChangeConfiguration", + &MessageHandler::workspace_didChangeConfiguration); + Bind("workspace/didChangeWatchedFiles", + &MessageHandler::workspace_didChangeWatchedFiles); + Bind("workspace/didChangeWorkspaceFolders", + &MessageHandler::workspace_didChangeWorkspaceFolders); + Bind("workspace/executeCommand", &MessageHandler::workspace_executeCommand); + Bind("workspace/symbol", &MessageHandler::workspace_symbol); +} + +void MessageHandler::Run(InMessage &msg) { + rapidjson::Document &doc = *msg.document; + rapidjson::Value param; + auto it = doc.FindMember("params"); + if (it != doc.MemberEnd()) + param = it->value; + JsonReader reader(¶m); + if (msg.id.Valid()) { + ReplyOnce reply{msg.id}; + auto it = method2request.find(msg.method); + if (it != method2request.end()) { + try { + it->second(reader, reply); + } catch (...) { + LOG_S(ERROR) << "failed to process request " << msg.method; + } + } else { + lsResponseError err; + err.code = lsErrorCodes::MethodNotFound; + err.message = "unknown request " + msg.method; + reply.Error(err); + } + } else { + auto it = method2notification.find(msg.method); + if (it != method2notification.end()) + try { + it->second(reader); + } catch (...) { + LOG_S(ERROR) << "failed to process " << msg.method; + } + } +} + +QueryFile *MessageHandler::FindFile(ReplyOnce &reply, + const std::string &path, + int *out_file_id) { + QueryFile *ret = nullptr; + auto it = db->name2file_id.find(LowerPathIfInsensitive(path)); if (it != db->name2file_id.end()) { QueryFile &file = db->files[it->second]; if (file.def) { - *out_query_file = &file; + ret = &file; if (out_file_id) *out_file_id = it->second; - return true; + return ret; } } if (out_file_id) *out_file_id = -1; - bool has_entry = false; - { - std::lock_guard lock(project->mutex_); - for (auto &[root, folder] : project->root2folder) - has_entry |= folder.path2entry_index.count(absolute_path); - } - - if (id) { + if (reply.id.Valid()) { + bool has_entry = false; + { + std::lock_guard lock(project->mutex_); + for (auto &[root, folder] : project->root2folder) + has_entry |= folder.path2entry_index.count(path); + } lsResponseError err; if (has_entry) { err.code = lsErrorCodes::ServerNotInitialized; - err.message = absolute_path + " is being indexed"; + err.message = path + " is being indexed"; } else { err.code = lsErrorCodes::InternalError; - err.message = "unable to find " + absolute_path; + err.message = "unable to find " + path; } - pipeline::ReplyError(*id, err); + reply.Error(err); } - return false; + return ret; } void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) { @@ -322,3 +461,4 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { params.symbols.push_back(std::move(entry.second)); pipeline::Notify("$ccls/publishSemanticHighlight", params); } +} // namespace ccls diff --git a/src/message_handler.h b/src/message_handler.h deleted file mode 100644 index bac5d3ea3..000000000 --- a/src/message_handler.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "lsp.h" -#include "query.h" - -#include -#include -#include -#include - -struct CompletionManager; -struct Config; -struct GroupMatch; -struct VFS; -struct IncludeComplete; -struct MultiQueueWaiter; -struct Project; -struct DB; -struct WorkingFile; -struct WorkingFiles; - - -// Usage: -// -// struct FooHandler : MessageHandler { -// // ... -// }; -// REGISTER_MESSAGE_HANDLER(FooHandler); -// -// Then there will be a global FooHandler instance in -// |MessageHandler::message_handlers|. - -#define REGISTER_MESSAGE_HANDLER(type) \ - static type type##message_handler_instance_; - -struct MessageHandler { - DB *db = nullptr; - Project *project = nullptr; - VFS *vfs = nullptr; - WorkingFiles *working_files = nullptr; - CompletionManager *clang_complete = nullptr; - IncludeComplete *include_complete = nullptr; - - virtual MethodType GetMethodType() const = 0; - virtual void Run(std::unique_ptr message) = 0; - - static std::vector *message_handlers; - -protected: - MessageHandler(); -}; - -template struct BaseMessageHandler : MessageHandler { - virtual void Run(TMessage *message) = 0; - - // MessageHandler: - void Run(std::unique_ptr message) override { - Run(static_cast(message.get())); - } -}; - -bool FindFileOrFail(DB *db, Project *project, std::optional id, - const std::string &absolute_path, - QueryFile **out_query_file, int *out_file_id = nullptr); - -void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file); - -void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file); diff --git a/src/message_handler.hh b/src/message_handler.hh new file mode 100644 index 000000000..ad1c50095 --- /dev/null +++ b/src/message_handler.hh @@ -0,0 +1,265 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#pragma once + +#include "lsp.hh" +#include "query.h" + +#include +#include +#include +#include +#include + +namespace ccls { +struct CompletionManager; +struct Config; +struct GroupMatch; +struct VFS; +struct IncludeComplete; +struct MultiQueueWaiter; +struct Project; +struct DB; +struct WorkingFile; +struct WorkingFiles; + +namespace pipeline { +void Reply(lsRequestId id, const std::function &fn); +void ReplyError(lsRequestId id, const std::function &fn); +} + +struct EmptyParam { + bool placeholder; +}; +struct TextDocumentParam { + lsTextDocumentIdentifier textDocument; +}; +struct DidOpenTextDocumentParam { + lsTextDocumentItem textDocument; +}; + +struct TextDocumentPositionParam { + lsTextDocumentIdentifier textDocument; + lsPosition position; +}; + +struct RenameParam { + lsTextDocumentIdentifier textDocument; + lsPosition position; + std::string newName; +}; + +// code* +struct CodeActionParam { + lsTextDocumentIdentifier textDocument; + lsRange range; + struct Context { + std::vector diagnostics; + } context; +}; + +// completion +enum class lsCompletionTriggerKind { + Invoked = 1, + TriggerCharacter = 2, + TriggerForIncompleteCompletions = 3, +}; +struct lsCompletionContext { + lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked; + std::optional triggerCharacter; +}; +struct lsCompletionParams : TextDocumentPositionParam { + lsCompletionContext context; +}; +enum class lsCompletionItemKind { + Text = 1, + Method = 2, + Function = 3, + Constructor = 4, + Field = 5, + Variable = 6, + Class = 7, + Interface = 8, + Module = 9, + Property = 10, + Unit = 11, + Value = 12, + Enum = 13, + Keyword = 14, + Snippet = 15, + Color = 16, + File = 17, + Reference = 18, + Folder = 19, + EnumMember = 20, + Constant = 21, + Struct = 22, + Event = 23, + Operator = 24, + TypeParameter = 25, +}; +enum class lsInsertTextFormat { + PlainText = 1, + Snippet = 2 +}; +struct lsCompletionItem { + std::string label; + lsCompletionItemKind kind = lsCompletionItemKind::Text; + std::string detail; + std::optional documentation; + std::string sortText; + std::optional filterText; + std::string insertText; + lsInsertTextFormat insertTextFormat = lsInsertTextFormat::PlainText; + lsTextEdit textEdit; + std::vector additionalTextEdits; + + std::vector parameters_; + int score_; + unsigned priority_; + bool use_angle_brackets_ = false; +}; + +// formatting +struct FormattingOptions { + int tabSize; + bool insertSpaces; +}; +struct DocumentFormattingParam { + lsTextDocumentIdentifier textDocument; + FormattingOptions options; +}; +struct DocumentOnTypeFormattingParam { + lsTextDocumentIdentifier textDocument; + lsPosition position; + std::string ch; + FormattingOptions options; +}; +struct DocumentRangeFormattingParam { + lsTextDocumentIdentifier textDocument; + lsRange range; + FormattingOptions options; +}; + +// workspace +enum class FileChangeType { + Created = 1, + Changed = 2, + Deleted = 3, +}; +struct DidChangeWatchedFilesParam { + struct Event { + lsDocumentUri uri; + FileChangeType type; + }; + std::vector changes; +}; +struct DidChangeWorkspaceFoldersParam { + struct Event { + std::vector added, removed; + } event; +}; +struct WorkspaceSymbolParam { + std::string query; +}; + +// TODO llvm 8 llvm::unique_function +template +using Callback = std::function; + +struct ReplyOnce { + lsRequestId id; + template void operator()(Res &result) const { + if (id.Valid()) + pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); }); + } + template void Error(Err &err) const { + if (id.Valid()) + pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); }); + } +}; + +struct MessageHandler { + DB *db = nullptr; + Project *project = nullptr; + VFS *vfs = nullptr; + WorkingFiles *working_files = nullptr; + CompletionManager *clang_complete = nullptr; + IncludeComplete *include_complete = nullptr; + + llvm::StringMap> method2notification; + llvm::StringMap> method2request; + + MessageHandler(); + void Run(InMessage &msg); + QueryFile *FindFile(ReplyOnce &reply, const std::string &path, + int *out_file_id = nullptr); + +private: + void Bind(const char *method, void (MessageHandler::*handler)(Reader &)); + template + void Bind(const char *method, void (MessageHandler::*handler)(Param &)); + void Bind(const char *method, + void (MessageHandler::*handler)(Reader &, ReplyOnce &)); + template + void Bind(const char *method, + void (MessageHandler::*handler)(Param &, ReplyOnce &)); + + void ccls_call(Reader &, ReplyOnce &); + void ccls_fileInfo(TextDocumentParam &, ReplyOnce &); + void ccls_info(EmptyParam &, ReplyOnce &); + void ccls_inheritance(Reader &, ReplyOnce &); + void ccls_member(Reader &, ReplyOnce &); + void ccls_navigate(Reader &, ReplyOnce &); + void ccls_reload(Reader &); + void ccls_vars(Reader &, ReplyOnce &); + void exit(EmptyParam &); + void initialize(Reader &, ReplyOnce &); + void shutdown(EmptyParam &, ReplyOnce &); + void textDocument_codeAction(CodeActionParam &, ReplyOnce &); + void textDocument_codeLens(TextDocumentParam &, ReplyOnce &); + void textDocument_completion(lsCompletionParams &, ReplyOnce &); + void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &); + void textDocument_didChange(TextDocumentDidChangeParam &); + void textDocument_didClose(TextDocumentParam &); + void textDocument_didOpen(DidOpenTextDocumentParam &); + void textDocument_didSave(TextDocumentParam &); + void textDocument_documentHighlight(TextDocumentPositionParam &, ReplyOnce &); + void textDocument_documentLink(TextDocumentParam &, ReplyOnce &); + void textDocument_documentSymbol(Reader &, ReplyOnce &); + void textDocument_foldingRange(TextDocumentParam &, ReplyOnce &); + void textDocument_formatting(DocumentFormattingParam &, ReplyOnce &); + void textDocument_hover(TextDocumentPositionParam &, ReplyOnce &); + void textDocument_implementation(TextDocumentPositionParam &, ReplyOnce &); + void textDocument_onTypeFormatting(DocumentOnTypeFormattingParam &, + ReplyOnce &); + void textDocument_rangeFormatting(DocumentRangeFormattingParam &, + ReplyOnce &); + void textDocument_references(Reader &, ReplyOnce &); + void textDocument_rename(RenameParam &, ReplyOnce &); + void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &); + void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &); + void workspace_didChangeConfiguration(EmptyParam &); + void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &); + void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &); + void workspace_executeCommand(Reader &, ReplyOnce &); + void workspace_symbol(WorkspaceSymbolParam &, ReplyOnce &); +}; + +void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file); + +void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file); +} // namespace ccls diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 46e992a9f..3dacfddea 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -14,18 +14,16 @@ limitations under the License. ==============================================================================*/ #include "hierarchy.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "query_utils.h" #include -using namespace ccls; +namespace ccls { namespace { -MethodType kMethodType = "$ccls/call"; - enum class CallType : uint8_t { Direct = 0, Base = 1, @@ -38,34 +36,24 @@ bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); } -struct In_cclsCall : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - - struct Params { - // If id is specified, expand a node; otherwise textDocument+position should - // be specified for building the root and |levels| of nodes below. - lsTextDocumentIdentifier textDocument; - lsPosition position; - - Usr usr; - std::string id; - - // true: callee tree (functions called by this function); false: caller tree - // (where this function is called) - bool callee = false; - // Base: include base functions; All: include both base and derived - // functions. - CallType callType = CallType::All; - bool qualified = true; - int levels = 1; - bool hierarchy = false; - }; - Params params; +struct Param : TextDocumentPositionParam { + // If id is specified, expand a node; otherwise textDocument+position should + // be specified for building the root and |levels| of nodes below. + Usr usr; + std::string id; + + // true: callee tree (functions called by this function); false: caller tree + // (where this function is called) + bool callee = false; + // Base: include base functions; All: include both base and derived + // functions. + CallType callType = CallType::All; + bool qualified = true; + int levels = 1; + bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(In_cclsCall::Params, textDocument, position, id, callee, - callType, qualified, levels, hierarchy); -MAKE_REFLECT_STRUCT(In_cclsCall, id, params); -REGISTER_IN_MESSAGE(In_cclsCall); +MAKE_REFLECT_STRUCT(Param, textDocument, position, id, callee, callType, + qualified, levels, hierarchy); struct Out_cclsCall { Usr usr; @@ -175,70 +163,64 @@ bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, return true; } -struct Handler_cclsCall : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - std::optional BuildInitial(Usr root_usr, bool callee, - CallType call_type, bool qualified, - int levels) { - const auto *def = db->Func(root_usr).AnyDef(); - if (!def) - return {}; - - Out_cclsCall entry; - entry.id = std::to_string(root_usr); - entry.usr = root_usr; - entry.callType = CallType::Direct; - if (def->spell) { - if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) - entry.location = *loc; - } - Expand(this, &entry, callee, call_type, qualified, levels); - return entry; +std::optional BuildInitial(MessageHandler *m, Usr root_usr, + bool callee, CallType call_type, + bool qualified, int levels) { + const auto *def = m->db->Func(root_usr).AnyDef(); + if (!def) + return {}; + + Out_cclsCall entry; + entry.id = std::to_string(root_usr); + entry.usr = root_usr; + entry.callType = CallType::Direct; + if (def->spell) { + if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + entry.location = *loc; } + Expand(m, &entry, callee, call_type, qualified, levels); + return entry; +} +} // namespace - void Run(In_cclsCall *request) override { - auto ¶ms = request->params; - std::optional result; - if (params.id.size()) { - try { - params.usr = std::stoull(params.id); - } catch (...) { - return; - } - result.emplace(); - result->id = std::to_string(params.usr); - result->usr = params.usr; - result->callType = CallType::Direct; - if (db->HasFunc(params.usr)) - Expand(this, &*result, params.callee, params.callType, params.qualified, - params.levels); - } else { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { - if (sym.kind == SymbolKind::Func) { - result = BuildInitial(sym.usr, params.callee, params.callType, - params.qualified, params.levels); - break; - } - } +void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { + Param param; + Reflect(reader, param); + std::optional result; + if (param.id.size()) { + try { + param.usr = std::stoull(param.id); + } catch (...) { + return; } - - if (params.hierarchy) - pipeline::Reply(request->id, result); - else { - auto out = FlattenHierarchy(result); - pipeline::Reply(request->id, out); + result.emplace(); + result->id = std::to_string(param.usr); + result->usr = param.usr; + result->callType = CallType::Direct; + if (db->HasFunc(param.usr)) + Expand(this, &*result, param.callee, param.callType, param.qualified, + param.levels); + } else { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *working_file = + working_files->GetFileByFilename(file->def->path); + for (SymbolRef sym : + FindSymbolsAtLocation(working_file, file, param.position)) { + if (sym.kind == SymbolKind::Func) { + result = BuildInitial(this, sym.usr, param.callee, param.callType, + param.qualified, param.levels); + break; + } } } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsCall); -} // namespace + if (param.hierarchy) + reply(result); + else { + auto out = FlattenHierarchy(result); + reply(out); + } +} +} // namespace ccls diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 4e4766bb4..19a68a2bf 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -13,24 +13,16 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" -#include "project.h" +#include "project.hh" #include "query_utils.h" -using namespace ccls; +namespace ccls { MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, dependencies); namespace { -MethodType cclsInfo = "$ccls/info", fileInfo = "$ccls/fileInfo"; - -struct In_cclsInfo : public RequestMessage { - MethodType GetMethodType() const override { return cclsInfo; } -}; -MAKE_REFLECT_STRUCT(In_cclsInfo, id); -REGISTER_IN_MESSAGE(In_cclsInfo); - struct Out_cclsInfo { struct DB { int files, funcs, types, vars; @@ -46,51 +38,33 @@ MAKE_REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars); MAKE_REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests); MAKE_REFLECT_STRUCT(Out_cclsInfo::Project, entries); MAKE_REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project); +} // namespace -struct Handler_cclsInfo : BaseMessageHandler { - MethodType GetMethodType() const override { return cclsInfo; } - void Run(In_cclsInfo *request) override { - Out_cclsInfo result; - result.db.files = db->files.size(); - result.db.funcs = db->funcs.size(); - result.db.types = db->types.size(); - result.db.vars = db->vars.size(); - result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; - result.project.entries = 0; - for (auto &[_, folder] : project->root2folder) - result.project.entries += folder.entries.size(); - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsInfo); - -struct In_cclsFileInfo : public RequestMessage { - MethodType GetMethodType() const override { return fileInfo; } - struct Params { - lsTextDocumentIdentifier textDocument; - } params; -}; -MAKE_REFLECT_STRUCT(In_cclsFileInfo::Params, textDocument); -MAKE_REFLECT_STRUCT(In_cclsFileInfo, id, params); -REGISTER_IN_MESSAGE(In_cclsFileInfo); +void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) { + Out_cclsInfo result; + result.db.files = db->files.size(); + result.db.funcs = db->funcs.size(); + result.db.types = db->types.size(); + result.db.vars = db->vars.size(); + result.pipeline.pendingIndexRequests = pipeline::pending_index_requests; + result.project.entries = 0; + for (auto &[_, folder] : project->root2folder) + result.project.entries += folder.entries.size(); + reply(result); +} -struct Handler_cclsFileInfo : BaseMessageHandler { - MethodType GetMethodType() const override { return fileInfo; } - void Run(In_cclsFileInfo *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) - return; +void MessageHandler::ccls_fileInfo(TextDocumentParam ¶m, ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; - QueryFile::Def result; - // Expose some fields of |QueryFile::Def|. - result.path = file->def->path; - result.args = file->def->args; - result.language = file->def->language; - result.includes = file->def->includes; - result.skipped_ranges = file->def->skipped_ranges; - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsFileInfo); -} // namespace + QueryFile::Def result; + // Expose some fields of |QueryFile::Def|. + result.path = file->def->path; + result.args = file->def->args; + result.language = file->def->language; + result.includes = file->def->includes; + result.skipped_ranges = file->def->skipped_ranges; + reply(result); +} +} // namespace ccls diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 132fad219..a8ec0c59a 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -14,41 +14,30 @@ limitations under the License. ==============================================================================*/ #include "hierarchy.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include +namespace ccls { namespace { -MethodType kMethodType = "$ccls/inheritance", - implementation = "textDocument/implementation"; - -struct In_cclsInheritance : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - // If id+kind are specified, expand a node; otherwise textDocument+position - // should be specified for building the root and |levels| of nodes below. - lsTextDocumentIdentifier textDocument; - lsPosition position; - - Usr usr; - std::string id; - SymbolKind kind = SymbolKind::Invalid; - - // true: derived classes/functions; false: base classes/functions - bool derived = false; - bool qualified = true; - int levels = 1; - bool hierarchy = false; - } params; +struct Param : TextDocumentPositionParam { + // If id+kind are specified, expand a node; otherwise textDocument+position + // should be specified for building the root and |levels| of nodes below. + Usr usr; + std::string id; + SymbolKind kind = SymbolKind::Invalid; + + // true: derived classes/functions; false: base classes/functions + bool derived = false; + bool qualified = true; + int levels = 1; + bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(In_cclsInheritance::Params, textDocument, position, id, - kind, derived, qualified, levels, hierarchy); -MAKE_REFLECT_STRUCT(In_cclsInheritance, id, params); -REGISTER_IN_MESSAGE(In_cclsInheritance); +MAKE_REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified, + levels, hierarchy); struct Out_cclsInheritance { Usr usr; @@ -130,85 +119,68 @@ bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived, m->db->Type(entry->usr)); } -struct Handler_cclsInheritance : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - std::optional BuildInitial(SymbolRef sym, bool derived, - bool qualified, int levels) { - Out_cclsInheritance entry; - entry.id = std::to_string(sym.usr); - entry.usr = sym.usr; - entry.kind = sym.kind; - Expand(this, &entry, derived, qualified, levels); - return entry; - } - - void Run(In_cclsInheritance *request) override { - auto ¶ms = request->params; - std::optional result; - if (params.id.size()) { - try { - params.usr = std::stoull(params.id); - } catch (...) { - return; - } - result.emplace(); - result->id = std::to_string(params.usr); - result->usr = params.usr; - result->kind = params.kind; - if (!(((params.kind == SymbolKind::Func && db->HasFunc(params.usr)) || - (params.kind == SymbolKind::Type && db->HasType(params.usr))) && - Expand(this, &*result, params.derived, params.qualified, - params.levels))) - result.reset(); - } else { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) - if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { - result = BuildInitial(sym, params.derived, params.qualified, - params.levels); - break; - } - } +std::optional BuildInitial(MessageHandler *m, SymbolRef sym, bool derived, + bool qualified, int levels) { + Out_cclsInheritance entry; + entry.id = std::to_string(sym.usr); + entry.usr = sym.usr; + entry.kind = sym.kind; + Expand(m, &entry, derived, qualified, levels); + return entry; +} - if (params.hierarchy) - pipeline::Reply(request->id, result); - else { - auto out = FlattenHierarchy(result); - pipeline::Reply(request->id, out); +void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { + std::optional result; + if (param.id.size()) { + try { + param.usr = std::stoull(param.id); + } catch (...) { + return; } + result.emplace(); + result->id = std::to_string(param.usr); + result->usr = param.usr; + result->kind = param.kind; + if (!(((param.kind == SymbolKind::Func && m->db->HasFunc(param.usr)) || + (param.kind == SymbolKind::Type && m->db->HasType(param.usr))) && + Expand(m, &*result, param.derived, param.qualified, + param.levels))) + result.reset(); + } else { + QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = m->working_files->GetFileByFilename(file->def->path); + + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) + if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { + result = BuildInitial(m, sym, param.derived, param.qualified, + param.levels); + break; + } } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsInheritance); -struct In_textDocumentImplementation : public RequestMessage { - MethodType GetMethodType() const override { return implementation; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_textDocumentImplementation, id, params); -REGISTER_IN_MESSAGE(In_textDocumentImplementation); - -struct Handler_textDocumentImplementation - : BaseMessageHandler { - MethodType GetMethodType() const override { return implementation; } - void Run(In_textDocumentImplementation *request) override { - Handler_cclsInheritance handler; - handler.db = db; - handler.project = project; - handler.working_files = working_files; - - In_cclsInheritance request1; - request1.id = request->id; - request1.params.textDocument = request->params.textDocument; - request1.params.position = request->params.position; - request1.params.derived = true; - handler.Run(&request1); + if (param.hierarchy) + reply(result); + else { + auto out = FlattenHierarchy(result); + reply(out); } -}; -REGISTER_MESSAGE_HANDLER(Handler_textDocumentImplementation); +} } // namespace + +void MessageHandler::ccls_inheritance(Reader &reader, ReplyOnce &reply) { + Param param; + Reflect(reader, param); + Inheritance(this, param, reply); +} + +void MessageHandler::textDocument_implementation( + TextDocumentPositionParam ¶m, ReplyOnce &reply) { + Param param1; + param1.textDocument = param.textDocument; + param1.position = param.position; + param1.derived = true; + Inheritance(this, param1, reply); +} +} // namespace ccls diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index a6d35d012..35921cc94 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -15,7 +15,7 @@ limitations under the License. #include "clang_tu.hh" #include "hierarchy.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "query_utils.h" @@ -24,38 +24,26 @@ limitations under the License. #include -using namespace ccls; +namespace ccls { using namespace clang; namespace { -MethodType kMethodType = "$ccls/member"; - -struct In_cclsMember : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - - struct Params { - // If id is specified, expand a node; otherwise textDocument+position should - // be specified for building the root and |levels| of nodes below. - lsTextDocumentIdentifier textDocument; - lsPosition position; - - // Type - Usr usr; - std::string id; +struct Param : TextDocumentPositionParam { + // If id is specified, expand a node; otherwise textDocument+position should + // be specified for building the root and |levels| of nodes below. + Usr usr; + std::string id; - bool qualified = false; - int levels = 1; - // If SymbolKind::Func and the point is at a type, list member functions - // instead of member variables. - SymbolKind kind = SymbolKind::Var; - bool hierarchy = false; - } params; + bool qualified = false; + int levels = 1; + // If SymbolKind::Func and the point is at a type, list member functions + // instead of member variables. + SymbolKind kind = SymbolKind::Var; + bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(In_cclsMember::Params, textDocument, position, id, - qualified, levels, kind, hierarchy); -MAKE_REFLECT_STRUCT(In_cclsMember, id, params); -REGISTER_IN_MESSAGE(In_cclsMember); +MAKE_REFLECT_STRUCT(Param, textDocument, position, id, qualified, levels, kind, + hierarchy); struct Out_cclsMember { Usr usr; @@ -233,106 +221,99 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, return true; } -struct Handler_cclsMember : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - std::optional BuildInitial(SymbolKind kind, Usr root_usr, - bool qualified, int levels, - SymbolKind memberKind) { - switch (kind) { - default: +std::optional BuildInitial(MessageHandler *m, SymbolKind kind, + Usr root_usr, bool qualified, + int levels, SymbolKind memberKind) { + switch (kind) { + default: + return {}; + case SymbolKind::Func: { + const auto *def = m->db->Func(root_usr).AnyDef(); + if (!def) return {}; - case SymbolKind::Func: { - const auto *def = db->Func(root_usr).AnyDef(); - if (!def) - return {}; - Out_cclsMember entry; - // Not type, |id| is invalid. - entry.name = def->Name(qualified); - if (def->spell) { - if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) - entry.location = *loc; - } - for (Usr usr : def->vars) { - auto &var = db->Var(usr); - if (var.def.size()) - DoField(this, &entry, var, -1, qualified, levels - 1); - } - return entry; + Out_cclsMember entry; + // Not type, |id| is invalid. + entry.name = def->Name(qualified); + if (def->spell) { + if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + entry.location = *loc; } - case SymbolKind::Type: { - const auto *def = db->Type(root_usr).AnyDef(); - if (!def) - return {}; - - Out_cclsMember entry; - entry.id = std::to_string(root_usr); - entry.usr = root_usr; - if (def->spell) { - if (std::optional loc = - GetLsLocation(db, working_files, *def->spell)) - entry.location = *loc; - } - Expand(this, &entry, qualified, levels, memberKind); - return entry; + for (Usr usr : def->vars) { + auto &var = m->db->Var(usr); + if (var.def.size()) + DoField(m, &entry, var, -1, qualified, levels - 1); } + return entry; + } + case SymbolKind::Type: { + const auto *def = m->db->Type(root_usr).AnyDef(); + if (!def) + return {}; + + Out_cclsMember entry; + entry.id = std::to_string(root_usr); + entry.usr = root_usr; + if (def->spell) { + if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + entry.location = *loc; } + Expand(m, &entry, qualified, levels, memberKind); + return entry; } + } +} +} // namespace - void Run(In_cclsMember *request) override { - auto ¶ms = request->params; - std::optional result; - if (params.id.size()) { - try { - params.usr = std::stoull(params.id); - } catch (...) { - return; - } - result.emplace(); - result->id = std::to_string(params.usr); - result->usr = params.usr; - // entry.name is empty as it is known by the client. - if (!(db->HasType(params.usr) && Expand(this, &*result, params.qualified, - params.levels, params.kind))) - result.reset(); - } else { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(wfile, file, params.position)) { - switch (sym.kind) { - case SymbolKind::Func: - case SymbolKind::Type: - result = BuildInitial(sym.kind, sym.usr, params.qualified, - params.levels, params.kind); - break; - case SymbolKind::Var: { - const QueryVar::Def *def = db->GetVar(sym).AnyDef(); - if (def && def->type) - result = BuildInitial(SymbolKind::Type, def->type, params.qualified, - params.levels, params.kind); - break; - } - default: - continue; - } +void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { + Param param; + Reflect(reader, param); + std::optional result; + if (param.id.size()) { + try { + param.usr = std::stoull(param.id); + } catch (...) { + return; + } + result.emplace(); + result->id = std::to_string(param.usr); + result->usr = param.usr; + // entry.name is empty as it is known by the client. + if (!(db->HasType(param.usr) && Expand(this, &*result, param.qualified, + param.levels, param.kind))) + result.reset(); + } else { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + for (SymbolRef sym : + FindSymbolsAtLocation(wfile, file, param.position)) { + switch (sym.kind) { + case SymbolKind::Func: + case SymbolKind::Type: + result = BuildInitial(this, sym.kind, sym.usr, param.qualified, + param.levels, param.kind); + break; + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (def && def->type) + result = BuildInitial(this, SymbolKind::Type, def->type, param.qualified, + param.levels, param.kind); break; } - } - - if (params.hierarchy) - pipeline::Reply(request->id, result); - else { - auto out = FlattenHierarchy(result); - pipeline::Reply(request->id, out); + default: + continue; + } + break; } } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsMember); -} // namespace + if (param.hierarchy) + reply(result); + else { + auto out = FlattenHierarchy(result); + reply(out); + } +} +} // namespace ccls diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 0af052a8a..f4ca72bb9 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -13,25 +13,17 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" -#include "pipeline.hh" +#include "message_handler.hh" #include "query_utils.h" -using namespace ccls; +namespace ccls { namespace { -MethodType kMethodType = "$ccls/navigate"; - -struct In_CclsNavigate : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - lsTextDocumentIdentifier textDocument; - lsPosition position; - std::string direction; - } params; +struct Param { + lsTextDocumentIdentifier textDocument; + lsPosition position; + std::string direction; }; -MAKE_REFLECT_STRUCT(In_CclsNavigate::Params, textDocument, position, direction); -MAKE_REFLECT_STRUCT(In_CclsNavigate, id, params); -REGISTER_IN_MESSAGE(In_CclsNavigate); +MAKE_REFLECT_STRUCT(Param, textDocument, position, direction); Maybe FindParent(QueryFile *file, Position pos) { Maybe parent; @@ -44,75 +36,72 @@ Maybe FindParent(QueryFile *file, Position pos) { parent = sym.extent; return parent; } +} // namespace -struct Handler_CclsNavigate : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_CclsNavigate *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; +void MessageHandler::ccls_navigate(Reader &reader, + ReplyOnce &reply) { + Param param; + Reflect(reader, param); + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; - WorkingFile *wfile = - working_files->GetFileByFilename(file->def->path); - lsPosition ls_pos = request->params.position; - if (wfile && wfile->index_lines.size()) - if (auto line = wfile->GetIndexPosFromBufferPos( - ls_pos.line, &ls_pos.character, false)) - ls_pos.line = *line; - Position pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsPosition ls_pos = param.position; + if (wfile && wfile->index_lines.size()) + if (auto line = wfile->GetIndexPosFromBufferPos(ls_pos.line, + &ls_pos.character, false)) + ls_pos.line = *line; + Position pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; - Maybe res; - switch (params.direction[0]) { - case 'D': { - Maybe parent = FindParent(file, pos); - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && pos < sym.extent.start && - (!parent || sym.extent.end <= parent->end) && - (!res || sym.extent.start < res->start)) - res = sym.extent; - break; - } - case 'L': - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && sym.extent.end <= pos && - (!res || (res->end == sym.extent.end ? sym.extent.start < res->start - : res->end < sym.extent.end))) - res = sym.extent; - break; - case 'R': { - Maybe parent = FindParent(file, pos); - if (parent && parent->start.line == pos.line && pos < parent->end) { - pos = parent->end; - if (pos.column) - pos.column--; - } - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && pos < sym.extent.start && - (!res || - (sym.extent.start == res->start ? res->end < sym.extent.end - : sym.extent.start < res->start))) - res = sym.extent; - break; - } - case 'U': - default: - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && sym.extent.start < pos && - pos < sym.extent.end && (!res || res->start < sym.extent.start)) - res = sym.extent; - break; + Maybe res; + switch (param.direction[0]) { + case 'D': { + Maybe parent = FindParent(file, pos); + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && pos < sym.extent.start && + (!parent || sym.extent.end <= parent->end) && + (!res || sym.extent.start < res->start)) + res = sym.extent; + break; + } + case 'L': + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.end <= pos && + (!res || (res->end == sym.extent.end ? sym.extent.start < res->start + : res->end < sym.extent.end))) + res = sym.extent; + break; + case 'R': { + Maybe parent = FindParent(file, pos); + if (parent && parent->start.line == pos.line && pos < parent->end) { + pos = parent->end; + if (pos.column) + pos.column--; } - std::vector result; - if (res) - if (auto ls_range = GetLsRange(wfile, *res)) { - lsLocation &ls_loc = result.emplace_back(); - ls_loc.uri = params.textDocument.uri; - ls_loc.range = *ls_range; - } - pipeline::Reply(request->id, result); + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && pos < sym.extent.start && + (!res || + (sym.extent.start == res->start ? res->end < sym.extent.end + : sym.extent.start < res->start))) + res = sym.extent; + break; } -}; -REGISTER_MESSAGE_HANDLER(Handler_CclsNavigate); -} // namespace + case 'U': + default: + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && sym.extent.start < pos && + pos < sym.extent.end && (!res || res->start < sym.extent.start)) + res = sym.extent; + break; + } + std::vector result; + if (res) + if (auto ls_range = GetLsRange(wfile, *res)) { + lsLocation &ls_loc = result.emplace_back(); + ls_loc.uri = param.textDocument.uri; + ls_loc.range = *ls_range; + } + reply(result); +} +} // namespace ccls diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 8a451effb..09772b6f0 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -15,80 +15,34 @@ limitations under the License. #include "clang_complete.hh" #include "match.h" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" -#include "project.h" +#include "project.hh" #include "working_files.h" #include #include -using namespace ccls; - +namespace ccls { namespace { -MethodType kMethodType = "$ccls/reload"; - -struct In_cclsReload : public NotificationMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - bool dependencies = true; - std::vector whitelist; - std::vector blacklist; - } params; +struct Param { + bool dependencies = true; + std::vector whitelist; + std::vector blacklist; }; -MAKE_REFLECT_STRUCT(In_cclsReload::Params, dependencies, whitelist, blacklist); -MAKE_REFLECT_STRUCT(In_cclsReload, params); -REGISTER_IN_MESSAGE(In_cclsReload); +MAKE_REFLECT_STRUCT(Param, dependencies, whitelist, blacklist); +} // namespace -struct Handler_cclsReload : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_cclsReload *request) override { - const auto ¶ms = request->params; +void MessageHandler::ccls_reload(Reader &reader) { + Param param; + Reflect(reader, param); // Send index requests for every file. - if (params.whitelist.empty() && params.blacklist.empty()) { - vfs->Clear(); - db->clear(); - project->Index(working_files, lsRequestId()); - clang_complete->FlushAllSessions(); - return; - } - - // TODO - GroupMatch matcher(params.whitelist, params.blacklist); - - std::queue q; - // |need_index| stores every filename ever enqueued. - std::unordered_set need_index; - // Reverse dependency graph. - std::unordered_map> graph; - // filename -> QueryFile mapping for files haven't enqueued. - std::unordered_map path_to_file; - - for (const auto &file : db->files) - if (file.def) { - if (matcher.IsMatch(file.def->path)) - q.push(&file); - else - path_to_file[file.def->path] = &file; - for (const std::string &dependency : file.def->dependencies) - graph[dependency].push_back(file.def->path); - } - - while (!q.empty()) { - const QueryFile *file = q.front(); - q.pop(); - need_index.insert(file->def->path); - - if (request->params.dependencies) - for (const std::string &path : graph[file->def->path]) { - auto it = path_to_file.find(path); - if (it != path_to_file.end()) { - q.push(it->second); - path_to_file.erase(it); - } - } - } + if (param.whitelist.empty() && param.blacklist.empty()) { + vfs->Clear(); + db->clear(); + project->Index(working_files, lsRequestId()); + clang_complete->FlushAllSessions(); + return; } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsReload); -} // namespace +} +} // namespace ccls diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index ca37d8718..834106354 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -13,63 +13,50 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; +namespace ccls { namespace { -MethodType kMethodType = "$ccls/vars"; - -struct In_cclsVars : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params : lsTextDocumentPositionParams { - // 1: field - // 2: local - // 4: parameter - unsigned kind = ~0u; - } params; +struct Param : TextDocumentPositionParam { + // 1: field + // 2: local + // 4: parameter + unsigned kind = ~0u; }; -MAKE_REFLECT_STRUCT(In_cclsVars::Params, textDocument, position, kind); -MAKE_REFLECT_STRUCT(In_cclsVars, id, params); -REGISTER_IN_MESSAGE(In_cclsVars); - -struct Handler_cclsVars : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_cclsVars *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); +MAKE_REFLECT_STRUCT(Param, textDocument, position, kind); +} // namespace - std::vector result; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, params.position)) { - Usr usr = sym.usr; - switch (sym.kind) { - default: - break; - case SymbolKind::Var: { - const QueryVar::Def *def = db->GetVar(sym).AnyDef(); - if (!def || !def->type) - continue; - usr = def->type; - [[fallthrough]]; - } - case SymbolKind::Type: - result = GetLsLocations( - db, working_files, - GetVarDeclarations(db, db->Type(usr).instances, params.kind)); - break; - } +void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { + Param param; + Reflect(reader, param); + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); + + std::vector result; + for (SymbolRef sym : + FindSymbolsAtLocation(working_file, file, param.position)) { + Usr usr = sym.usr; + switch (sym.kind) { + default: + break; + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (!def || !def->type) + continue; + usr = def->type; + [[fallthrough]]; + } + case SymbolKind::Type: + result = GetLsLocations( + db, working_files, + GetVarDeclarations(db, db->Type(usr).instances, param.kind)); + break; } - pipeline::Reply(request->id, result); } -}; -REGISTER_MESSAGE_HANDLER(Handler_cclsVars); -} // namespace + reply(result); +} +} // namespace ccls diff --git a/src/messages/exit.cc b/src/messages/exit.cc deleted file mode 100644 index fd8ccb9a4..000000000 --- a/src/messages/exit.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" - -namespace { -struct In_Exit : public NotificationMessage { - MethodType GetMethodType() const override { return kMethodType_Exit; } -}; -MAKE_REFLECT_EMPTY_STRUCT(In_Exit); -REGISTER_IN_MESSAGE(In_Exit); - -struct Handler_Exit : MessageHandler { - MethodType GetMethodType() const override { return kMethodType_Exit; } - - void Run(std::unique_ptr request) override { exit(0); } -}; -REGISTER_MESSAGE_HANDLER(Handler_Exit); -} // namespace diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index c51a86ff3..08b8b0c39 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -17,20 +17,21 @@ limitations under the License. #include "filesystem.hh" #include "include_complete.h" #include "log.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "platform.h" -#include "project.h" +#include "project.hh" #include "serializers/json.h" #include "working_files.h" #include #include +#include #include #include -using namespace ccls; +namespace ccls { using namespace llvm; // TODO Cleanup global variables @@ -38,8 +39,6 @@ extern std::string g_init_options; namespace { -MethodType kMethodType = "initialize"; - // Code Lens options. struct lsCodeLensOptions { // Code lens has a resolve provider as well. @@ -328,7 +327,7 @@ struct lsInitializeParams { // The initial trace setting. If omitted trace is disabled ('off'). lsTrace trace = lsTrace::Off; - std::vector workspaceFolders; + std::vector workspaceFolders; }; void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { @@ -348,14 +347,6 @@ void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { MAKE_REFLECT_STRUCT(lsInitializeParams, rootUri, initializationOptions, capabilities, trace, workspaceFolders); -struct In_InitializeRequest : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - - lsInitializeParams params; -}; -MAKE_REFLECT_STRUCT(In_InitializeRequest, id, params); -REGISTER_IN_MESSAGE(In_InitializeRequest); - struct lsInitializeResult { lsServerCapabilities capabilities; }; @@ -373,120 +364,124 @@ void *Indexer(void *arg_) { h->working_files); return nullptr; } +} // namespace -struct Handler_Initialize : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_InitializeRequest *request) override { - auto ¶ms = request->params; - if (!params.rootUri) - return; - std::string project_path = NormalizePath(params.rootUri->GetPath()); - LOG_S(INFO) << "initialize in directory " << project_path << " with uri " - << params.rootUri->raw_uri; - - { - g_config = new Config(params.initializationOptions); - rapidjson::Document reader; - reader.Parse(g_init_options.c_str()); - if (!reader.HasParseError()) { - JsonReader json_reader{&reader}; - try { - Reflect(json_reader, *g_config); - } catch (std::invalid_argument &) { - // This will not trigger because parse error is handled in - // MessageRegistry::Parse in lsp.cc - } +void Initialize(MessageHandler *m, lsInitializeParams ¶m, ReplyOnce &reply) { + std::string project_path = NormalizePath(param.rootUri->GetPath()); + LOG_S(INFO) << "initialize in directory " << project_path << " with uri " + << param.rootUri->raw_uri; + + { + g_config = new Config(param.initializationOptions); + rapidjson::Document reader; + reader.Parse(g_init_options.c_str()); + if (!reader.HasParseError()) { + JsonReader json_reader{&reader}; + try { + Reflect(json_reader, *g_config); + } catch (std::invalid_argument &) { + // This will not trigger because parse error is handled in + // MessageRegistry::Parse in lsp.cc } + } - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer(&writer); - Reflect(json_writer, *g_config); - LOG_S(INFO) << "initializationOptions: " << output.GetString(); + rapidjson::StringBuffer output; + rapidjson::Writer writer(output); + JsonWriter json_writer(&writer); + Reflect(json_writer, *g_config); + LOG_S(INFO) << "initializationOptions: " << output.GetString(); - if (g_config->cacheDirectory.size()) { - g_config->cacheDirectory = NormalizePath(g_config->cacheDirectory); - EnsureEndsInSlash(g_config->cacheDirectory); - } + if (g_config->cacheDirectory.size()) { + g_config->cacheDirectory = NormalizePath(g_config->cacheDirectory); + EnsureEndsInSlash(g_config->cacheDirectory); } + } - // Client capabilities - const auto &capabilities = params.capabilities; - g_config->client.snippetSupport &= - capabilities.textDocument.completion.completionItem.snippetSupport; - g_config->client.hierarchicalDocumentSymbolSupport &= - capabilities.textDocument.documentSymbol.hierarchicalDocumentSymbolSupport; - - // Ensure there is a resource directory. - if (g_config->clang.resourceDir.empty()) - g_config->clang.resourceDir = GetDefaultResourceDirectory(); - DoPathMapping(g_config->clang.resourceDir); - LOG_S(INFO) << "Using -resource-dir=" << g_config->clang.resourceDir; - - // Send initialization before starting indexers, so we don't send a - // status update too early. - { - lsInitializeResult result; - pipeline::Reply(request->id, result); - } + // Client capabilities + const auto &capabilities = param.capabilities; + g_config->client.snippetSupport &= + capabilities.textDocument.completion.completionItem.snippetSupport; + g_config->client.hierarchicalDocumentSymbolSupport &= + capabilities.textDocument.documentSymbol + .hierarchicalDocumentSymbolSupport; + + // Ensure there is a resource directory. + if (g_config->clang.resourceDir.empty()) + g_config->clang.resourceDir = GetDefaultResourceDirectory(); + DoPathMapping(g_config->clang.resourceDir); + LOG_S(INFO) << "use -resource-dir=" << g_config->clang.resourceDir; + + // Send initialization before starting indexers, so we don't send a + // status update too early. + { + lsInitializeResult result; + reply(result); + } - // Set project root. - EnsureEndsInSlash(project_path); - g_config->fallbackFolder = project_path; - for (const lsWorkspaceFolder &wf : request->params.workspaceFolders) { - std::string path = wf.uri.GetPath(); - EnsureEndsInSlash(path); - g_config->workspaceFolders.push_back(path); - LOG_S(INFO) << "add workspace folder " << wf.name << ": " << path; + // Set project root. + EnsureEndsInSlash(project_path); + g_config->fallbackFolder = project_path; + for (const WorkspaceFolder &wf : param.workspaceFolders) { + std::string path = wf.uri.GetPath(); + EnsureEndsInSlash(path); + g_config->workspaceFolders.push_back(path); + LOG_S(INFO) << "add workspace folder " << wf.name << ": " << path; + } + if (param.workspaceFolders.empty()) + g_config->workspaceFolders.push_back(project_path); + if (g_config->cacheDirectory.size()) + for (const std::string &folder : g_config->workspaceFolders) { + // Create two cache directories for files inside and outside of the + // project. + std::string escaped = EscapeFileName(folder.substr(0, folder.size() - 1)); + sys::fs::create_directories(g_config->cacheDirectory + escaped); + sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); } - if (request->params.workspaceFolders.empty()) - g_config->workspaceFolders.push_back(project_path); - if (g_config->cacheDirectory.size()) - for (const std::string &folder : g_config->workspaceFolders) { - // Create two cache directories for files inside and outside of the - // project. - std::string escaped = - EscapeFileName(folder.substr(0, folder.size() - 1)); - sys::fs::create_directories(g_config->cacheDirectory + escaped); - sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); - } - idx::Init(); - for (const std::string &folder : g_config->workspaceFolders) - project->Load(folder); + idx::Init(); + for (const std::string &folder : g_config->workspaceFolders) + m->project->Load(folder); - // Start indexer threads. Start this after loading the project, as that - // may take a long time. Indexer threads will emit status/progress - // reports. - if (g_config->index.threads == 0) - g_config->index.threads = std::thread::hardware_concurrency(); + // Start indexer threads. Start this after loading the project, as that + // may take a long time. Indexer threads will emit status/progress + // reports. + if (g_config->index.threads == 0) + g_config->index.threads = std::thread::hardware_concurrency(); - LOG_S(INFO) << "start " << g_config->index.threads << " indexers"; - for (int i = 0; i < g_config->index.threads; i++) - SpawnThread(Indexer, new std::pair{this, i}); + LOG_S(INFO) << "start " << g_config->index.threads << " indexers"; + for (int i = 0; i < g_config->index.threads; i++) + SpawnThread(Indexer, new std::pair{m, i}); - // Start scanning include directories before dispatching project - // files, because that takes a long time. - include_complete->Rescan(); + // Start scanning include directories before dispatching project + // files, because that takes a long time. + m->include_complete->Rescan(); - LOG_S(INFO) << "dispatch initial index requests"; - project->Index(working_files, request->id); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_Initialize); -} // namespace + LOG_S(INFO) << "dispatch initial index requests"; + m->project->Index(m->working_files, reply.id); +} + +void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { + lsInitializeParams param; + Reflect(reader, param); + if (!param.rootUri) + return; + Initialize(this, param, reply); +} + +void StandaloneInitialize(MessageHandler &handler, const std::string &root) { + lsInitializeParams param; + param.rootUri = lsDocumentUri::FromPath(root); + ReplyOnce reply; + Initialize(&handler, param, reply); +} + +void MessageHandler::shutdown(EmptyParam &, ReplyOnce &reply) { + JsonNull result; + reply(result); +} -void StandaloneInitialize(const std::string &root, Project &project, - WorkingFiles &wfiles, VFS &vfs, - IncludeComplete &complete) { - Handler_Initialize handler; - handler.project = &project; - handler.working_files = &wfiles; - handler.vfs = &vfs; - handler.include_complete = &complete; - - In_InitializeRequest request; - request.params.rootUri = lsDocumentUri::FromPath(root); - handler.Run(&request); +void MessageHandler::exit(EmptyParam &) { + // FIXME cancel threads + ::exit(0); } +} // namespace ccls diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc deleted file mode 100644 index 9f9a0dba0..000000000 --- a/src/messages/shutdown.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -using namespace ccls; - -namespace { -MethodType kMethodType = "shutdown"; - -struct In_Shutdown : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } -}; -MAKE_REFLECT_STRUCT(In_Shutdown, id); -REGISTER_IN_MESSAGE(In_Shutdown); - -struct Handler_Shutdown : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_Shutdown *request) override { - JsonNull result; - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_Shutdown); -} // namespace diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc new file mode 100644 index 000000000..ee46bc8a8 --- /dev/null +++ b/src/messages/textDocument_code.cc @@ -0,0 +1,234 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "message_handler.hh" +#include "pipeline.hh" +#include "query_utils.h" +#include "serializers/json.h" + +#include + +#include + +namespace ccls { +namespace { +struct CodeAction { + std::string title; + const char *kind = "quickfix"; + lsWorkspaceEdit edit; +}; +MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); +} +void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, + ReplyOnce &reply) { + WorkingFile *wfile = + working_files->GetFileByFilename(param.textDocument.uri.GetPath()); + if (!wfile) { + return; + } + std::vector result; + std::vector diagnostics; + working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); + for (lsDiagnostic &diag : diagnostics) + if (diag.fixits_.size()) { + CodeAction &cmd = result.emplace_back(); + cmd.title = "FixIt: " + diag.message; + auto &edit = cmd.edit.documentChanges.emplace_back(); + edit.textDocument.uri = param.textDocument.uri; + edit.textDocument.version = wfile->version; + edit.edits = diag.fixits_; + } + reply(result); +} + +namespace { +struct Cmd_xref { + Usr usr; + SymbolKind kind; + std::string field; +}; +struct lsCommand { + std::string title; + std::string command; + std::vector arguments; +}; +struct lsCodeLens { + lsRange range; + std::optional command; +}; +MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); +MAKE_REFLECT_STRUCT(lsCommand, title, command, arguments); +MAKE_REFLECT_STRUCT(lsCodeLens, range, command); + +template +std::string ToString(T &v) { + rapidjson::StringBuffer output; + rapidjson::Writer writer(output); + JsonWriter json_writer(&writer); + Reflect(json_writer, v); + return output.GetString(); +} + +struct CommonCodeLensParams { + std::vector *result; + DB *db; + WorkingFile *wfile; +}; +} // namespace + +void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, + ReplyOnce &reply) { + std::vector result; + std::string path = param.textDocument.uri.GetPath(); + + QueryFile *file = FindFile(reply, path); + WorkingFile *wfile = + file ? working_files->GetFileByFilename(file->def->path) : nullptr; + if (!wfile) { + return; + } + + auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, + bool force_display = false) { + if (!num && !force_display) + return; + std::optional ls_range = GetLsRange(wfile, range); + if (!ls_range) + return; + lsCodeLens &code_lens = result.emplace_back(); + code_lens.range = *ls_range; + code_lens.command = lsCommand(); + code_lens.command->command = std::string(ccls_xref); + bool plural = num > 1 && singular[strlen(singular) - 1] != 'd'; + code_lens.command->title = + llvm::formatv("{0} {1}{2}", num, singular, plural ? "s" : "").str(); + code_lens.command->arguments.push_back(ToString(show)); + }; + + std::unordered_set seen; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid() || !seen.insert(sym.range).second) + continue; + switch (sym.kind) { + case SymbolKind::Func: { + QueryFunc &func = db->GetFunc(sym); + const QueryFunc::Def *def = func.AnyDef(); + if (!def) + continue; + std::vector base_uses = GetUsesForAllBases(db, func); + std::vector derived_uses = GetUsesForAllDerived(db, func); + Add("ref", {sym.usr, SymbolKind::Func, "uses"}, sym.range, + func.uses.size(), base_uses.empty()); + if (base_uses.size()) + Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, sym.range, + base_uses.size()); + if (derived_uses.size()) + Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, sym.range, + derived_uses.size()); + if (base_uses.empty()) + Add("base", {sym.usr, SymbolKind::Func, "bases"}, sym.range, + def->bases.size()); + Add("derived", {sym.usr, SymbolKind::Func, "derived"}, sym.range, + func.derived.size()); + break; + } + case SymbolKind::Type: { + QueryType &type = db->GetType(sym); + Add("ref", {sym.usr, SymbolKind::Type, "uses"}, sym.range, + type.uses.size(), true); + Add("derived", {sym.usr, SymbolKind::Type, "derived"}, sym.range, + type.derived.size()); + Add("var", {sym.usr, SymbolKind::Type, "instances"}, sym.range, + type.instances.size()); + break; + } + case SymbolKind::Var: { + QueryVar &var = db->GetVar(sym); + const QueryVar::Def *def = var.AnyDef(); + if (!def || (def->is_local() && !g_config->codeLens.localVariables)) + continue; + Add("ref", {sym.usr, SymbolKind::Var, "uses"}, sym.range, var.uses.size(), + def->kind != lsSymbolKind::Macro); + break; + } + case SymbolKind::File: + case SymbolKind::Invalid: + llvm_unreachable(""); + }; + } + + reply(result); +} + +void MessageHandler::workspace_executeCommand(Reader &reader, + ReplyOnce &reply) { + lsCommand param; + Reflect(reader, param); + if (param.arguments.empty()) { + return; + } + rapidjson::Document reader1; + reader1.Parse(param.arguments[0].c_str()); + JsonReader json_reader{&reader1}; + if (param.command == ccls_xref) { + Cmd_xref cmd; + Reflect(json_reader, cmd); + std::vector result; + auto Map = [&](auto &&uses) { + for (auto &use : uses) + if (auto loc = GetLsLocation(db, working_files, use)) + result.push_back(std::move(*loc)); + }; + switch (cmd.kind) { + case SymbolKind::Func: { + QueryFunc &func = db->Func(cmd.usr); + if (cmd.field == "bases") { + if (auto *def = func.AnyDef()) + Map(GetFuncDeclarations(db, def->bases)); + } else if (cmd.field == "bases uses") { + Map(GetUsesForAllBases(db, func)); + } else if (cmd.field == "derived") { + Map(GetFuncDeclarations(db, func.derived)); + } else if (cmd.field == "derived uses") { + Map(GetUsesForAllDerived(db, func)); + } else if (cmd.field == "uses") { + Map(func.uses); + } + break; + } + case SymbolKind::Type: { + QueryType &type = db->Type(cmd.usr); + if (cmd.field == "derived") { + Map(GetTypeDeclarations(db, type.derived)); + } else if (cmd.field == "instances") { + Map(GetVarDeclarations(db, type.instances, 7)); + } else if (cmd.field == "uses") { + Map(type.uses); + } + break; + } + case SymbolKind::Var: { + QueryVar &var = db->Var(cmd.usr); + if (cmd.field == "uses") + Map(var.uses); + break; + } + default: + break; + } + reply(result); + } +} +} // namespace ccls diff --git a/src/messages/textDocument_codeAction.cc b/src/messages/textDocument_codeAction.cc deleted file mode 100644 index b84d546ee..000000000 --- a/src/messages/textDocument_codeAction.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "working_files.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/codeAction"; - -struct In_TextDocumentCodeAction : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - - // Contains additional diagnostic information about the context in which - // a code action is run. - struct lsCodeActionContext { - // An array of diagnostics. - std::vector diagnostics; - }; - // Params for the CodeActionRequest - struct lsCodeActionParams { - // The document in which the command was invoked. - lsTextDocumentIdentifier textDocument; - // The range for which the command was invoked. - lsRange range; - // Context carrying additional information. - lsCodeActionContext context; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, - diagnostics); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument, - range, context); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); - -struct lsCodeAction { - std::string title; - const char *kind = "quickfix"; - lsWorkspaceEdit edit; -}; -MAKE_REFLECT_STRUCT(lsCodeAction, title, kind, edit); - -struct Handler_TextDocumentCodeAction - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentCodeAction *request) override { - const auto ¶ms = request->params; - WorkingFile *wfile = - working_files->GetFileByFilename(params.textDocument.uri.GetPath()); - if (!wfile) - return; - std::vector result; - std::vector diagnostics; - working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); - for (lsDiagnostic &diag : diagnostics) - if (diag.fixits_.size()) { - lsCodeAction &cmd = result.emplace_back(); - cmd.title = "FixIt: " + diag.message; - auto &edit = cmd.edit.documentChanges.emplace_back(); - edit.textDocument.uri = params.textDocument.uri; - edit.textDocument.version = wfile->version; - edit.edits = diag.fixits_; - } - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); -} // namespace diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc deleted file mode 100644 index d07895579..000000000 --- a/src/messages/textDocument_codeLens.cc +++ /dev/null @@ -1,231 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -#include "serializers/json.h" - -#include - -#include - -using namespace ccls; - -namespace { -const MethodType codeLens = "textDocument/codeLens", - executeCommand = "workspace/executeCommand"; - -struct lsCommand { - std::string title; - std::string command; - std::vector arguments; -}; -MAKE_REFLECT_STRUCT(lsCommand, title, command, arguments); - -struct lsCodeLens { - lsRange range; - std::optional command; -}; -MAKE_REFLECT_STRUCT(lsCodeLens, range, command); - -struct Cmd_xref { - Usr usr; - SymbolKind kind; - std::string field; -}; -MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); - -template -std::string ToString(T &v) { - rapidjson::StringBuffer output; - rapidjson::Writer writer(output); - JsonWriter json_writer(&writer); - Reflect(json_writer, v); - return output.GetString(); -} - -struct CommonCodeLensParams { - std::vector *result; - DB *db; - WorkingFile *wfile; -}; - -struct In_TextDocumentCodeLens : public RequestMessage { - MethodType GetMethodType() const override { return codeLens; } - struct Params { - lsTextDocumentIdentifier textDocument; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentCodeLens); - -struct Handler_TextDocumentCodeLens - : BaseMessageHandler { - MethodType GetMethodType() const override { return codeLens; } - void Run(In_TextDocumentCodeLens *request) override { - auto ¶ms = request->params; - std::vector result; - std::string path = params.textDocument.uri.GetPath(); - - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, path, &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - - auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, - bool force_display = false) { - if (!num && !force_display) - return; - std::optional ls_range = GetLsRange(wfile, range); - if (!ls_range) - return; - lsCodeLens &code_lens = result.emplace_back(); - code_lens.range = *ls_range; - code_lens.command = lsCommand(); - code_lens.command->command = std::string(ccls_xref); - bool plural = num > 1 && singular[strlen(singular) - 1] != 'd'; - code_lens.command->title = - llvm::formatv("{0} {1}{2}", num, singular, plural ? "s" : "").str(); - code_lens.command->arguments.push_back(ToString(show)); - }; - - std::unordered_set seen; - for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0 || !sym.extent.Valid() || !seen.insert(sym.range).second) - continue; - switch (sym.kind) { - case SymbolKind::Func: { - QueryFunc &func = db->GetFunc(sym); - const QueryFunc::Def *def = func.AnyDef(); - if (!def) - continue; - std::vector base_uses = GetUsesForAllBases(db, func); - std::vector derived_uses = GetUsesForAllDerived(db, func); - Add("ref", {sym.usr, SymbolKind::Func, "uses"}, sym.range, - func.uses.size(), base_uses.empty()); - if (base_uses.size()) - Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, sym.range, - base_uses.size()); - if (derived_uses.size()) - Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, sym.range, - derived_uses.size()); - if (base_uses.empty()) - Add("base", {sym.usr, SymbolKind::Func, "bases"}, sym.range, - def->bases.size()); - Add("derived", {sym.usr, SymbolKind::Func, "derived"}, sym.range, - func.derived.size()); - break; - } - case SymbolKind::Type: { - QueryType &type = db->GetType(sym); - Add("ref", {sym.usr, SymbolKind::Type, "uses"}, sym.range, type.uses.size(), - true); - Add("derived", {sym.usr, SymbolKind::Type, "derived"}, sym.range, - type.derived.size()); - Add("var", {sym.usr, SymbolKind::Type, "instances"}, sym.range, - type.instances.size()); - break; - } - case SymbolKind::Var: { - QueryVar &var = db->GetVar(sym); - const QueryVar::Def *def = var.AnyDef(); - if (!def || (def->is_local() && !g_config->codeLens.localVariables)) - continue; - Add("ref", {sym.usr, SymbolKind::Var, "uses"}, sym.range, var.uses.size(), - def->kind != lsSymbolKind::Macro); - break; - } - case SymbolKind::File: - case SymbolKind::Invalid: - llvm_unreachable(""); - }; - } - - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); - -struct In_WorkspaceExecuteCommand : public RequestMessage { - MethodType GetMethodType() const override { return executeCommand; } - lsCommand params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceExecuteCommand, id, params); -REGISTER_IN_MESSAGE(In_WorkspaceExecuteCommand); - -struct Handler_WorkspaceExecuteCommand - : BaseMessageHandler { - MethodType GetMethodType() const override { return executeCommand; } - void Run(In_WorkspaceExecuteCommand *request) override { - const auto ¶ms = request->params; - if (params.arguments.empty()) - return; - rapidjson::Document reader; - reader.Parse(params.arguments[0].c_str()); - JsonReader json_reader{&reader}; - if (params.command == ccls_xref) { - Cmd_xref cmd; - Reflect(json_reader, cmd); - std::vector result; - auto Map = [&](auto &&uses) { - for (auto &use : uses) - if (auto loc = GetLsLocation(db, working_files, use)) - result.push_back(std::move(*loc)); - }; - switch (cmd.kind) { - case SymbolKind::Func: { - QueryFunc &func = db->Func(cmd.usr); - if (cmd.field == "bases") { - if (auto *def = func.AnyDef()) - Map(GetFuncDeclarations(db, def->bases)); - } else if (cmd.field == "bases uses") { - Map(GetUsesForAllBases(db, func)); - } else if (cmd.field == "derived") { - Map(GetFuncDeclarations(db, func.derived)); - } else if (cmd.field == "derived uses") { - Map(GetUsesForAllDerived(db, func)); - } else if (cmd.field == "uses") { - Map(func.uses); - } - break; - } - case SymbolKind::Type: { - QueryType &type = db->Type(cmd.usr); - if (cmd.field == "derived") { - Map(GetTypeDeclarations(db, type.derived)); - } else if (cmd.field == "instances") { - Map(GetVarDeclarations(db, type.instances, 7)); - } else if (cmd.field == "uses") { - Map(type.uses); - } - break; - } - case SymbolKind::Var: { - QueryVar &var = db->Var(cmd.usr); - if (cmd.field == "uses") - Map(var.uses); - break; - } - default: - break; - } - pipeline::Reply(request->id, result); - } - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); -} // namespace diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 4e83cc8f4..5a2c2210c 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -17,7 +17,7 @@ limitations under the License. #include "fuzzy_match.h" #include "include_complete.h" #include "log.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "working_files.h" @@ -26,62 +26,23 @@ limitations under the License. #include -using namespace ccls; +namespace ccls { using namespace clang; using namespace llvm; -namespace { -MethodType kMethodType = "textDocument/completion"; - -// How a completion was triggered -enum class lsCompletionTriggerKind { - // Completion was triggered by typing an identifier (24x7 code - // complete), manual invocation (e.g Ctrl+Space) or via API. - Invoked = 1, - // Completion was triggered by a trigger character specified by - // the `triggerCharacters` properties of the `CompletionRegistrationOptions`. - TriggerCharacter = 2, - // Completion was re-triggered as the current completion list is incomplete. - TriggerForIncompleteCompletions = 3, -}; -MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind); - -// Contains additional information about the context in which a completion -// request is triggered. -struct lsCompletionContext { - // How the completion was triggered. - lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked; - - // The trigger character (a single character) that has trigger code complete. - // Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` - std::optional triggerCharacter; -}; -MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter); - -struct lsCompletionParams : lsTextDocumentPositionParams { - // The completion context. This is only available it the client specifies to - // send this using - // `ClientCapabilities.textDocument.completion.contextSupport === true` - lsCompletionContext context; -}; -MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); - -struct In_TextDocumentComplete : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsCompletionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentComplete, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentComplete); - struct lsCompletionList { - // This list it not complete. Further typing should result in recomputing - // this list. bool isIncomplete = false; - // The completion items. std::vector items; }; + +MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat); +MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind); +MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation, + sortText, filterText, insertText, insertTextFormat, + textEdit, additionalTextEdits); MAKE_REFLECT_STRUCT(lsCompletionList, isIncomplete, items); +namespace { void DecorateIncludePaths(const std::smatch &match, std::vector *items) { std::string spaces_after_include = " "; @@ -485,139 +446,129 @@ class CompletionConsumer : public CodeCompleteConsumer { CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } }; +} // namespace -struct Handler_TextDocumentCompletion - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentComplete *request) override { - static CompleteConsumerCache> cache; +void MessageHandler::textDocument_completion(lsCompletionParams ¶m, + ReplyOnce &reply) { + static CompleteConsumerCache> cache; + lsCompletionList result; + std::string path = param.textDocument.uri.GetPath(); + WorkingFile *file = working_files->GetFileByFilename(path); + if (!file) { + return; + } - const auto ¶ms = request->params; - lsCompletionList result; + // It shouldn't be possible, but sometimes vscode will send queries out + // of order, ie, we get completion request before buffer content update. + std::string buffer_line; + if (param.position.line >= 0 && + param.position.line < file->buffer_lines.size()) + buffer_line = file->buffer_lines[param.position.line]; + + // Check for - and : before completing -> or ::, since vscode does not + // support multi-character trigger characters. + if (param.context.triggerKind == lsCompletionTriggerKind::TriggerCharacter && + param.context.triggerCharacter) { + bool did_fail_check = false; + + std::string character = *param.context.triggerCharacter; + int preceding_index = param.position.character - 2; + + // If the character is '"', '<' or '/', make sure that the line starts + // with '#'. + if (character == "\"" || character == "<" || character == "/") { + size_t i = 0; + while (i < buffer_line.size() && isspace(buffer_line[i])) + ++i; + if (i >= buffer_line.size() || buffer_line[i] != '#') + did_fail_check = true; + } + // If the character is > or : and we are at the start of the line, do not + // show completion results. + else if ((character == ">" || character == ":") && preceding_index < 0) { + did_fail_check = true; + } + // If the character is > but - does not preced it, or if it is : and : + // does not preced it, do not show completion results. + else if (preceding_index >= 0 && + preceding_index < (int)buffer_line.size()) { + char preceding = buffer_line[preceding_index]; + did_fail_check = (preceding != '-' && character == ">") || + (preceding != ':' && character == ":"); + } - std::string path = params.textDocument.uri.GetPath(); - WorkingFile *file = working_files->GetFileByFilename(path); - if (!file) { - pipeline::Reply(request->id, result); + if (did_fail_check) { + reply(result); return; } + } - // It shouldn't be possible, but sometimes vscode will send queries out - // of order, ie, we get completion request before buffer content update. - std::string buffer_line; - if (params.position.line >= 0 && - params.position.line < file->buffer_lines.size()) - buffer_line = file->buffer_lines[params.position.line]; - - // Check for - and : before completing -> or ::, since vscode does not - // support multi-character trigger characters. - if (params.context.triggerKind == - lsCompletionTriggerKind::TriggerCharacter && - params.context.triggerCharacter) { - bool did_fail_check = false; - - std::string character = *params.context.triggerCharacter; - int preceding_index = params.position.character - 2; - - // If the character is '"', '<' or '/', make sure that the line starts - // with '#'. - if (character == "\"" || character == "<" || character == "/") { - size_t i = 0; - while (i < buffer_line.size() && isspace(buffer_line[i])) - ++i; - if (i >= buffer_line.size() || buffer_line[i] != '#') - did_fail_check = true; - } - // If the character is > or : and we are at the start of the line, do not - // show completion results. - else if ((character == ">" || character == ":") && preceding_index < 0) { - did_fail_check = true; - } - // If the character is > but - does not preced it, or if it is : and : - // does not preced it, do not show completion results. - else if (preceding_index >= 0 && - preceding_index < (int)buffer_line.size()) { - char preceding = buffer_line[preceding_index]; - did_fail_check = (preceding != '-' && character == ">") || - (preceding != ':' && character == ":"); - } + std::string completion_text; + lsPosition end_pos = param.position; + lsPosition begin_pos = file->FindStableCompletionSource( + param.position, &completion_text, &end_pos); - if (did_fail_check) { - pipeline::Reply(request->id, result); - return; - } + ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); + + if (preprocess.ok && preprocess.keyword.compare("include") == 0) { + lsCompletionList result; + { + std::unique_lock lock( + include_complete->completion_items_mutex, std::defer_lock); + if (include_complete->is_scanning) + lock.lock(); + std::string quote = preprocess.match[5]; + for (auto &item : include_complete->completion_items) + if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + result.items.push_back(item); } + begin_pos.character = 0; + end_pos.character = (int)buffer_line.size(); + FilterCandidates(result, preprocess.pattern, begin_pos, end_pos, + buffer_line); + DecorateIncludePaths(preprocess.match, &result.items); + reply(result); + } else { + std::string path = param.textDocument.uri.GetPath(); + CompletionManager::OnComplete callback = + [completion_text, path, begin_pos, end_pos, reply, + buffer_line](CodeCompleteConsumer *OptConsumer) { + if (!OptConsumer) + return; + auto *Consumer = static_cast(OptConsumer); + lsCompletionList result; + result.items = Consumer->ls_items; + + FilterCandidates(result, completion_text, begin_pos, end_pos, + buffer_line); + reply(result); + if (!Consumer->from_cache) { + cache.WithLock([&]() { + cache.path = path; + cache.position = begin_pos; + cache.result = Consumer->ls_items; + }); + } + }; - std::string completion_text; - lsPosition end_pos = params.position; - lsPosition begin_pos = file->FindStableCompletionSource( - params.position, &completion_text, &end_pos); - - ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); - - if (preprocess.ok && preprocess.keyword.compare("include") == 0) { - lsCompletionList result; - { - std::unique_lock lock( - include_complete->completion_items_mutex, std::defer_lock); - if (include_complete->is_scanning) - lock.lock(); - std::string quote = preprocess.match[5]; - for (auto &item : include_complete->completion_items) - if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) - result.items.push_back(item); - } - begin_pos.character = 0; - end_pos.character = (int)buffer_line.size(); - FilterCandidates(result, preprocess.pattern, begin_pos, end_pos, - buffer_line); - DecorateIncludePaths(preprocess.match, &result.items); - pipeline::Reply(request->id, result); - } else { - std::string path = params.textDocument.uri.GetPath(); - CompletionManager::OnComplete callback = - [completion_text, path, begin_pos, end_pos, - id = request->id, buffer_line](CodeCompleteConsumer *OptConsumer) { - if (!OptConsumer) - return; - auto *Consumer = static_cast(OptConsumer); - lsCompletionList result; - result.items = Consumer->ls_items; - - FilterCandidates(result, completion_text, begin_pos, end_pos, - buffer_line); - pipeline::Reply(id, result); - if (!Consumer->from_cache) { - cache.WithLock([&]() { - cache.path = path; - cache.position = begin_pos; - cache.result = Consumer->ls_items; - }); - } - }; - - clang::CodeCompleteOptions CCOpts; - CCOpts.IncludeBriefComments = true; - CCOpts.IncludeCodePatterns = preprocess.ok; // if there is a # + clang::CodeCompleteOptions CCOpts; + CCOpts.IncludeBriefComments = true; + CCOpts.IncludeCodePatterns = preprocess.ok; // if there is a # #if LLVM_VERSION_MAJOR >= 7 - CCOpts.IncludeFixIts = true; + CCOpts.IncludeFixIts = true; #endif - CCOpts.IncludeMacros = true; - if (cache.IsCacheValid(path, begin_pos)) { - CompletionConsumer Consumer(CCOpts, true); - cache.WithLock([&]() { Consumer.ls_items = cache.result; }); - callback(&Consumer); - } else { - clang_complete->completion_request_.PushBack( + CCOpts.IncludeMacros = true; + if (cache.IsCacheValid(path, begin_pos)) { + CompletionConsumer Consumer(CCOpts, true); + cache.WithLock([&]() { Consumer.ls_items = cache.result; }); + callback(&Consumer); + } else { + clang_complete->completion_request_.PushBack( std::make_unique( - request->id, params.textDocument, begin_pos, - std::make_unique(CCOpts, false), CCOpts, - callback)); - } + reply.id, param.textDocument, begin_pos, + std::make_unique(CCOpts, false), CCOpts, + callback)); } } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCompletion); - -} // namespace +} +} // namespace ccls diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 649a02062..2660f222d 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -13,26 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" -#include "pipeline.hh" +#include "message_handler.hh" #include "query_utils.h" #include #include #include -using namespace ccls; - +namespace ccls { namespace { -MethodType kMethodType = "textDocument/definition"; - -struct In_TextDocumentDefinition : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDefinition, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentDefinition); - std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { case SymbolKind::Var: { @@ -54,133 +43,173 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { return GetNonDefDeclarations(db, sym); } } +} // namespace -struct Handler_TextDocumentDefinition - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentDefinition *request) override { - auto ¶ms = request->params; - int file_id; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file, &file_id)) - return; - - std::vector result; - Maybe on_def; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - lsPosition &ls_pos = params.position; - - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { - // Special cases which are handled: - // - symbol has declaration but no definition (ie, pure virtual) - // - goto declaration while in definition of recursive type - std::vector uses; - EachEntityDef(db, sym, [&](const auto &def) { - if (def.spell) { - Use spell = *def.spell; - if (spell.file_id == file_id && - spell.range.Contains(ls_pos.line, ls_pos.character)) { - on_def = spell; - uses.clear(); - return false; - } - uses.push_back(spell); +void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, + ReplyOnce &reply) { + int file_id; + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + if (!file) + return; + + std::vector result; + Maybe on_def; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsPosition &ls_pos = param.position; + + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { + // Special cases which are handled: + // - symbol has declaration but no definition (ie, pure virtual) + // - goto declaration while in definition of recursive type + std::vector uses; + EachEntityDef(db, sym, [&](const auto &def) { + if (def.spell) { + Use spell = *def.spell; + if (spell.file_id == file_id && + spell.range.Contains(ls_pos.line, ls_pos.character)) { + on_def = spell; + uses.clear(); + return false; } - return true; - }); - - // |uses| is empty if on a declaration/definition, otherwise it includes - // all declarations/definitions. - if (uses.empty()) { - for (Use use : GetNonDefDeclarationTargets(db, sym)) - if (!(use.file_id == file_id && - use.range.Contains(ls_pos.line, ls_pos.character))) - uses.push_back(use); - // There is no declaration but the cursor is on a definition. - if (uses.empty() && on_def) - uses.push_back(*on_def); + uses.push_back(spell); } - auto locs = GetLsLocations(db, working_files, uses); - result.insert(result.end(), locs.begin(), locs.end()); + return true; + }); + + // |uses| is empty if on a declaration/definition, otherwise it includes + // all declarations/definitions. + if (uses.empty()) { + for (Use use : GetNonDefDeclarationTargets(db, sym)) + if (!(use.file_id == file_id && + use.range.Contains(ls_pos.line, ls_pos.character))) + uses.push_back(use); + // There is no declaration but the cursor is on a definition. + if (uses.empty() && on_def) + uses.push_back(*on_def); } + auto locs = GetLsLocations(db, working_files, uses); + result.insert(result.end(), locs.begin(), locs.end()); + } - if (result.size()) { - std::sort(result.begin(), result.end()); - result.erase(std::unique(result.begin(), result.end()), result.end()); - } else { - Maybe range; - // Check #include - for (const IndexInclude &include : file->def->includes) { - if (include.line == ls_pos.line) { - result.push_back( - lsLocation{lsDocumentUri::FromPath(include.resolved_path)}); - range = {{0, 0}, {0, 0}}; - break; - } + if (result.size()) { + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + } else { + Maybe range; + // Check #include + for (const IndexInclude &include : file->def->includes) { + if (include.line == ls_pos.line) { + result.push_back( + lsLocation{lsDocumentUri::FromPath(include.resolved_path)}); + range = {{0, 0}, {0, 0}}; + break; + } + } + // Find the best match of the identifier at point. + if (!range) { + lsPosition position = param.position; + const std::string &buffer = wfile->buffer_content; + std::string_view query = LexIdentifierAroundPos(position, buffer); + std::string_view short_query = query; + { + auto pos = query.rfind(':'); + if (pos != std::string::npos) + short_query = query.substr(pos + 1); } - // Find the best match of the identifier at point. - if (!range) { - lsPosition position = request->params.position; - const std::string &buffer = wfile->buffer_content; - std::string_view query = LexIdentifierAroundPos(position, buffer); - std::string_view short_query = query; - { - auto pos = query.rfind(':'); - if (pos != std::string::npos) - short_query = query.substr(pos + 1); - } - // For symbols whose short/detailed names contain |query| as a - // substring, we use the tuple to find the best match. - std::tuple best_score{INT_MAX, 0, true, 0}; - SymbolIdx best_sym; - best_sym.kind = SymbolKind::Invalid; - auto fn = [&](SymbolIdx sym) { - std::string_view short_name = db->GetSymbolName(sym, false), - name = short_query.size() < query.size() - ? db->GetSymbolName(sym, true) - : short_name; - if (short_name != short_query) - return; - if (Maybe dr = GetDefinitionSpell(db, sym)) { - std::tuple score{ - int(name.size() - short_query.size()), 0, - dr->file_id != file_id, - std::abs(dr->range.start.line - position.line)}; - // Update the score with qualified name if the qualified name - // occurs in |name|. - auto pos = name.rfind(query); - if (pos != std::string::npos) { - std::get<0>(score) = int(name.size() - query.size()); - std::get<1>(score) = -int(pos); - } - if (score < best_score) { - best_score = score; - best_sym = sym; - } + // For symbols whose short/detailed names contain |query| as a + // substring, we use the tuple to find the best match. + std::tuple best_score{INT_MAX, 0, true, 0}; + SymbolIdx best_sym; + best_sym.kind = SymbolKind::Invalid; + auto fn = [&](SymbolIdx sym) { + std::string_view short_name = db->GetSymbolName(sym, false), + name = short_query.size() < query.size() + ? db->GetSymbolName(sym, true) + : short_name; + if (short_name != short_query) + return; + if (Maybe dr = GetDefinitionSpell(db, sym)) { + std::tuple score{ + int(name.size() - short_query.size()), 0, dr->file_id != file_id, + std::abs(dr->range.start.line - position.line)}; + // Update the score with qualified name if the qualified name + // occurs in |name|. + auto pos = name.rfind(query); + if (pos != std::string::npos) { + std::get<0>(score) = int(name.size() - query.size()); + std::get<1>(score) = -int(pos); + } + if (score < best_score) { + best_score = score; + best_sym = sym; } - }; - for (auto &func : db->funcs) - fn({func.usr, SymbolKind::Func}); - for (auto &type : db->types) - fn({type.usr, SymbolKind::Type}); - for (auto &var : db->vars) - if (var.def.size() && !var.def[0].is_local()) - fn({var.usr, SymbolKind::Var}); - - if (best_sym.kind != SymbolKind::Invalid) { - Maybe dr = GetDefinitionSpell(db, best_sym); - assert(dr); - if (auto loc = GetLsLocation(db, working_files, *dr)) - result.push_back(*loc); } + }; + for (auto &func : db->funcs) + fn({func.usr, SymbolKind::Func}); + for (auto &type : db->types) + fn({type.usr, SymbolKind::Type}); + for (auto &var : db->vars) + if (var.def.size() && !var.def[0].is_local()) + fn({var.usr, SymbolKind::Var}); + + if (best_sym.kind != SymbolKind::Invalid) { + Maybe dr = GetDefinitionSpell(db, best_sym); + assert(dr); + if (auto loc = GetLsLocation(db, working_files, *dr)) + result.push_back(*loc); } } + } + + reply(result); +} - pipeline::Reply(request->id, result); +void MessageHandler::textDocument_typeDefinition( + TextDocumentPositionParam ¶m, ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); + + std::vector result; + auto Add = [&](const QueryType &type) { + for (const auto &def : type.def) + if (def.spell) { + if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) + result.push_back(*ls_loc); + } + if (result.empty()) + for (const DeclRef &dr : type.declarations) + if (auto ls_loc = GetLsLocation(db, working_files, dr)) + result.push_back(*ls_loc); + }; + for (SymbolRef sym : + FindSymbolsAtLocation(working_file, file, param.position)) { + switch (sym.kind) { + case SymbolKind::Var: { + const QueryVar::Def *def = db->GetVar(sym).AnyDef(); + if (def && def->type) + Add(db->Type(def->type)); + break; + } + case SymbolKind::Type: { + for (auto &def : db->GetType(sym).def) + if (def.alias_of) { + Add(db->Type(def.alias_of)); + break; + } + break; + } + default: + break; + } } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); -} // namespace + + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + reply(result); +} +} // namespace ccls diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 1c284d002..e38bc2c0b 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -15,148 +15,56 @@ limitations under the License. #include "clang_complete.hh" #include "include_complete.h" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" -#include "project.h" +#include "project.hh" #include "working_files.h" -using namespace ccls; -namespace { -MethodType didChange = "textDocument/didChange"; -MethodType didClose = "textDocument/didClose"; -MethodType didOpen = "textDocument/didOpen"; -MethodType didSave = "textDocument/didSave"; - -struct In_TextDocumentDidChange : public NotificationMessage { - MethodType GetMethodType() const override { return didChange; } - lsTextDocumentDidChangeParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidChange, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidChange); - -struct Handler_TextDocumentDidChange - : BaseMessageHandler { - MethodType GetMethodType() const override { return didChange; } - - void Run(In_TextDocumentDidChange *request) override { - const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); - working_files->OnChange(params); - if (g_config->index.onChange) - pipeline::Index(path, {}, IndexMode::OnChange); - clang_complete->NotifyView(path); - if (g_config->diagnostics.onChange >= 0) - clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); - -struct In_TextDocumentDidClose : public NotificationMessage { - MethodType GetMethodType() const override { return didClose; } - struct Params { - lsTextDocumentIdentifier textDocument; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidClose); - -struct Handler_TextDocumentDidClose - : BaseMessageHandler { - MethodType GetMethodType() const override { return didClose; } - - void Run(In_TextDocumentDidClose *request) override { - std::string path = request->params.textDocument.uri.GetPath(); - - working_files->OnClose(request->params.textDocument); - clang_complete->OnClose(path); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); - -struct In_TextDocumentDidOpen : public NotificationMessage { - MethodType GetMethodType() const override { return didOpen; } - - struct Params { - lsTextDocumentItem textDocument; - - // ccls extension - // If specified (e.g. ["clang++", "-DM", "a.cc"]), it overrides the project - // entry (e.g. loaded from compile_commands.json or .ccls). - std::vector args; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen::Params, textDocument, args); -MAKE_REFLECT_STRUCT(In_TextDocumentDidOpen, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidOpen); - -struct Handler_TextDocumentDidOpen - : BaseMessageHandler { - MethodType GetMethodType() const override { return didOpen; } - - void Run(In_TextDocumentDidOpen *request) override { - // NOTE: This function blocks code lens. If it starts taking a long time - // we will need to find a way to unblock the code lens request. - const auto ¶ms = request->params; - const std::string &path = params.textDocument.uri.GetPath(); - - WorkingFile *working_file = working_files->OnOpen(params.textDocument); - if (std::optional cached_file_contents = - pipeline::LoadIndexedContent(path)) - working_file->SetIndexContent(*cached_file_contents); - - QueryFile *file = nullptr; - FindFileOrFail(db, project, std::nullopt, path, &file); - if (file) { - EmitSkippedRanges(working_file, *file); - EmitSemanticHighlight(db, working_file, *file); - } - - include_complete->AddFile(working_file->filename); - std::vector args; - for (const std::string &arg : params.args) - args.push_back(Intern(arg)); - if (args.size()) - project->SetArgsForFile(args, path); - - // Submit new index request if it is not a header file or there is no - // pending index request. - std::pair lang = lookupExtension(path); - if ((lang.first != LanguageId::Unknown && !lang.second) || - !pipeline::pending_index_requests) - pipeline::Index(path, args, IndexMode::Normal); - - clang_complete->NotifyView(path); +namespace ccls { +void MessageHandler::textDocument_didChange(TextDocumentDidChangeParam ¶m) { + std::string path = param.textDocument.uri.GetPath(); + working_files->OnChange(param); + if (g_config->index.onChange) + pipeline::Index(path, {}, IndexMode::OnChange); + clang_complete->NotifyView(path); + if (g_config->diagnostics.onChange >= 0) + clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); +} + +void MessageHandler::textDocument_didClose(TextDocumentParam ¶m) { + std::string path = param.textDocument.uri.GetPath(); + working_files->OnClose(param.textDocument); + clang_complete->OnClose(path); +} + +void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { + std::string path = param.textDocument.uri.GetPath(); + WorkingFile *working_file = working_files->OnOpen(param.textDocument); + if (std::optional cached_file_contents = + pipeline::LoadIndexedContent(path)) + working_file->SetIndexContent(*cached_file_contents); + + ReplyOnce reply; + QueryFile *file = FindFile(reply, path); + if (file) { + EmitSkippedRanges(working_file, *file); + EmitSemanticHighlight(db, working_file, *file); } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidOpen); - -struct In_TextDocumentDidSave : public NotificationMessage { - MethodType GetMethodType() const override { return didSave; } - - struct Params { - // The document that was saved. - lsTextDocumentIdentifier textDocument; + include_complete->AddFile(working_file->filename); - // Optional the content when saved. Depends on the includeText value - // when the save notifcation was requested. - // std::string text; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDidSave::Params, textDocument); -MAKE_REFLECT_STRUCT(In_TextDocumentDidSave, params); -REGISTER_IN_MESSAGE(In_TextDocumentDidSave); + // Submit new index request if it is not a header file or there is no + // pending index request. + std::pair lang = lookupExtension(path); + if ((lang.first != LanguageId::Unknown && !lang.second) || + !pipeline::pending_index_requests) + pipeline::Index(path, {}, IndexMode::Normal); -struct Handler_TextDocumentDidSave - : BaseMessageHandler { - MethodType GetMethodType() const override { return didSave; } + clang_complete->NotifyView(path); +} - void Run(In_TextDocumentDidSave *request) override { - const auto ¶ms = request->params; - const std::string &path = params.textDocument.uri.GetPath(); - pipeline::Index(path, {}, IndexMode::Normal); - clang_complete->NotifySave(path); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); -} // namespace +void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) { + const std::string &path = param.textDocument.uri.GetPath(); + pipeline::Index(path, {}, IndexMode::Normal); + clang_complete->NotifySave(path); +} +} // namespace ccls diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 7dcf7142d..16342b740 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -13,21 +13,19 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "query_utils.h" #include -MAKE_HASHABLE(SymbolIdx, t.usr, t.kind); +MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { -namespace { -MethodType documentHighlight = "textDocument/documentHighlight", - documentLink = "textDocument/documentLink", - documentSymbol = "textDocument/documentSymbol"; +MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); -struct lsDocumentHighlight { +namespace { +struct DocumentHighlight { enum Kind { Text = 1, Read = 2, Write = 3 }; lsRange range; @@ -36,109 +34,81 @@ struct lsDocumentHighlight { // ccls extension Role role = Role::None; - bool operator<(const lsDocumentHighlight &o) const { + bool operator<(const DocumentHighlight &o) const { return !(range == o.range) ? range < o.range : kind < o.kind; } }; -MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); - -struct In_TextDocumentDocumentHighlight : public RequestMessage { - MethodType GetMethodType() const override { return documentHighlight; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight); +MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role); +} // namespace -struct Handler_TextDocumentDocumentHighlight - : BaseMessageHandler { - MethodType GetMethodType() const override { return documentHighlight; } - void Run(In_TextDocumentDocumentHighlight *request) override { - int file_id; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) - return; +void MessageHandler::textDocument_documentHighlight( + TextDocumentPositionParam ¶m, ReplyOnce &reply) { + int file_id; + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + if (!file) + return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - std::vector result; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + std::vector result; - std::vector syms = - FindSymbolsAtLocation(wfile, file, request->params.position, true); - for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0) - continue; - Usr usr = sym.usr; - SymbolKind kind = sym.kind; - if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { - return usr == sym1.usr && kind == sym1.kind; - })) - continue; - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { - lsDocumentHighlight highlight; - highlight.range = loc->range; - if (sym.role & Role::Write) - highlight.kind = lsDocumentHighlight::Write; - else if (sym.role & Role::Read) - highlight.kind = lsDocumentHighlight::Read; - else - highlight.kind = lsDocumentHighlight::Text; - highlight.role = sym.role; - result.push_back(highlight); - } + std::vector syms = + FindSymbolsAtLocation(wfile, file, param.position, true); + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0) + continue; + Usr usr = sym.usr; + SymbolKind kind = sym.kind; + if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { + return usr == sym1.usr && kind == sym1.kind; + })) + continue; + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + DocumentHighlight highlight; + highlight.range = loc->range; + if (sym.role & Role::Write) + highlight.kind = DocumentHighlight::Write; + else if (sym.role & Role::Read) + highlight.kind = DocumentHighlight::Read; + else + highlight.kind = DocumentHighlight::Text; + highlight.role = sym.role; + result.push_back(highlight); } - std::sort(result.begin(), result.end()); - pipeline::Reply(request->id, result); } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); - -struct In_textDocumentDocumentLink : public RequestMessage { - MethodType GetMethodType() const override { return documentLink; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_textDocumentDocumentLink, id, params); -REGISTER_IN_MESSAGE(In_textDocumentDocumentLink); + std::sort(result.begin(), result.end()); + reply(result); +} +namespace { struct lsDocumentLink { lsRange range; lsDocumentUri target; }; MAKE_REFLECT_STRUCT(lsDocumentLink, range, target); +} // namespace -struct Handler_textDocumentDocumentLink - : BaseMessageHandler { - MethodType GetMethodType() const override { return documentLink; } - void Run(In_textDocumentDocumentLink *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) - return; +void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, + ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; - std::vector result; - for (const IndexInclude &include : file->def->includes) - result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}}, - lsDocumentUri::FromPath(include.resolved_path)}); - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentLink); + std::vector result; + for (const IndexInclude &include : file->def->includes) + result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}}, + lsDocumentUri::FromPath(include.resolved_path)}); + reply(result); +} // namespace ccls -struct In_textDocumentDocumentSymbol : public RequestMessage { - MethodType GetMethodType() const override { return documentSymbol; } - struct Params { - lsTextDocumentIdentifier textDocument; - // false: outline; true: all symbols - bool all = false; - // If >= 0, return Range[] instead of SymbolInformation[] to reduce output. - int startLine = -1; - int endLine = -1; - } params; +namespace { +struct DocumentSymbolParam : TextDocumentParam { + // false: outline; true: all symbols + bool all = false; + // If >= 0, return Range[] instead of SymbolInformation[] to reduce output. + int startLine = -1; + int endLine = -1; }; -MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol::Params, textDocument, all, - startLine, endLine); -MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol, id, params); -REGISTER_IN_MESSAGE(In_textDocumentDocumentSymbol); +MAKE_REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine); struct lsDocumentSymbol { std::string name; @@ -167,131 +137,126 @@ template<> bool Ignore(const QueryVar::Def *def) { return !def || def->is_local(); } +} // namespace -struct Handler_textDocumentDocumentSymbol - : BaseMessageHandler { - MethodType GetMethodType() const override { return documentSymbol; } - void Run(In_textDocumentDocumentSymbol *request) override { - auto ¶ms = request->params; - - QueryFile *file; - int file_id; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file, &file_id)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - if (!wfile) - return; +void MessageHandler::textDocument_documentSymbol(Reader &reader, + ReplyOnce &reply) { + DocumentSymbolParam param; + Reflect(reader, param); - if (params.startLine >= 0) { - std::vector result; - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && (params.all || sym.extent.Valid()) && - params.startLine <= sym.range.start.line && - sym.range.start.line <= params.endLine) - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) - result.push_back(loc->range); - std::sort(result.begin(), result.end()); - pipeline::Reply(request->id, result); - } else if (g_config->client.hierarchicalDocumentSymbolSupport) { - std::unordered_map> sym2ds; - std::vector, lsDocumentSymbol *>> - funcs, types; - for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0 || !sym.extent.Valid()) - continue; - auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); - if (!r.second) - continue; - auto &ds = r.first->second; - ds = std::make_unique(); - std::vector def_ptrs; - WithEntity(db, sym, [&, sym = sym](const auto &entity) { - auto *def = entity.AnyDef(); - if (!def) - return; - ds->name = def->Name(false); - ds->detail = def->Name(true); - if (auto ls_range = GetLsRange(wfile, sym.range)) { - ds->selectionRange = *ls_range; - ds->range = ds->selectionRange; - if (sym.extent.Valid()) - if (auto ls_range1 = GetLsRange(wfile, sym.extent)) - ds->range = *ls_range1; - } + int file_id; + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; - for (auto &def : entity.def) - if (def.file_id == file_id && !Ignore(&def)) { - ds->kind = def.kind; - if (def.spell || def.kind == lsSymbolKind::Namespace) - def_ptrs.push_back(&def); - } - }); - if (def_ptrs.empty() || !(params.all || sym.role & Role::Definition || - ds->kind == lsSymbolKind::Namespace)) { - ds.reset(); - continue; + if (param.startLine >= 0) { + std::vector result; + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && (param.all || sym.extent.Valid()) && + param.startLine <= sym.range.start.line && + sym.range.start.line <= param.endLine) + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) + result.push_back(loc->range); + std::sort(result.begin(), result.end()); + reply(result); + } else if (g_config->client.hierarchicalDocumentSymbolSupport) { + std::unordered_map> sym2ds; + std::vector, lsDocumentSymbol *>> funcs, + types; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid()) + continue; + auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); + if (!r.second) + continue; + auto &ds = r.first->second; + ds = std::make_unique(); + std::vector def_ptrs; + WithEntity(db, sym, [&, sym = sym](const auto &entity) { + auto *def = entity.AnyDef(); + if (!def) + return; + ds->name = def->Name(false); + ds->detail = def->Name(true); + if (auto ls_range = GetLsRange(wfile, sym.range)) { + ds->selectionRange = *ls_range; + ds->range = ds->selectionRange; + if (sym.extent.Valid()) + if (auto ls_range1 = GetLsRange(wfile, sym.extent)) + ds->range = *ls_range1; } - if (sym.kind == SymbolKind::Func) - funcs.emplace_back(std::move(def_ptrs), ds.get()); - else if (sym.kind == SymbolKind::Type) - types.emplace_back(std::move(def_ptrs), ds.get()); - } - for (auto &[def_ptrs, ds] : funcs) - for (const void *def_ptr : def_ptrs) - for (Usr usr1 : ((const QueryFunc::Def *)def_ptr)->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (auto &[def_ptrs, ds] : types) - for (const void *def_ptr : def_ptrs) { - auto *def = (const QueryType::Def *)def_ptr; - for (Usr usr1 : def->funcs) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (Usr usr1 : def->types) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); - } - for (auto [usr1, _] : def->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); - if (it != sym2ds.end() && it->second) - ds->children.push_back(std::move(it->second)); + for (auto &def : entity.def) + if (def.file_id == file_id && !Ignore(&def)) { + ds->kind = def.kind; + if (def.spell || def.kind == lsSymbolKind::Namespace) + def_ptrs.push_back(&def); } + }); + if (def_ptrs.empty() || !(param.all || sym.role & Role::Definition || + ds->kind == lsSymbolKind::Namespace)) { + ds.reset(); + continue; + } + if (sym.kind == SymbolKind::Func) + funcs.emplace_back(std::move(def_ptrs), ds.get()); + else if (sym.kind == SymbolKind::Type) + types.emplace_back(std::move(def_ptrs), ds.get()); + } + + for (auto &[def_ptrs, ds] : funcs) + for (const void *def_ptr : def_ptrs) + for (Usr usr1 : ((const QueryFunc::Def *)def_ptr)->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (auto &[def_ptrs, ds] : types) + for (const void *def_ptr : def_ptrs) { + auto *def = (const QueryType::Def *)def_ptr; + for (Usr usr1 : def->funcs) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); } - std::vector> result; - for (auto &[_, ds] : sym2ds) - if (ds) - result.push_back(std::move(ds)); - pipeline::Reply(request->id, result); - } else { - std::vector result; - for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0 || !sym.extent.Valid() || - !(params.all || sym.role & Role::Definition)) + for (Usr usr1 : def->types) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + for (auto [usr1, _] : def->vars) { + auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + if (it != sym2ds.end() && it->second) + ds->children.push_back(std::move(it->second)); + } + } + std::vector> result; + for (auto &[_, ds] : sym2ds) + if (ds) + result.push_back(std::move(ds)); + reply(result); + } else { + std::vector result; + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !sym.extent.Valid() || + !(param.all || sym.role & Role::Definition)) + continue; + if (std::optional info = + GetSymbolInfo(db, sym, false)) { + if ((sym.kind == SymbolKind::Type && + Ignore(db->GetType(sym).AnyDef())) || + (sym.kind == SymbolKind::Var && Ignore(db->GetVar(sym).AnyDef()))) continue; - if (std::optional info = - GetSymbolInfo(db, sym, false)) { - if ((sym.kind == SymbolKind::Type && - Ignore(db->GetType(sym).AnyDef())) || - (sym.kind == SymbolKind::Var && - Ignore(db->GetVar(sym).AnyDef()))) - continue; - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { - info->location = *loc; - result.push_back(*info); - } + if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + info->location = *loc; + result.push_back(*info); } } - pipeline::Reply(request->id, result); } + reply(result); } -}; -REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentSymbol); -} // namespace +} } // namespace ccls diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index ea86ba27e..7777226f8 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -13,61 +13,43 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" -#include "project.h" +#include "project.hh" #include "query_utils.h" #include "working_files.h" namespace ccls { namespace { -MethodType foldingRange = "textDocument/foldingRange"; - -struct In_textDocumentFoldingRange : public RequestMessage { - MethodType GetMethodType() const override { return foldingRange; } - struct Params { - lsTextDocumentIdentifier textDocument; - } params; -}; -MAKE_REFLECT_STRUCT(In_textDocumentFoldingRange::Params, textDocument); -MAKE_REFLECT_STRUCT(In_textDocumentFoldingRange, id, params); -REGISTER_IN_MESSAGE(In_textDocumentFoldingRange); - struct FoldingRange { int startLine, startCharacter, endLine, endCharacter; std::string kind = "region"; }; -MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, endCharacter, kind); - -struct Handler_textDocumentFoldingRange - : BaseMessageHandler { - MethodType GetMethodType() const override { return foldingRange; } - void Run(In_textDocumentFoldingRange *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - nullptr)) - return; - WorkingFile *wfile = - working_files->GetFileByFilename(file->def->path); - if (!wfile) - return; - std::vector result; - std::optional ls_range; - - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && - (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) && - (ls_range = GetLsRange(wfile, sym.extent))) { - FoldingRange &fold = result.emplace_back(); - fold.startLine = ls_range->start.line; - fold.startCharacter = ls_range->start.character; - fold.endLine = ls_range->end.line; - fold.endCharacter = ls_range->end.character; - } - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_textDocumentFoldingRange); +MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, + endCharacter, kind); } // namespace + +void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, + ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::vector result; + std::optional ls_range; + + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.extent.Valid() && + (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) && + (ls_range = GetLsRange(wfile, sym.extent))) { + FoldingRange &fold = result.emplace_back(); + fold.startLine = ls_range->start.line; + fold.startCharacter = ls_range->start.character; + fold.endLine = ls_range->end.line; + fold.endCharacter = ls_range->end.character; + } + reply(result); +} } // namespace ccls diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index a6444c58a..91d84e6ea 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -13,29 +13,17 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "working_files.h" #include #include -using namespace ccls; +namespace ccls { using namespace clang; namespace { -const MethodType formatting = "textDocument/formatting", - onTypeFormatting = "textDocument/onTypeFormatting", - rangeFormatting = "textDocument/rangeFormatting"; - -struct lsFormattingOptions { - // Size of a tab in spaces. - int tabSize; - // Prefer spaces over tabs. - bool insertSpaces; -}; -MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); - llvm::Expected FormatCode(std::string_view code, std::string_view file, tooling::Range Range) { StringRef Code(code.data(), code.size()), File(file.data(), file.size()); @@ -79,116 +67,59 @@ ReplacementsToEdits(std::string_view code, const tooling::Replacements &Repls) { return ret; } -void Format(WorkingFile *wfile, tooling::Range range, lsRequestId id) { +void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { std::string_view code = wfile->buffer_content; - auto ReplsOrErr = - FormatCode(code, wfile->filename, range); + auto ReplsOrErr = FormatCode(code, wfile->filename, range); if (ReplsOrErr) { auto result = ReplacementsToEdits(code, *ReplsOrErr); - pipeline::Reply(id, result); + reply(result); } else { lsResponseError err; err.code = lsErrorCodes::UnknownErrorCode; err.message = llvm::toString(ReplsOrErr.takeError()); - pipeline::ReplyError(id, err); + reply.Error(err); } } +} // namespace -struct In_TextDocumentFormatting : public RequestMessage { - MethodType GetMethodType() const override { return formatting; } - struct Params { - lsTextDocumentIdentifier textDocument; - lsFormattingOptions options; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentFormatting::Params, textDocument, options); -MAKE_REFLECT_STRUCT(In_TextDocumentFormatting, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentFormatting); - -struct Handler_TextDocumentFormatting - : BaseMessageHandler { - MethodType GetMethodType() const override { return formatting; } - void Run(In_TextDocumentFormatting *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - if (!wfile) - return; - Format(wfile, {0, (unsigned)wfile->buffer_content.size()}, request->id); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); - -struct In_TextDocumentOnTypeFormatting : public RequestMessage { - MethodType GetMethodType() const override { return onTypeFormatting; } - struct Params { - lsTextDocumentIdentifier textDocument; - lsPosition position; - std::string ch; - lsFormattingOptions options; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentOnTypeFormatting::Params, textDocument, - position, ch, options); -MAKE_REFLECT_STRUCT(In_TextDocumentOnTypeFormatting, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentOnTypeFormatting); - -struct Handler_TextDocumentOnTypeFormatting - : BaseMessageHandler { - MethodType GetMethodType() const override { return onTypeFormatting; } - void Run(In_TextDocumentOnTypeFormatting *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - if (!wfile) - return; - std::string_view code = wfile->buffer_content; - int pos = GetOffsetForPosition(params.position, code); - auto lbrace = code.find_last_of('{', pos); - if (lbrace == std::string::npos) - lbrace = pos; - Format(wfile, {(unsigned)lbrace, unsigned(pos - lbrace)}, request->id); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentOnTypeFormatting); - -struct In_TextDocumentRangeFormatting : public RequestMessage { - MethodType GetMethodType() const override { return rangeFormatting; } - struct Params { - lsTextDocumentIdentifier textDocument; - lsRange range; - lsFormattingOptions options; - } params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting::Params, textDocument, range, - options); -MAKE_REFLECT_STRUCT(In_TextDocumentRangeFormatting, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentRangeFormatting); +void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, + ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + Format(reply, wfile, {0, (unsigned)wfile->buffer_content.size()}); +} -struct Handler_TextDocumentRangeFormatting - : BaseMessageHandler { - MethodType GetMethodType() const override { return rangeFormatting; } +void MessageHandler::textDocument_onTypeFormatting( + DocumentOnTypeFormattingParam ¶m, ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::string_view code = wfile->buffer_content; + int pos = GetOffsetForPosition(param.position, code); + auto lbrace = code.find_last_of('{', pos); + if (lbrace == std::string::npos) + lbrace = pos; + Format(reply, wfile, {(unsigned)lbrace, unsigned(pos - lbrace)}); +} - void Run(In_TextDocumentRangeFormatting *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - if (!wfile) - return; - std::string_view code = wfile->buffer_content; - int begin = GetOffsetForPosition(params.range.start, code), - end = GetOffsetForPosition(params.range.end, code); - Format(wfile, {(unsigned)begin, unsigned(end - begin)}, request->id); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); -} // namespace +void MessageHandler::textDocument_rangeFormatting( + DocumentRangeFormattingParam ¶m, ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!wfile) + return; + std::string_view code = wfile->buffer_content; + int begin = GetOffsetForPosition(param.range.start, code), + end = GetOffsetForPosition(param.range.end, code); + Format(reply, wfile, {(unsigned)begin, unsigned(end - begin)}); +} +} // namespace ccls diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index c88368b88..b645c1383 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -13,13 +13,33 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" -#include "pipeline.hh" +#include "message_handler.hh" #include "query_utils.h" -using namespace ccls; +namespace ccls { namespace { -MethodType kMethodType = "textDocument/hover"; +struct lsMarkedString { + std::optional language; + std::string value; +}; +struct Hover { + std::vector contents; + std::optional range; +}; + +void Reflect(Writer &visitor, lsMarkedString &value) { + // If there is a language, emit a `{language:string, value:string}` object. If + // not, emit a string. + if (value.language) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(language); + REFLECT_MEMBER(value); + REFLECT_MEMBER_END(); + } else { + Reflect(visitor, value.value); + } +} +MAKE_REFLECT_STRUCT(Hover, contents, range); const char *LanguageIdentifier(LanguageId lang) { switch (lang) { @@ -69,51 +89,34 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { }); return {hover, ls_comments}; } +} // namespace -struct In_TextDocumentHover : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentHover, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentHover); - -struct lsHover { - std::vector contents; - std::optional range; -}; -MAKE_REFLECT_STRUCT(lsHover, contents, range); - -struct Handler_TextDocumentHover : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentHover *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; +void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, + ReplyOnce &reply) { + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - lsHover result; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + Hover result; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { - std::optional ls_range = GetLsRange( - working_files->GetFileByFilename(file->def->path), sym.range); - if (!ls_range) - continue; + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + std::optional ls_range = GetLsRange( + working_files->GetFileByFilename(file->def->path), sym.range); + if (!ls_range) + continue; - auto [hover, comments] = GetHover(db, file->def->language, sym, file->id); - if (comments || hover) { - result.range = *ls_range; - if (comments) - result.contents.push_back(*comments); - if (hover) - result.contents.push_back(*hover); - break; - } + auto [hover, comments] = GetHover(db, file->def->language, sym, file->id); + if (comments || hover) { + result.range = *ls_range; + if (comments) + result.contents.push_back(*comments); + if (hover) + result.contents.push_back(*hover); + break; } - - pipeline::Reply(request->id, result); } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); -} // namespace + + reply(result); +} +} // namespace ccls diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 07573d56f..9c4d0f630 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -13,20 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" -#include "pipeline.hh" +#include "message_handler.hh" #include "query_utils.h" #include -using namespace ccls; - +namespace ccls { namespace { -MethodType kMethodType = "textDocument/references"; - -struct In_TextDocumentReferences : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct lsReferenceContext { +struct ReferenceParam : public TextDocumentPositionParam { + struct Context { bool base = true; // Exclude references with any |Role| bits set. Role excludeRole = Role::None; @@ -34,116 +29,99 @@ struct In_TextDocumentReferences : public RequestMessage { bool includeDeclaration = false; // Include references with all |Role| bits set. Role role = Role::None; - }; - struct Params { - lsTextDocumentIdentifier textDocument; - lsPosition position; - lsReferenceContext context; - }; - - Params params; + } context; }; -MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, base, - excludeRole, includeDeclaration, role); -MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position, - context); -MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentReferences); - -struct Handler_TextDocumentReferences - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } +MAKE_REFLECT_STRUCT(ReferenceParam::Context, base, excludeRole, + includeDeclaration, role); +MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context); +} // namespace - void Run(In_TextDocumentReferences *request) override { - auto ¶ms = request->params; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - params.textDocument.uri.GetPath(), &file)) - return; - std::vector result; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - if (!file) { - pipeline::Reply(request->id, result); - return; - } +void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { + ReferenceParam param; + Reflect(reader, param); + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + if (!file) + return; + std::vector result; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!file) + return; - std::unordered_set seen_uses; - int line = params.position.line; + std::unordered_set seen_uses; + int line = param.position.line; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { - // Found symbol. Return references. - std::unordered_set seen; - seen.insert(sym.usr); - std::vector stack{sym.usr}; - if (sym.kind != SymbolKind::Func) - params.context.base = false; - while (stack.size()) { - sym.usr = stack.back(); - stack.pop_back(); - auto fn = [&](Use use, lsSymbolKind parent_kind) { - if (Role(use.role & params.context.role) == params.context.role && - !(use.role & params.context.excludeRole) && - seen_uses.insert(use).second) - if (auto loc = GetLsLocation(db, working_files, use)) { - result.push_back(*loc); - } - }; - WithEntity(db, sym, [&](const auto &entity) { - lsSymbolKind parent_kind = lsSymbolKind::Unknown; + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + // Found symbol. Return references. + std::unordered_set seen; + seen.insert(sym.usr); + std::vector stack{sym.usr}; + if (sym.kind != SymbolKind::Func) + param.context.base = false; + while (stack.size()) { + sym.usr = stack.back(); + stack.pop_back(); + auto fn = [&](Use use, lsSymbolKind parent_kind) { + if (Role(use.role & param.context.role) == param.context.role && + !(use.role & param.context.excludeRole) && + seen_uses.insert(use).second) + if (auto loc = GetLsLocation(db, working_files, use)) { + result.push_back(*loc); + } + }; + WithEntity(db, sym, [&](const auto &entity) { + lsSymbolKind parent_kind = lsSymbolKind::Unknown; + for (auto &def : entity.def) + if (def.spell) { + parent_kind = GetSymbolKind(db, sym); + if (param.context.base) + for (Usr usr : def.GetBases()) + if (!seen.count(usr)) { + seen.insert(usr); + stack.push_back(usr); + } + break; + } + for (Use use : entity.uses) + fn(use, parent_kind); + if (param.context.includeDeclaration) { for (auto &def : entity.def) - if (def.spell) { - parent_kind = GetSymbolKind(db, sym); - if (params.context.base) - for (Usr usr : def.GetBases()) - if (!seen.count(usr)) { - seen.insert(usr); - stack.push_back(usr); - } - break; - } - for (Use use : entity.uses) + if (def.spell) + fn(*def.spell, parent_kind); + for (Use use : entity.declarations) fn(use, parent_kind); - if (params.context.includeDeclaration) { - for (auto &def : entity.def) - if (def.spell) - fn(*def.spell, parent_kind); - for (Use use : entity.declarations) - fn(use, parent_kind); - } - }); - } - break; - } - - if (result.empty()) { - // |path| is the #include line. If the cursor is not on such line but line - // = 0, - // use the current filename. - std::string path; - if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1) - path = file->def->path; - for (const IndexInclude &include : file->def->includes) - if (include.line == params.position.line) { - path = include.resolved_path; - break; } - if (path.size()) - for (QueryFile &file1 : db->files) - if (file1.def) - for (const IndexInclude &include : file1.def->includes) - if (include.resolved_path == path) { - // Another file |file1| has the same include line. - lsLocation &loc = result.emplace_back(); - loc.uri = lsDocumentUri::FromPath(file1.def->path); - loc.range.start.line = loc.range.end.line = include.line; - break; - } + }); } + break; + } - if ((int)result.size() >= g_config->xref.maxNum) - result.resize(g_config->xref.maxNum); - pipeline::Reply(request->id, result); + if (result.empty()) { + // |path| is the #include line. If the cursor is not on such line but line + // = 0, + // use the current filename. + std::string path; + if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1) + path = file->def->path; + for (const IndexInclude &include : file->def->includes) + if (include.line == param.position.line) { + path = include.resolved_path; + break; + } + if (path.size()) + for (QueryFile &file1 : db->files) + if (file1.def) + for (const IndexInclude &include : file1.def->includes) + if (include.resolved_path == path) { + // Another file |file1| has the same include line. + lsLocation &loc = result.emplace_back(); + loc.uri = lsDocumentUri::FromPath(file1.def->path); + loc.range.start.line = loc.range.end.line = include.line; + break; + } } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); -} // namespace + + if ((int)result.size() >= g_config->xref.maxNum) + result.resize(g_config->xref.maxNum); + reply(result); +} +} // namespace ccls diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index d172e0bf5..0b87efc57 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -13,14 +13,11 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "message_handler.h" -#include "pipeline.hh" +#include "message_handler.hh" #include "query_utils.h" -using namespace ccls; +namespace ccls { namespace { -MethodType kMethodType = "textDocument/rename"; - lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, SymbolRef sym, const std::string &new_text) { std::unordered_map path_to_edit; @@ -62,49 +59,21 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, edit.documentChanges.push_back(changes.second); return edit; } +} // namespace -struct In_TextDocumentRename : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - // The document to format. - lsTextDocumentIdentifier textDocument; - - // The position at which this request was sent. - lsPosition position; - - // The new name of the symbol. If the given name is not valid the - // request must return a [ResponseError](#ResponseError) with an - // appropriate message set. - std::string newName; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position, - newName); -MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentRename); - -struct Handler_TextDocumentRename : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentRename *request) override { - int file_id; - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - &file_id)) - return; - - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - lsWorkspaceEdit result; - for (SymbolRef sym : - FindSymbolsAtLocation(wfile, file, request->params.position)) { - result = - BuildWorkspaceEdit(db, working_files, sym, request->params.newName); - break; - } - - pipeline::Reply(request->id, result); +void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { + int file_id; + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + if (!file) + return; + + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + lsWorkspaceEdit result; + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + result = BuildWorkspaceEdit(db, working_files, sym, param.newName); + break; } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); -} // namespace + + reply(result); +} +} // namespace ccls diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 14a9230f9..32b7e3ffe 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -14,56 +14,35 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include -using namespace ccls; +namespace ccls { using namespace clang; namespace { -MethodType kMethodType = "textDocument/signatureHelp"; - -// Represents a parameter of a callable-signature. A parameter can -// have a label and a doc-comment. -struct lsParameterInformation { +struct ParameterInformation { std::string label; - // Not available in clang - // std::optional documentation; }; -MAKE_REFLECT_STRUCT(lsParameterInformation, label); - -// Represents the signature of something callable. A signature -// can have a label, like a function-name, a doc-comment, and -// a set of parameters. -struct lsSignatureInformation { +struct SignatureInformation { std::string label; std::optional documentation; - std::vector parameters; + std::vector parameters; }; -MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters); - -// Signature help represents the signature of something -// callable. There can be multiple signature but only one -// active and only one active parameter. struct lsSignatureHelp { - std::vector signatures; + std::vector signatures; int activeSignature = 0; int activeParameter = 0; }; +MAKE_REFLECT_STRUCT(ParameterInformation, label); +MAKE_REFLECT_STRUCT(SignatureInformation, label, documentation, parameters); MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, activeParameter); -struct In_TextDocumentSignatureHelp : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentSignatureHelp, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentSignatureHelp); - std::string BuildOptional(const CodeCompletionString &CCS, - std::vector &ls_params) { + std::vector &ls_params) { std::string ret; for (const auto &Chunk : CCS) { switch (Chunk.Kind) { @@ -79,7 +58,7 @@ std::string BuildOptional(const CodeCompletionString &CCS, // the code-completion location within a function call, message send, // macro invocation, etc. ret += Chunk.Text; - ls_params.push_back(lsParameterInformation{Chunk.Text}); + ls_params.push_back({Chunk.Text}); break; } case CodeCompletionString::CK_VerticalSpace: @@ -125,7 +104,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { Cand.CreateSignatureString(CurrentArg, S, *Alloc, CCTUInfo, true); const char *ret_type = nullptr; - lsSignatureInformation &ls_sig = ls_sighelp.signatures.emplace_back(); + SignatureInformation &ls_sig = ls_sighelp.signatures.emplace_back(); #if LLVM_VERSION_MAJOR >= 8 const RawComment *RC = getCompletionComment(S.getASTContext(), Cand.getFunction()); ls_sig.documentation = RC ? RC->getBriefText(S.getASTContext()) : ""; @@ -138,7 +117,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { case CodeCompletionString::CK_Placeholder: case CodeCompletionString::CK_CurrentParameter: { ls_sig.label += Chunk.Text; - ls_sig.parameters.push_back(lsParameterInformation{Chunk.Text}); + ls_sig.parameters.push_back({Chunk.Text}); break; } case CodeCompletionString::CK_Optional: @@ -157,7 +136,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { } std::sort( ls_sighelp.signatures.begin(), ls_sighelp.signatures.end(), - [](const lsSignatureInformation &l, const lsSignatureInformation &r) { + [](const SignatureInformation &l, const SignatureInformation &r) { if (l.parameters.size() != r.parameters.size()) return l.parameters.size() < r.parameters.size(); if (l.label.size() != r.label.size()) @@ -169,55 +148,50 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } }; +} // namespace -struct Handler_TextDocumentSignatureHelp - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - - void Run(In_TextDocumentSignatureHelp *request) override { - static CompleteConsumerCache cache; - - const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); - lsPosition begin_pos = params.position; - if (WorkingFile *file = working_files->GetFileByFilename(path)) { - std::string completion_text; - lsPosition end_pos = params.position; - begin_pos = file->FindStableCompletionSource( - request->params.position, &completion_text, &end_pos); - } +void MessageHandler::textDocument_signatureHelp( + TextDocumentPositionParam ¶m, ReplyOnce &reply) { + static CompleteConsumerCache cache; + + std::string path = param.textDocument.uri.GetPath(); + lsPosition begin_pos = param.position; + if (WorkingFile *file = working_files->GetFileByFilename(path)) { + std::string completion_text; + lsPosition end_pos = param.position; + begin_pos = file->FindStableCompletionSource(param.position, + &completion_text, &end_pos); + } - CompletionManager::OnComplete callback = - [id = request->id, path, begin_pos](CodeCompleteConsumer *OptConsumer) { - if (!OptConsumer) - return; - auto *Consumer = static_cast(OptConsumer); - pipeline::Reply(id, Consumer->ls_sighelp); - if (!Consumer->from_cache) { - cache.WithLock([&]() { - cache.path = path; - cache.position = begin_pos; - cache.result = Consumer->ls_sighelp; - }); - } - }; - - CodeCompleteOptions CCOpts; - CCOpts.IncludeGlobals = false; - CCOpts.IncludeMacros = false; - CCOpts.IncludeBriefComments = false; - if (cache.IsCacheValid(path, begin_pos)) { - SignatureHelpConsumer Consumer(CCOpts, true); - cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); - callback(&Consumer); - } else { - clang_complete->completion_request_.PushBack( - std::make_unique( - request->id, params.textDocument, params.position, - std::make_unique(CCOpts, false), CCOpts, - callback)); - } + CompletionManager::OnComplete callback = + [reply, path, begin_pos](CodeCompleteConsumer *OptConsumer) { + if (!OptConsumer) + return; + auto *Consumer = static_cast(OptConsumer); + reply(Consumer->ls_sighelp); + if (!Consumer->from_cache) { + cache.WithLock([&]() { + cache.path = path; + cache.position = begin_pos; + cache.result = Consumer->ls_sighelp; + }); + } + }; + + CodeCompleteOptions CCOpts; + CCOpts.IncludeGlobals = false; + CCOpts.IncludeMacros = false; + CCOpts.IncludeBriefComments = false; + if (cache.IsCacheValid(path, begin_pos)) { + SignatureHelpConsumer Consumer(CCOpts, true); + cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); + callback(&Consumer); + } else { + clang_complete->completion_request_.PushBack( + std::make_unique( + reply.id, param.textDocument, param.position, + std::make_unique(CCOpts, false), CCOpts, + callback)); } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentSignatureHelp); -} // namespace +} +} // namespace ccls diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc deleted file mode 100644 index 76a25c49c..000000000 --- a/src/messages/textDocument_typeDefinition.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" -using namespace ccls; - -namespace { -MethodType kMethodType = "textDocument/typeDefinition"; - -struct In_TextDocumentTypeDefinition : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - lsTextDocumentPositionParams params; -}; -MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params); -REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition); - -struct Handler_TextDocumentTypeDefinition - : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_TextDocumentTypeDefinition *request) override { - QueryFile *file; - if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file, - nullptr)) - return; - WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); - - std::vector result; - auto Add = [&](const QueryType &type) { - for (const auto &def : type.def) - if (def.spell) { - if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) - result.push_back(*ls_loc); - } - if (result.empty()) - for (const DeclRef &dr : type.declarations) - if (auto ls_loc = GetLsLocation(db, working_files, dr)) - result.push_back(*ls_loc); - }; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { - switch (sym.kind) { - case SymbolKind::Var: { - const QueryVar::Def *def = db->GetVar(sym).AnyDef(); - if (def && def->type) - Add(db->Type(def->type)); - break; - } - case SymbolKind::Type: { - for (auto &def : db->GetType(sym).def) - if (def.alias_of) { - Add(db->Type(def.alias_of)); - break; - } - break; - } - default: - break; - } - } - - std::sort(result.begin(), result.end()); - result.erase(std::unique(result.begin(), result.end()), result.end()); - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); - -} // namespace diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc new file mode 100644 index 000000000..b0dc591b1 --- /dev/null +++ b/src/messages/workspace.cc @@ -0,0 +1,189 @@ +/* Copyright 2017-2018 ccls Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "clang_complete.hh" +#include "fuzzy_match.h" +#include "log.hh" +#include "message_handler.hh" +#include "pipeline.hh" +#include "project.hh" +#include "query_utils.h" + +#include + +#include +#include +#include +#include + +namespace ccls { +MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); + +void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { + for (const std::string &folder : g_config->workspaceFolders) + project->Load(folder); + project->Index(working_files, lsRequestId()); + + clang_complete->FlushAllSessions(); +}; + +void MessageHandler::workspace_didChangeWatchedFiles( + DidChangeWatchedFilesParam ¶m) { + for (auto &event : param.changes) { + std::string path = event.uri.GetPath(); + IndexMode mode = working_files->GetFileByFilename(path) + ? IndexMode::Normal + : IndexMode::NonInteractive; + switch (event.type) { + case FileChangeType::Created: + case FileChangeType::Changed: { + pipeline::Index(path, {}, mode); + if (mode == IndexMode::Normal) + clang_complete->NotifySave(path); + else + clang_complete->OnClose(path); + break; + } + case FileChangeType::Deleted: + pipeline::Index(path, {}, mode); + clang_complete->OnClose(path); + break; + } + } +} + +void MessageHandler::workspace_didChangeWorkspaceFolders( + DidChangeWorkspaceFoldersParam ¶m) { + for (const WorkspaceFolder &wf : param.event.removed) { + std::string root = wf.uri.GetPath(); + EnsureEndsInSlash(root); + LOG_S(INFO) << "delete workspace folder " << wf.name << ": " << root; + auto it = llvm::find(g_config->workspaceFolders, root); + if (it != g_config->workspaceFolders.end()) { + g_config->workspaceFolders.erase(it); + { + // auto &folder = project->root2folder[path]; + // FIXME delete + } + project->root2folder.erase(root); + } + } + for (const WorkspaceFolder &wf : param.event.added) { + std::string root = wf.uri.GetPath(); + EnsureEndsInSlash(root); + LOG_S(INFO) << "add workspace folder " << wf.name << ": " << root; + g_config->workspaceFolders.push_back(root); + project->Load(root); + } + + project->Index(working_files, lsRequestId()); + + clang_complete->FlushAllSessions(); +} + +namespace { +// Lookup |symbol| in |db| and insert the value into |result|. +bool AddSymbol( + DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed, + std::vector> *result) { + std::optional info = GetSymbolInfo(db, sym, true); + if (!info) + return false; + + Use loc; + if (Maybe dr = GetDefinitionSpell(db, sym)) + loc = *dr; + else { + auto decls = GetNonDefDeclarations(db, sym); + if (decls.empty()) + return false; + loc = decls[0]; + } + + std::optional ls_location = GetLsLocation(db, working_files, loc); + if (!ls_location) + return false; + info->location = *ls_location; + result->emplace_back(*info, int(use_detailed), sym); + return true; +} +} // namespace + +void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, + ReplyOnce &reply) { + std::vector result; + std::string query = param.query; + + // {symbol info, matching detailed_name or short_name, index} + std::vector> cands; + bool sensitive = g_config->workspaceSymbol.caseSensitivity; + + // Find subsequence matches. + std::string query_without_space; + query_without_space.reserve(query.size()); + for (char c : query) + if (!isspace(c)) + query_without_space += c; + + auto Add = [&](SymbolIdx sym) { + std::string_view detailed_name = db->GetSymbolName(sym, true); + int pos = ReverseSubseqMatch(query_without_space, detailed_name, sensitive); + return pos >= 0 && + AddSymbol(db, working_files, sym, + detailed_name.find(':', pos) != std::string::npos, + &cands) && + cands.size() >= g_config->workspaceSymbol.maxNum; + }; + for (auto &func : db->funcs) + if (Add({func.usr, SymbolKind::Func})) + goto done_add; + for (auto &type : db->types) + if (Add({type.usr, SymbolKind::Type})) + goto done_add; + for (auto &var : db->vars) + if (var.def.size() && !var.def[0].is_local() && + Add({var.usr, SymbolKind::Var})) + goto done_add; +done_add: + + if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { + // Sort results with a fuzzy matching algorithm. + int longest = 0; + for (auto &cand : cands) + longest = std::max( + longest, int(db->GetSymbolName(std::get<2>(cand), true).size())); + FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); + for (auto &cand : cands) + std::get<1>(cand) = + fuzzy.Match(db->GetSymbolName(std::get<2>(cand), std::get<1>(cand))); + std::sort(cands.begin(), cands.end(), [](const auto &l, const auto &r) { + return std::get<1>(l) > std::get<1>(r); + }); + result.reserve(cands.size()); + for (auto &cand : cands) { + // Discard awful candidates. + if (std::get<1>(cand) <= FuzzyMatcher::kMinScore) + break; + result.push_back(std::get<0>(cand)); + } + } else { + result.reserve(cands.size()); + for (auto &cand : cands) + result.push_back(std::get<0>(cand)); + } + + reply(result); +} +} // namespace ccls diff --git a/src/messages/workspace_did.cc b/src/messages/workspace_did.cc deleted file mode 100644 index 46ae4cb5f..000000000 --- a/src/messages/workspace_did.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "clang_complete.hh" -#include "log.hh" -#include "message_handler.h" -#include "pipeline.hh" -#include "project.h" -#include "working_files.h" - -#include -using namespace ccls; - -namespace { -MethodType didChangeConfiguration = "workspace/didChangeConfiguration", - didChangeWatchedFiles = "workspace/didChangeWatchedFiles", - didChangeWorkspaceFolders = "workspace/didChangeWorkspaceFolders"; - -struct lsDidChangeConfigurationParams { - bool placeholder; -}; -MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); - -struct In_workspaceDidChangeConfiguration : public NotificationMessage { - MethodType GetMethodType() const override { return didChangeConfiguration; } - lsDidChangeConfigurationParams params; -}; -MAKE_REFLECT_STRUCT(In_workspaceDidChangeConfiguration, params); -REGISTER_IN_MESSAGE(In_workspaceDidChangeConfiguration); - -struct Handler_workspaceDidChangeConfiguration - : BaseMessageHandler { - MethodType GetMethodType() const override { return didChangeConfiguration; } - void Run(In_workspaceDidChangeConfiguration *request) override { - for (const std::string &folder : g_config->workspaceFolders) - project->Load(folder); - - project->Index(working_files, lsRequestId()); - - clang_complete->FlushAllSessions(); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_workspaceDidChangeConfiguration); - -enum class lsFileChangeType { - Created = 1, - Changed = 2, - Deleted = 3, -}; -MAKE_REFLECT_TYPE_PROXY(lsFileChangeType); - -struct lsFileEvent { - lsDocumentUri uri; - lsFileChangeType type; -}; -MAKE_REFLECT_STRUCT(lsFileEvent, uri, type); - -struct lsDidChangeWatchedFilesParams { - std::vector changes; -}; -MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes); - -struct In_WorkspaceDidChangeWatchedFiles : public NotificationMessage { - MethodType GetMethodType() const override { return didChangeWatchedFiles; } - lsDidChangeWatchedFilesParams params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeWatchedFiles, params); -REGISTER_IN_MESSAGE(In_WorkspaceDidChangeWatchedFiles); - -struct Handler_WorkspaceDidChangeWatchedFiles - : BaseMessageHandler { - MethodType GetMethodType() const override { return didChangeWatchedFiles; } - void Run(In_WorkspaceDidChangeWatchedFiles *request) override { - for (lsFileEvent &event : request->params.changes) { - std::string path = event.uri.GetPath(); - IndexMode mode = working_files->GetFileByFilename(path) - ? IndexMode::Normal - : IndexMode::NonInteractive; - switch (event.type) { - case lsFileChangeType::Created: - case lsFileChangeType::Changed: { - pipeline::Index(path, {}, mode); - if (mode == IndexMode::Normal) - clang_complete->NotifySave(path); - else - clang_complete->OnClose(path); - break; - } - case lsFileChangeType::Deleted: - pipeline::Index(path, {}, mode); - clang_complete->OnClose(path); - break; - } - } - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeWatchedFiles); - -struct lsWorkspaceFoldersChangeEvent { - std::vector added, removed; -}; -MAKE_REFLECT_STRUCT(lsWorkspaceFoldersChangeEvent, added, removed); - -struct In_workspaceDidChangeWorkspaceFolders : public NotificationMessage { - MethodType GetMethodType() const override { - return didChangeWorkspaceFolders; - } - struct Params { - lsWorkspaceFoldersChangeEvent event; - } params; -}; -MAKE_REFLECT_STRUCT(In_workspaceDidChangeWorkspaceFolders::Params, event); -MAKE_REFLECT_STRUCT(In_workspaceDidChangeWorkspaceFolders, params); -REGISTER_IN_MESSAGE(In_workspaceDidChangeWorkspaceFolders); - -struct Handler_workspaceDidChangeWorkspaceFolders - : BaseMessageHandler { - MethodType GetMethodType() const override { - return didChangeWorkspaceFolders; - } - void Run(In_workspaceDidChangeWorkspaceFolders *request) override { - const auto &event = request->params.event; - for (const lsWorkspaceFolder &wf : event.removed) { - std::string root = wf.uri.GetPath(); - EnsureEndsInSlash(root); - LOG_S(INFO) << "delete workspace folder " << wf.name << ": " << root; - auto it = llvm::find(g_config->workspaceFolders, root); - if (it != g_config->workspaceFolders.end()) { - g_config->workspaceFolders.erase(it); - { - // auto &folder = project->root2folder[path]; - // FIXME delete - } - project->root2folder.erase(root); - } - } - for (const lsWorkspaceFolder &wf : event.added) { - std::string root = wf.uri.GetPath(); - EnsureEndsInSlash(root); - LOG_S(INFO) << "add workspace folder " << wf.name << ": " << root; - g_config->workspaceFolders.push_back(root); - project->Load(root); - } - - project->Index(working_files, lsRequestId()); - - clang_complete->FlushAllSessions(); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_workspaceDidChangeWorkspaceFolders); -} // namespace diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc deleted file mode 100644 index e87d7c6f3..000000000 --- a/src/messages/workspace_symbol.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "fuzzy_match.h" -#include "message_handler.h" -#include "pipeline.hh" -#include "query_utils.h" - -#include -#include -#include -#include - -using namespace ccls; - -namespace { -MethodType kMethodType = "workspace/symbol"; - -// Lookup |symbol| in |db| and insert the value into |result|. -bool AddSymbol( - DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed, - std::vector> *result) { - std::optional info = GetSymbolInfo(db, sym, true); - if (!info) - return false; - - Use loc; - if (Maybe dr = GetDefinitionSpell(db, sym)) - loc = *dr; - else { - auto decls = GetNonDefDeclarations(db, sym); - if (decls.empty()) - return false; - loc = decls[0]; - } - - std::optional ls_location = GetLsLocation(db, working_files, loc); - if (!ls_location) - return false; - info->location = *ls_location; - result->emplace_back(*info, int(use_detailed), sym); - return true; -} - -struct In_WorkspaceSymbol : public RequestMessage { - MethodType GetMethodType() const override { return kMethodType; } - struct Params { - std::string query; - }; - Params params; -}; -MAKE_REFLECT_STRUCT(In_WorkspaceSymbol::Params, query); -MAKE_REFLECT_STRUCT(In_WorkspaceSymbol, id, params); -REGISTER_IN_MESSAGE(In_WorkspaceSymbol); - - -struct Handler_WorkspaceSymbol : BaseMessageHandler { - MethodType GetMethodType() const override { return kMethodType; } - void Run(In_WorkspaceSymbol *request) override { - std::vector result; - std::string query = request->params.query; - - // {symbol info, matching detailed_name or short_name, index} - std::vector> cands; - bool sensitive = g_config->workspaceSymbol.caseSensitivity; - - // Find subsequence matches. - std::string query_without_space; - query_without_space.reserve(query.size()); - for (char c : query) - if (!isspace(c)) - query_without_space += c; - - auto Add = [&](SymbolIdx sym) { - std::string_view detailed_name = db->GetSymbolName(sym, true); - int pos = - ReverseSubseqMatch(query_without_space, detailed_name, sensitive); - return pos >= 0 && - AddSymbol(db, working_files, sym, - detailed_name.find(':', pos) != std::string::npos, - &cands) && - cands.size() >= g_config->workspaceSymbol.maxNum; - }; - for (auto &func : db->funcs) - if (Add({func.usr, SymbolKind::Func})) - goto done_add; - for (auto &type : db->types) - if (Add({type.usr, SymbolKind::Type})) - goto done_add; - for (auto &var : db->vars) - if (var.def.size() && !var.def[0].is_local() && - Add({var.usr, SymbolKind::Var})) - goto done_add; - done_add: - - if (g_config->workspaceSymbol.sort && - query.size() <= FuzzyMatcher::kMaxPat) { - // Sort results with a fuzzy matching algorithm. - int longest = 0; - for (auto &cand : cands) - longest = std::max( - longest, int(db->GetSymbolName(std::get<2>(cand), true).size())); - FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); - for (auto &cand : cands) - std::get<1>(cand) = fuzzy.Match( - db->GetSymbolName(std::get<2>(cand), std::get<1>(cand))); - std::sort(cands.begin(), cands.end(), [](const auto &l, const auto &r) { - return std::get<1>(l) > std::get<1>(r); - }); - result.reserve(cands.size()); - for (auto &cand : cands) { - // Discard awful candidates. - if (std::get<1>(cand) <= FuzzyMatcher::kMinScore) - break; - result.push_back(std::get<0>(cand)); - } - } else { - result.reserve(cands.size()); - for (auto &cand : cands) - result.push_back(std::get<0>(cand)); - } - - pipeline::Reply(request->id, result); - } -}; -REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); -} // namespace diff --git a/src/pipeline.cc b/src/pipeline.cc index ed674646b..586e4ece0 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -19,15 +19,16 @@ limitations under the License. #include "config.h" #include "include_complete.h" #include "log.hh" -#include "lsp.h" +#include "lsp.hh" #include "match.h" -#include "message_handler.h" +#include "message_handler.hh" #include "pipeline.hh" #include "platform.h" -#include "project.h" +#include "project.hh" #include "query_utils.h" #include "serializers/json.h" +#include #include #include @@ -43,9 +44,7 @@ using namespace llvm; #include #endif -void StandaloneInitialize(const std::string &, Project &, WorkingFiles &, VFS &, - IncludeComplete &); - +namespace ccls { void VFS::Clear() { std::lock_guard lock(mutex); state.clear(); @@ -67,7 +66,10 @@ bool VFS::Stamp(const std::string &path, int64_t ts, int step) { return false; } -namespace ccls::pipeline { +struct MessageHandler; +void StandaloneInitialize(MessageHandler &, const std::string &root); + +namespace pipeline { std::atomic loaded_ts = ATOMIC_VAR_INIT(0), pending_index_requests = ATOMIC_VAR_INIT(0); @@ -86,7 +88,7 @@ struct Index_Request { MultiQueueWaiter *main_waiter; MultiQueueWaiter *indexer_waiter; MultiQueueWaiter *stdout_waiter; -ThreadedQueue> *on_request; +ThreadedQueue *on_request; ThreadedQueue *index_request; ThreadedQueue *on_indexed; ThreadedQueue *for_stdout; @@ -357,7 +359,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, void Init() { main_waiter = new MultiQueueWaiter; - on_request = new ThreadedQueue>(main_waiter); + on_request = new ThreadedQueue(main_waiter); on_indexed = new ThreadedQueue(main_waiter); indexer_waiter = new MultiQueueWaiter; @@ -414,35 +416,53 @@ void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { void LaunchStdin() { std::thread([]() { set_thread_name("stdin"); + std::string str; while (true) { - std::unique_ptr message; - std::optional error = - MessageRegistry::instance()->ReadMessageFromStdin(&message); - - // Message parsing can fail if we don't recognize the method. - if (error) { - // The message may be partially deserialized. - // Emit an error ResponseMessage if |id| is available. - if (message) { - lsRequestId id = message->GetRequestId(); - if (id.Valid()) { - lsResponseError err; - err.code = lsErrorCodes::InvalidParams; - err.message = std::move(*error); - ReplyError(id, err); - } + constexpr std::string_view kContentLength("Content-Length: "); + int len = 0; + str.clear(); + while (true) { + int c = getchar(); + if (c == EOF) + return; + if (c == '\n') { + if (str.empty()) + break; + if (!str.compare(0, kContentLength.size(), kContentLength)) + len = atoi(str.c_str() + kContentLength.size()); + str.clear(); + } else if (c != '\r') { + str += c; } - continue; } - // Cache |method_id| so we can access it after moving |message|. - MethodType method_type = message->GetMethodType(); - - on_request->PushBack(std::move(message)); + str.resize(len); + for (int i = 0; i < len; ++i) { + int c = getchar(); + if (c == EOF) + return; + str[i] = c; + } - // If the message was to exit then querydb will take care of the actual - // exit. Stop reading from stdin since it might be detached. - if (method_type == kMethodType_Exit) + auto message = std::make_unique(len); + std::copy(str.begin(), str.end(), message.get()); + auto document = std::make_unique(); + document->Parse(message.get(), len); + assert(!document->HasParseError()); + + JsonReader reader{document.get()}; + if (!reader.HasMember("jsonrpc") || + std::string(reader["jsonrpc"]->GetString()) != "2.0") + return; + lsRequestId id; + std::string method; + ReflectMember(reader, "id", id); + ReflectMember(reader, "method", method); + auto param = std::make_unique(); + on_request->PushBack( + {id, std::move(method), std::move(message), std::move(document)}); + + if (method == "exit") break; } }) @@ -491,31 +511,20 @@ void MainLoop() { DB db; // Setup shared references. - for (MessageHandler *handler : *MessageHandler::message_handlers) { - handler->db = &db; - handler->project = &project; - handler->vfs = &vfs; - handler->working_files = &working_files; - handler->clang_complete = &clang_complete; - handler->include_complete = &include_complete; - } + MessageHandler handler; + handler.db = &db; + handler.project = &project; + handler.vfs = &vfs; + handler.working_files = &working_files; + handler.clang_complete = &clang_complete; + handler.include_complete = &include_complete; bool has_indexed = false; while (true) { - std::vector> messages = on_request->DequeueAll(); + std::vector messages = on_request->DequeueAll(); bool did_work = messages.size(); - for (auto &message : messages) { - // TODO: Consider using std::unordered_map to lookup the handler - for (MessageHandler *handler : *MessageHandler::message_handlers) { - if (handler->GetMethodType() == message->GetMethodType()) { - handler->Run(std::move(message)); - break; - } - } - - if (message) - LOG_S(ERROR) << "No handler for " << message->GetMethodType(); - } + for (InMessage &message : messages) + handler.Run(message); bool indexed = false; for (int i = 20; i--;) { @@ -544,7 +553,14 @@ void Standalone(const std::string &root) { WorkingFiles wfiles; VFS vfs; IncludeComplete complete(&project); - StandaloneInitialize(root, project, wfiles, vfs, complete); + + MessageHandler handler; + handler.project = &project; + handler.working_files = &wfiles; + handler.vfs = &vfs; + handler.include_complete = &complete; + + StandaloneInitialize(handler, root); bool tty = sys::Process::StandardOutIsDisplayed(); if (tty) { @@ -634,5 +650,5 @@ void Reply(lsRequestId id, const std::function &fn) { void ReplyError(lsRequestId id, const std::function &fn) { Reply(id, "error", fn); } - -} // namespace ccls::pipeline +} // namespace pipeline +} // namespace ccls diff --git a/src/pipeline.hh b/src/pipeline.hh index 112e8bb9c..641b1f597 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,6 +1,6 @@ #pragma once -#include "lsp.h" +#include "lsp.hh" #include "query.h" #include @@ -9,9 +9,9 @@ #include #include +namespace ccls { struct CompletionManager; struct GroupMatch; -struct VFS; struct Project; struct WorkingFiles; @@ -29,7 +29,6 @@ struct VFS { bool Stamp(const std::string &path, int64_t ts, int step); }; -namespace ccls { enum class IndexMode { NonInteractive, OnChange, diff --git a/src/position.cc b/src/position.cc index 96292ef1d..54e72c580 100644 --- a/src/position.cc +++ b/src/position.cc @@ -15,12 +15,13 @@ limitations under the License. #include "position.h" -#include "serializer.h" +#include "serializer.hh" #include #include #include +namespace ccls { Position Position::FromString(const std::string &encoded) { char *p = const_cast(encoded.c_str()); int16_t line = int16_t(strtol(p, &p, 10)) - 1; @@ -112,3 +113,4 @@ void Reflect(Writer &visitor, Range &value) { Reflect(visitor, value.end.column); } } +} // namespace ccls diff --git a/src/position.h b/src/position.h index 5ff535155..04f8cc5c0 100644 --- a/src/position.h +++ b/src/position.h @@ -21,6 +21,7 @@ limitations under the License. #include #include +namespace ccls { struct Position { int16_t line = -1; int16_t column = -1; @@ -42,7 +43,6 @@ struct Position { } bool operator<=(const Position &o) const { return !(o < *this); } }; -MAKE_HASHABLE(Position, t.line, t.column); struct Range { Position start; @@ -64,24 +64,27 @@ struct Range { } }; +// Reflection +class Reader; +class Writer; +void Reflect(Reader &visitor, Position &value); +void Reflect(Writer &visitor, Position &value); +void Reflect(Reader &visitor, Range &value); +void Reflect(Writer &visitor, Range &value); +} // namespace ccls + namespace std { -template <> struct hash { - std::size_t operator()(Range x) const { +template <> struct hash { + std::size_t operator()(ccls::Range x) const { union U { - Range range = {}; + ccls::Range range = {}; uint64_t u64; } u; - static_assert(sizeof(Range) == 8); + static_assert(sizeof(ccls::Range) == 8); u.range = x; return hash()(u.u64); } }; } // namespace std -// Reflection -class Reader; -class Writer; -void Reflect(Reader &visitor, Position &value); -void Reflect(Writer &visitor, Position &value); -void Reflect(Reader &visitor, Range &value); -void Reflect(Writer &visitor, Range &value); +MAKE_HASHABLE(ccls::Position, t.line, t.column); diff --git a/src/project.cc b/src/project.cc index 1bcededa2..5c65f0a79 100644 --- a/src/project.cc +++ b/src/project.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "project.h" +#include "project.hh" #include "filesystem.hh" #include "log.hh" @@ -43,10 +43,10 @@ limitations under the License. #include #include -using namespace ccls; using namespace clang; using namespace llvm; +namespace ccls { std::pair lookupExtension(std::string_view filename) { using namespace clang::driver; auto I = types::lookupTypeForExtension( @@ -485,3 +485,4 @@ void Project::Index(WorkingFiles *wfiles, lsRequestId id) { // trigger refreshing semantic highlight for all working files. pipeline::Index("", {}, IndexMode::NonInteractive); } +} // namespace ccls diff --git a/src/project.h b/src/project.hh similarity index 97% rename from src/project.h rename to src/project.hh index d3786aa21..0d6ed8c08 100644 --- a/src/project.h +++ b/src/project.hh @@ -16,7 +16,7 @@ limitations under the License. #pragma once #include "config.h" -#include "lsp.h" +#include "lsp.hh" #include #include @@ -24,6 +24,7 @@ limitations under the License. #include #include +namespace ccls { struct WorkingFiles; std::pair lookupExtension(std::string_view filename); @@ -76,3 +77,4 @@ struct Project { void Index(WorkingFiles *wfiles, lsRequestId id); }; +} // namespace ccls diff --git a/src/query.cc b/src/query.cc index 19889465f..360df79a2 100644 --- a/src/query.cc +++ b/src/query.cc @@ -16,7 +16,7 @@ limitations under the License. #include "query.h" #include "indexer.h" -#include "serializer.h" +#include "serializer.hh" #include "serializers/json.h" #include @@ -27,8 +27,8 @@ limitations under the License. #include #include +namespace ccls { namespace { - void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) { if (use.file_id == -1) use.file_id = file_id; @@ -468,3 +468,4 @@ std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) { } return ""; } +} // namespace ccls diff --git a/src/query.h b/src/query.h index 9ba3898b3..5da593aaf 100644 --- a/src/query.h +++ b/src/query.h @@ -16,22 +16,25 @@ limitations under the License. #pragma once #include "indexer.h" -#include "serializer.h" +#include "serializer.hh" #include #include namespace llvm { -template <> struct DenseMapInfo { - static inline ExtentRef getEmptyKey() { return {}; } - static inline ExtentRef getTombstoneKey() { return {{Range(), Usr(-1)}}; } - static unsigned getHashValue(ExtentRef sym) { - return std::hash()(sym); +template <> struct DenseMapInfo { + static inline ccls::ExtentRef getEmptyKey() { return {}; } + static inline ccls::ExtentRef getTombstoneKey() { + return {{ccls::Range(), ccls::Usr(-1)}}; } - static bool isEqual(ExtentRef l, ExtentRef r) { return l == r; } + static unsigned getHashValue(ccls::ExtentRef sym) { + return std::hash()(sym); + } + static bool isEqual(ccls::ExtentRef l, ccls::ExtentRef r) { return l == r; } }; -} +} // namespace llvm +namespace ccls { struct QueryFile { struct Def { std::string path; @@ -192,3 +195,4 @@ struct DB { QueryType &GetType(SymbolIdx ref) { return Type(ref.usr); } QueryVar &GetVar(SymbolIdx ref) { return Var(ref.usr); } }; +} // namespace ccls diff --git a/src/query_utils.cc b/src/query_utils.cc index 3da47b352..dbc4bbdf9 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -20,6 +20,7 @@ limitations under the License. #include #include +namespace ccls { namespace { // Computes roughly how long |range| is. @@ -342,3 +343,4 @@ std::vector FindSymbolsAtLocation(WorkingFile *wfile, return symbols; } +} // namespace ccls diff --git a/src/query_utils.h b/src/query_utils.h index 55baa6a47..1a202044b 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -20,6 +20,7 @@ limitations under the License. #include +namespace ccls { Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) @@ -102,3 +103,4 @@ void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { fn(obj); } } +} // namespace ccls diff --git a/src/serializer.cc b/src/serializer.cc index 8c813430b..9540aa7f7 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "serializer.h" +#include "serializer.hh" #include "filesystem.hh" #include "indexer.h" @@ -27,11 +27,11 @@ limitations under the License. #include #include -using namespace ccls; using namespace llvm; bool gTestOutputMode = false; +namespace ccls { Reader::~Reader() {} BinaryReader::~BinaryReader() {} JsonReader::~JsonReader() {} @@ -362,7 +362,6 @@ void Reflect(Writer &visitor, SerializeFormat &value) { } } -namespace ccls { static BumpPtrAllocator Alloc; static DenseSet Strings; static std::mutex AllocMutex; diff --git a/src/serializer.h b/src/serializer.hh similarity index 98% rename from src/serializer.h rename to src/serializer.hh index ae111444d..370a26d1a 100644 --- a/src/serializer.h +++ b/src/serializer.hh @@ -35,6 +35,7 @@ class CachedHashStringRef; class StringRef; } +namespace ccls { enum class SerializeFormat { Binary, Json }; struct JsonNull {}; @@ -103,12 +104,12 @@ struct IndexFile; #define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &visitor, type &value) { \ as_type value0; \ - ::Reflect(visitor, value0); \ + ::ccls::Reflect(visitor, value0); \ value = static_cast(value0); \ } \ LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &visitor, type &value) { \ auto value0 = static_cast(value); \ - ::Reflect(visitor, value0); \ + ::ccls::Reflect(visitor, value0); \ } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); @@ -305,7 +306,6 @@ template void ReflectMember(Writer &vis, const char *name, T &v) { // API -namespace ccls { const char *Intern(llvm::StringRef str); llvm::CachedHashStringRef InternH(llvm::StringRef str); std::string Serialize(SerializeFormat format, IndexFile &file); diff --git a/src/serializers/binary.h b/src/serializers/binary.h index 7a1e478cc..e995ec444 100644 --- a/src/serializers/binary.h +++ b/src/serializers/binary.h @@ -15,10 +15,11 @@ limitations under the License. #pragma once -#include "serializer.h" +#include "serializer.hh" #include +namespace ccls { class BinaryReader : public Reader { const char *p_; @@ -135,3 +136,4 @@ class BinaryWriter : public Writer { void EndObject() override {} void Key(const char *name) override {} }; +} // namespace ccls diff --git a/src/serializers/json.h b/src/serializers/json.h index e987902f0..a1d29b728 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -15,11 +15,12 @@ limitations under the License. #pragma once -#include "serializer.h" +#include "serializer.hh" #include #include +namespace ccls { class JsonReader : public Reader { rapidjson::GenericValue> *m_; std::vector path_; @@ -116,3 +117,4 @@ class JsonWriter : public Writer { void EndObject() override { m_->EndObject(); } void Key(const char *name) override { m_->Key(name); } }; +} // namespace ccls diff --git a/src/test.cc b/src/test.cc index 57af162c7..2a31dd448 100644 --- a/src/test.cc +++ b/src/test.cc @@ -20,7 +20,7 @@ limitations under the License. #include "indexer.h" #include "pipeline.hh" #include "platform.h" -#include "serializer.h" +#include "serializer.hh" #include "utils.h" #include @@ -44,6 +44,7 @@ using namespace llvm; extern bool gTestOutputMode; +namespace ccls { std::string ToString(const rapidjson::Document &document) { rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); @@ -373,3 +374,4 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { return success; } +} // namespace ccls diff --git a/src/test.h b/src/test.h index d22f1edd2..d7221537f 100644 --- a/src/test.h +++ b/src/test.h @@ -17,4 +17,6 @@ limitations under the License. #include +namespace ccls { bool RunIndexTests(const std::string &filter_path, bool enable_update); +} diff --git a/src/threaded_queue.h b/src/threaded_queue.h index d72f06d7b..603ed5f87 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -25,17 +25,18 @@ limitations under the License. #include #include -struct BaseThreadQueue { - virtual bool IsEmpty() = 0; - virtual ~BaseThreadQueue() = default; -}; - // std::lock accepts two or more arguments. We define an overload for one // argument. namespace std { template void lock(Lockable &l) { l.lock(); } } // namespace std +namespace ccls { +struct BaseThreadQueue { + virtual bool IsEmpty() = 0; + virtual ~BaseThreadQueue() = default; +}; + template struct MultiQueueLock { MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); } ~MultiQueueLock() { unlock(); } @@ -173,3 +174,4 @@ template struct ThreadedQueue : public BaseThreadQueue { MultiQueueWaiter *waiter_; std::unique_ptr owned_waiter_; }; +} // namespace ccls diff --git a/src/utils.cc b/src/utils.cc index 6a2f9e50c..68c7c83be 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -33,6 +33,7 @@ using namespace llvm; #include #include +namespace ccls { uint64_t HashUsr(std::string_view s) { union { uint64_t ret; @@ -174,3 +175,4 @@ int ReverseSubseqMatch(std::string_view pat, std::string_view text, } std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; } +} diff --git a/src/utils.h b/src/utils.h index 85e74c1d0..1bf9ed372 100644 --- a/src/utils.h +++ b/src/utils.h @@ -26,6 +26,7 @@ namespace llvm { class StringRef; } +namespace ccls { uint64_t HashUsr(std::string_view s); uint64_t HashUsr(llvm::StringRef s); @@ -81,10 +82,11 @@ inline void hash_combine(std::size_t &seed, const T &v, Rest... rest) { template <> struct hash { \ std::size_t operator()(const type &t) const { \ std::size_t ret = 0; \ - hash_combine(ret, __VA_ARGS__); \ + ccls::hash_combine(ret, __VA_ARGS__); \ return ret; \ } \ }; \ } std::string GetDefaultResourceDirectory(); +} // namespace ccls diff --git a/src/working_files.cc b/src/working_files.cc index f3ec44f89..b7d19199f 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -23,6 +23,7 @@ limitations under the License. #include #include +namespace ccls { namespace { // When finding a best match of buffer line and index line, limit the max edit @@ -468,7 +469,7 @@ WorkingFile *WorkingFiles::OnOpen(const lsTextDocumentItem &open) { return files[files.size() - 1].get(); } -void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams &change) { +void WorkingFiles::OnChange(const TextDocumentDidChangeParam &change) { std::lock_guard lock(files_mutex); std::string filename = change.textDocument.uri.GetPath(); @@ -483,7 +484,7 @@ void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams &change) { if (change.textDocument.version) file->version = *change.textDocument.version; - for (const lsTextDocumentContentChangeEvent &diff : change.contentChanges) { + for (const TextDocumentContentChangeEvent &diff : change.contentChanges) { // Per the spec replace everything if the rangeLength and range are not set. // See https://github.com/Microsoft/language-server-protocol/issues/9. if (!diff.range) { @@ -575,3 +576,4 @@ std::string_view LexIdentifierAroundPos(lsPosition position, return content.substr(start, end - start); } +} diff --git a/src/working_files.h b/src/working_files.h index 1767789e4..0784e5934 100644 --- a/src/working_files.h +++ b/src/working_files.h @@ -15,13 +15,14 @@ limitations under the License. #pragma once -#include "lsp.h" +#include "lsp.hh" #include "utils.h" #include #include #include +namespace ccls { struct WorkingFile { int version = 0; std::string filename; @@ -117,7 +118,7 @@ struct WorkingFiles { const std::function &action); WorkingFile *OnOpen(const lsTextDocumentItem &open); - void OnChange(const lsTextDocumentDidChangeParams &change); + void OnChange(const TextDocumentDidChangeParam &change); void OnClose(const lsTextDocumentIdentifier &close); // If |filter_paths| is non-empty, only files which contain any of the given @@ -135,3 +136,4 @@ int GetOffsetForPosition(lsPosition position, std::string_view content); std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content); +} // namespace ccls From df20969788cdb542696bc6d76a2846e0898b1e10 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 28 Oct 2018 21:21:21 -0700 Subject: [PATCH 275/378] *.h -> *.hh --- src/clang_complete.cc | 16 +++++----- src/clang_complete.hh | 10 +++---- src/clang_tu.cc | 4 +-- src/clang_tu.hh | 2 +- src/config.cc | 2 +- src/{config.h => config.hh} | 0 src/filesystem.cc | 2 +- src/fuzzy_match.cc | 2 +- src/{fuzzy_match.h => fuzzy_match.hh} | 0 src/include_complete.cc | 6 ++-- ...include_complete.h => include_complete.hh} | 0 src/indexer.cc | 6 ++-- src/{indexer.h => indexer.hh} | 6 ++-- src/{lru_cache.h => lru_cache.hh} | 0 src/lsp.cc | 2 +- src/lsp.hh | 4 +-- src/main.cc | 8 ++--- src/match.cc | 2 +- src/{match.h => match.hh} | 0 src/{maybe.h => maybe.hh} | 0 src/message_handler.cc | 6 ++-- src/message_handler.hh | 4 +-- src/messages/ccls_call.cc | 8 ++--- src/messages/ccls_info.cc | 2 +- src/messages/ccls_inheritance.cc | 8 ++--- src/messages/ccls_member.cc | 22 +++++++------- src/messages/ccls_navigate.cc | 4 +-- src/messages/ccls_reload.cc | 6 ++-- src/messages/ccls_vars.cc | 6 ++-- src/messages/initialize.cc | 12 ++++---- src/messages/textDocument_code.cc | 12 ++++---- src/messages/textDocument_completion.cc | 8 ++--- src/messages/textDocument_definition.cc | 14 ++++----- src/messages/textDocument_did.cc | 10 +++---- src/messages/textDocument_document.cc | 12 ++++---- src/messages/textDocument_foldingRange.cc | 6 ++-- src/messages/textDocument_formatting.cc | 8 ++--- src/messages/textDocument_hover.cc | 6 ++-- src/messages/textDocument_references.cc | 6 ++-- src/messages/textDocument_rename.cc | 12 ++++---- src/messages/textDocument_signatureHelp.cc | 2 +- src/messages/workspace.cc | 16 +++++----- src/pipeline.cc | 30 +++++++++---------- src/pipeline.hh | 2 +- src/{platform.h => platform.hh} | 0 src/platform_posix.cc | 4 +-- src/platform_win.cc | 4 +-- src/position.cc | 2 +- src/{position.h => position.hh} | 4 +-- src/project.cc | 10 +++---- src/project.hh | 2 +- src/query.cc | 6 ++-- src/{query.h => query.hh} | 2 +- src/query_utils.cc | 2 +- src/{query_utils.h => query_utils.hh} | 4 +-- src/serializer.cc | 6 ++-- src/serializer.hh | 2 +- src/serializers/{binary.h => binary.hh} | 0 src/serializers/{json.h => json.hh} | 0 src/test.cc | 8 ++--- src/{test.h => test.hh} | 0 src/{threaded_queue.h => threaded_queue.hh} | 2 +- src/utils.cc | 4 +-- src/{utils.h => utils.hh} | 0 src/working_files.cc | 4 +-- src/{working_files.h => working_files.hh} | 2 +- 66 files changed, 181 insertions(+), 181 deletions(-) rename src/{config.h => config.hh} (100%) rename src/{fuzzy_match.h => fuzzy_match.hh} (100%) rename src/{include_complete.h => include_complete.hh} (100%) rename src/{indexer.h => indexer.hh} (99%) rename src/{lru_cache.h => lru_cache.hh} (100%) rename src/{match.h => match.hh} (100%) rename src/{maybe.h => maybe.hh} (100%) rename src/{platform.h => platform.hh} (100%) rename src/{position.h => position.hh} (98%) rename src/{query.h => query.hh} (99%) rename src/{query_utils.h => query_utils.hh} (98%) rename src/serializers/{binary.h => binary.hh} (100%) rename src/serializers/{json.h => json.hh} (100%) rename src/{test.h => test.hh} (100%) rename src/{threaded_queue.h => threaded_queue.hh} (99%) rename src/{utils.h => utils.hh} (100%) rename src/{working_files.h => working_files.hh} (99%) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 615162b35..8c2e5eecb 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -18,8 +18,8 @@ limitations under the License. #include "clang_tu.hh" #include "filesystem.hh" #include "log.hh" -#include "match.h" -#include "platform.h" +#include "match.hh" +#include "platform.hh" #include #include @@ -417,7 +417,7 @@ void *CompletionMain(void *manager_) { DiagnosticConsumer DC; WorkingFiles::Snapshot snapshot = - manager->working_files_->AsSnapshot({StripFileType(path)}); + manager->wfiles_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, preamble.get(), snapshot, Bufs); @@ -491,7 +491,7 @@ void *DiagnosticMain(void *manager_) { CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; StoreDiags DC(path); WorkingFiles::Snapshot snapshot = - manager->working_files_->AsSnapshot({StripFileType(path)}); + manager->wfiles_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, preamble.get(), snapshot, Bufs); @@ -575,10 +575,10 @@ std::shared_ptr CompletionSession::GetPreamble() { } CompletionManager::CompletionManager(Project *project, - WorkingFiles *working_files, + WorkingFiles *wfiles, OnDiagnostic on_diagnostic, OnDropped on_dropped) - : project_(project), working_files_(working_files), + : project_(project), wfiles_(wfiles), on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), preloads(kMaxPreloadedSessions), sessions(kMaxCompletionSessions), @@ -637,7 +637,7 @@ bool CompletionManager::EnsureCompletionOrCreatePreloadSession( // No CompletionSession, create new one. auto session = std::make_shared( - project_->FindEntry(path, false), working_files_, PCH); + project_->FindEntry(path, false), wfiles_, PCH); if (session->file.filename != path) { session->inferred = true; session->file.filename = path; @@ -666,7 +666,7 @@ CompletionManager::TryGetSession(const std::string &path, bool preload, session = sessions.TryGet(path); if (!session && !preload) { session = std::make_shared( - project_->FindEntry(path, false), working_files_, PCH); + project_->FindEntry(path, false), wfiles_, PCH); sessions.Insert(path, session); LOG_S(INFO) << "create session for " << path; if (is_open) diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 3c5145f80..336cff1c0 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -16,11 +16,11 @@ limitations under the License. #pragma once #include "clang_tu.hh" -#include "lru_cache.h" +#include "lru_cache.hh" #include "lsp.hh" #include "project.hh" -#include "threaded_queue.h" -#include "working_files.h" +#include "threaded_queue.hh" +#include "working_files.hh" #include #include @@ -108,7 +108,7 @@ struct CompletionManager { int64_t debounce; }; - CompletionManager(Project *project, WorkingFiles *working_files, + CompletionManager(Project *project, WorkingFiles *wfiles, OnDiagnostic on_diagnostic, OnDropped on_dropped); // Request a diagnostics update. @@ -141,7 +141,7 @@ struct CompletionManager { // Global state. Project *project_; - WorkingFiles *working_files_; + WorkingFiles *wfiles_; OnDiagnostic on_diagnostic_; OnDropped on_dropped_; diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 2a9b05504..cc3437f6f 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -15,8 +15,8 @@ limitations under the License. #include "clang_tu.hh" -#include "config.h" -#include "platform.h" +#include "config.hh" +#include "platform.hh" #include #include diff --git a/src/clang_tu.hh b/src/clang_tu.hh index d88c836e1..2bfa23659 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "position.h" +#include "position.hh" #include #include diff --git a/src/config.cc b/src/config.cc index 489c87819..fd607730d 100644 --- a/src/config.cc +++ b/src/config.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "config.h" +#include "config.hh" namespace ccls { Config *g_config; diff --git a/src/config.h b/src/config.hh similarity index 100% rename from src/config.h rename to src/config.hh diff --git a/src/filesystem.cc b/src/filesystem.cc index d2cd1b3ca..fb463b989 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -16,7 +16,7 @@ limitations under the License. #include "filesystem.hh" using namespace llvm; -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 62a8d24f4..680aa4acb 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "fuzzy_match.h" +#include "fuzzy_match.hh" #include #include diff --git a/src/fuzzy_match.h b/src/fuzzy_match.hh similarity index 100% rename from src/fuzzy_match.h rename to src/fuzzy_match.hh diff --git a/src/include_complete.cc b/src/include_complete.cc index b17756648..07c71b585 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -13,11 +13,11 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "include_complete.h" +#include "include_complete.hh" #include "filesystem.hh" -#include "match.h" -#include "platform.h" +#include "match.hh" +#include "platform.hh" #include "project.hh" #include diff --git a/src/include_complete.h b/src/include_complete.hh similarity index 100% rename from src/include_complete.h rename to src/include_complete.hh diff --git a/src/indexer.cc b/src/indexer.cc index 96137b2ad..43852a7f1 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -13,14 +13,14 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "indexer.h" +#include "indexer.hh" #include "clang_complete.hh" #include "clang_tu.hh" #include "log.hh" -#include "match.h" +#include "match.hh" #include "pipeline.hh" -#include "platform.h" +#include "platform.hh" #include "serializer.hh" #include diff --git a/src/indexer.h b/src/indexer.hh similarity index 99% rename from src/indexer.h rename to src/indexer.hh index 488eb9c09..cce9c2e6f 100644 --- a/src/indexer.h +++ b/src/indexer.hh @@ -16,10 +16,10 @@ limitations under the License. #pragma once #include "lsp.hh" -#include "maybe.h" -#include "position.h" +#include "maybe.hh" +#include "position.hh" #include "serializer.hh" -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/lru_cache.h b/src/lru_cache.hh similarity index 100% rename from src/lru_cache.h rename to src/lru_cache.hh diff --git a/src/lsp.cc b/src/lsp.cc index 6a55f1ae2..705d7817a 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -16,7 +16,7 @@ limitations under the License. #include "lsp.hh" #include "log.hh" -#include "serializers/json.h" +#include "serializers/json.hh" #include diff --git a/src/lsp.hh b/src/lsp.hh index c95607775..b28f322cc 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -15,9 +15,9 @@ limitations under the License. #pragma once -#include "config.h" +#include "config.hh" #include "serializer.hh" -#include "utils.h" +#include "utils.hh" #include diff --git a/src/main.cc b/src/main.cc index 8b728fbee..606e7ca1a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -15,11 +15,11 @@ limitations under the License. #include "log.hh" #include "pipeline.hh" -#include "platform.h" +#include "platform.hh" #include "serializer.hh" -#include "serializers/json.h" -#include "test.h" -#include "working_files.h" +#include "serializers/json.hh" +#include "test.hh" +#include "working_files.hh" #include #include diff --git a/src/match.cc b/src/match.cc index ad83396c0..125f2bba0 100644 --- a/src/match.cc +++ b/src/match.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "match.h" +#include "match.hh" #include "lsp.hh" #include "pipeline.hh" diff --git a/src/match.h b/src/match.hh similarity index 100% rename from src/match.h rename to src/match.hh diff --git a/src/maybe.h b/src/maybe.hh similarity index 100% rename from src/maybe.h rename to src/maybe.hh diff --git a/src/message_handler.cc b/src/message_handler.cc index b4b61a217..b85bdd507 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -16,11 +16,11 @@ limitations under the License. #include "message_handler.hh" #include "log.hh" -#include "match.h" +#include "match.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.h" -#include "serializers/json.h" +#include "query_utils.hh" +#include "serializers/json.hh" using namespace clang; diff --git a/src/message_handler.hh b/src/message_handler.hh index ad1c50095..8410390f1 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -16,7 +16,7 @@ limitations under the License. #pragma once #include "lsp.hh" -#include "query.h" +#include "query.hh" #include #include @@ -196,7 +196,7 @@ struct MessageHandler { DB *db = nullptr; Project *project = nullptr; VFS *vfs = nullptr; - WorkingFiles *working_files = nullptr; + WorkingFiles *wfiles = nullptr; CompletionManager *clang_complete = nullptr; IncludeComplete *include_complete = nullptr; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 3dacfddea..f22ee46b1 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -16,7 +16,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" +#include "query_utils.hh" #include @@ -85,7 +85,7 @@ bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, Out_cclsCall entry1; entry1.id = std::to_string(sym.usr); entry1.usr = sym.usr; - if (auto loc = GetLsLocation(m->db, m->working_files, + if (auto loc = GetLsLocation(m->db, m->wfiles, Use{{sym.range, sym.role}, file_id})) entry1.location = *loc; entry1.callType = call_type1; @@ -175,7 +175,7 @@ std::optional BuildInitial(MessageHandler *m, Usr root_usr, entry.usr = root_usr; entry.callType = CallType::Direct; if (def->spell) { - if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def->spell)) entry.location = *loc; } Expand(m, &entry, callee, call_type, qualified, levels); @@ -205,7 +205,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { if (!file) return; WorkingFile *working_file = - working_files->GetFileByFilename(file->def->path); + wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, param.position)) { if (sym.kind == SymbolKind::Func) { diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 19a68a2bf..664ff3d78 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -16,7 +16,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.h" +#include "query_utils.hh" namespace ccls { MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index a8ec0c59a..4afecee06 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -16,7 +16,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" +#include "query_utils.hh" #include @@ -64,10 +64,10 @@ bool ExpandHelper(MessageHandler *m, Out_cclsInheritance *entry, bool derived, if (def) { entry->name = def->Name(qualified); if (def->spell) { - if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def->spell)) entry->location = *loc; } else if (entity.declarations.size()) { - if (auto loc = GetLsLocation(m->db, m->working_files, entity.declarations[0])) + if (auto loc = GetLsLocation(m->db, m->wfiles, entity.declarations[0])) entry->location = *loc; } } else if (!derived) { @@ -150,7 +150,7 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = m->working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = m->wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index 35921cc94..c39fe7902 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -17,7 +17,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" +#include "query_utils.hh" #include #include @@ -90,7 +90,7 @@ void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var, } if (def1->spell) { if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } if (def1->type) { @@ -145,13 +145,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, if (def1 && def1->spell) { // The declaration of target type. if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (def->spell) { // Builtin types have no declaration but the typedef declaration // itself is useful. if (std::optional loc = - GetLsLocation(m->db, m->working_files, *def->spell)) + GetLsLocation(m->db, m->wfiles, *def->spell)) entry1.location = *loc; } if (def1 && qualified) @@ -173,10 +173,10 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, entry1.fieldName = def1->Name(false); if (def1->spell) { if (auto loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (func1.declarations.size()) { - if (auto loc = GetLsLocation(m->db, m->working_files, + if (auto loc = GetLsLocation(m->db, m->wfiles, func1.declarations[0])) entry1.location = *loc; } @@ -194,10 +194,10 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, entry1.fieldName = def1->Name(false); if (def1->spell) { if (auto loc = - GetLsLocation(m->db, m->working_files, *def1->spell)) + GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (type1.declarations.size()) { - if (auto loc = GetLsLocation(m->db, m->working_files, + if (auto loc = GetLsLocation(m->db, m->wfiles, type1.declarations[0])) entry1.location = *loc; } @@ -236,7 +236,7 @@ std::optional BuildInitial(MessageHandler *m, SymbolKind kind, // Not type, |id| is invalid. entry.name = def->Name(qualified); if (def->spell) { - if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def->spell)) entry.location = *loc; } for (Usr usr : def->vars) { @@ -255,7 +255,7 @@ std::optional BuildInitial(MessageHandler *m, SymbolKind kind, entry.id = std::to_string(root_usr); entry.usr = root_usr; if (def->spell) { - if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def->spell)) entry.location = *loc; } Expand(m, &entry, qualified, levels, memberKind); @@ -286,7 +286,7 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { switch (sym.kind) { diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index f4ca72bb9..be76d8baf 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.h" +#include "query_utils.hh" namespace ccls { namespace { @@ -46,7 +46,7 @@ void MessageHandler::ccls_navigate(Reader &reader, if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); lsPosition ls_pos = param.position; if (wfile && wfile->index_lines.size()) if (auto line = wfile->GetIndexPosFromBufferPos(ls_pos.line, diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 09772b6f0..4bb292e01 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -14,11 +14,11 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "match.h" +#include "match.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "working_files.h" +#include "working_files.hh" #include #include @@ -40,7 +40,7 @@ void MessageHandler::ccls_reload(Reader &reader) { if (param.whitelist.empty() && param.blacklist.empty()) { vfs->Clear(); db->clear(); - project->Index(working_files, lsRequestId()); + project->Index(wfiles, lsRequestId()); clang_complete->FlushAllSessions(); return; } diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 834106354..8b4531f2a 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" +#include "query_utils.hh" namespace ccls { namespace { @@ -34,7 +34,7 @@ void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); + WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); std::vector result; for (SymbolRef sym : @@ -52,7 +52,7 @@ void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { } case SymbolKind::Type: result = GetLsLocations( - db, working_files, + db, wfiles, GetVarDeclarations(db, db->Type(usr).instances, param.kind)); break; } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 08b8b0c39..1d5b7e70f 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -15,14 +15,14 @@ limitations under the License. #include "clang_complete.hh" #include "filesystem.hh" -#include "include_complete.h" +#include "include_complete.hh" #include "log.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "platform.h" +#include "platform.hh" #include "project.hh" -#include "serializers/json.h" -#include "working_files.h" +#include "serializers/json.hh" +#include "working_files.hh" #include #include @@ -361,7 +361,7 @@ void *Indexer(void *arg_) { std::string name = "indexer" + std::to_string(idx); set_thread_name(name.c_str()); pipeline::Indexer_Main(h->clang_complete, h->vfs, h->project, - h->working_files); + h->wfiles); return nullptr; } } // namespace @@ -457,7 +457,7 @@ void Initialize(MessageHandler *m, lsInitializeParams ¶m, ReplyOnce &reply) m->include_complete->Rescan(); LOG_S(INFO) << "dispatch initial index requests"; - m->project->Index(m->working_files, reply.id); + m->project->Index(m->wfiles, reply.id); } void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index ee46bc8a8..6bd2929b9 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -15,8 +15,8 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" -#include "serializers/json.h" +#include "query_utils.hh" +#include "serializers/json.hh" #include @@ -34,13 +34,13 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { WorkingFile *wfile = - working_files->GetFileByFilename(param.textDocument.uri.GetPath()); + wfiles->GetFileByFilename(param.textDocument.uri.GetPath()); if (!wfile) { return; } std::vector result; std::vector diagnostics; - working_files->DoAction([&]() { diagnostics = wfile->diagnostics_; }); + wfiles->DoAction([&]() { diagnostics = wfile->diagnostics_; }); for (lsDiagnostic &diag : diagnostics) if (diag.fixits_.size()) { CodeAction &cmd = result.emplace_back(); @@ -95,7 +95,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, QueryFile *file = FindFile(reply, path); WorkingFile *wfile = - file ? working_files->GetFileByFilename(file->def->path) : nullptr; + file ? wfiles->GetFileByFilename(file->def->path) : nullptr; if (!wfile) { return; } @@ -188,7 +188,7 @@ void MessageHandler::workspace_executeCommand(Reader &reader, std::vector result; auto Map = [&](auto &&uses) { for (auto &use : uses) - if (auto loc = GetLsLocation(db, working_files, use)) + if (auto loc = GetLsLocation(db, wfiles, use)) result.push_back(std::move(*loc)); }; switch (cmd.kind) { diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 5a2c2210c..dd4d0f486 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -14,12 +14,12 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "fuzzy_match.h" -#include "include_complete.h" +#include "fuzzy_match.hh" +#include "include_complete.hh" #include "log.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "working_files.h" +#include "working_files.hh" #include #include @@ -453,7 +453,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams ¶m, static CompleteConsumerCache> cache; lsCompletionList result; std::string path = param.textDocument.uri.GetPath(); - WorkingFile *file = working_files->GetFileByFilename(path); + WorkingFile *file = wfiles->GetFileByFilename(path); if (!file) { return; } diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 2660f222d..36eb2b765 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.h" +#include "query_utils.hh" #include #include @@ -54,7 +54,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, std::vector result; Maybe on_def; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); lsPosition &ls_pos = param.position; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { @@ -87,7 +87,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, if (uses.empty() && on_def) uses.push_back(*on_def); } - auto locs = GetLsLocations(db, working_files, uses); + auto locs = GetLsLocations(db, wfiles, uses); result.insert(result.end(), locs.begin(), locs.end()); } @@ -158,7 +158,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, if (best_sym.kind != SymbolKind::Invalid) { Maybe dr = GetDefinitionSpell(db, best_sym); assert(dr); - if (auto loc = GetLsLocation(db, working_files, *dr)) + if (auto loc = GetLsLocation(db, wfiles, *dr)) result.push_back(*loc); } } @@ -172,18 +172,18 @@ void MessageHandler::textDocument_typeDefinition( QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *working_file = working_files->GetFileByFilename(file->def->path); + WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); std::vector result; auto Add = [&](const QueryType &type) { for (const auto &def : type.def) if (def.spell) { - if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) + if (auto ls_loc = GetLsLocation(db, wfiles, *def.spell)) result.push_back(*ls_loc); } if (result.empty()) for (const DeclRef &dr : type.declarations) - if (auto ls_loc = GetLsLocation(db, working_files, dr)) + if (auto ls_loc = GetLsLocation(db, wfiles, dr)) result.push_back(*ls_loc); }; for (SymbolRef sym : diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index e38bc2c0b..0a8bbff1c 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -14,16 +14,16 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "include_complete.h" +#include "include_complete.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "working_files.h" +#include "working_files.hh" namespace ccls { void MessageHandler::textDocument_didChange(TextDocumentDidChangeParam ¶m) { std::string path = param.textDocument.uri.GetPath(); - working_files->OnChange(param); + wfiles->OnChange(param); if (g_config->index.onChange) pipeline::Index(path, {}, IndexMode::OnChange); clang_complete->NotifyView(path); @@ -33,13 +33,13 @@ void MessageHandler::textDocument_didChange(TextDocumentDidChangeParam ¶m) { void MessageHandler::textDocument_didClose(TextDocumentParam ¶m) { std::string path = param.textDocument.uri.GetPath(); - working_files->OnClose(param.textDocument); + wfiles->OnClose(param.textDocument); clang_complete->OnClose(path); } void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { std::string path = param.textDocument.uri.GetPath(); - WorkingFile *working_file = working_files->OnOpen(param.textDocument); + WorkingFile *working_file = wfiles->OnOpen(param.textDocument); if (std::optional cached_file_contents = pipeline::LoadIndexedContent(path)) working_file->SetIndexContent(*cached_file_contents); diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 16342b740..866599ebc 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.h" +#include "query_utils.hh" #include @@ -48,7 +48,7 @@ void MessageHandler::textDocument_documentHighlight( if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); std::vector result; std::vector syms = @@ -62,7 +62,7 @@ void MessageHandler::textDocument_documentHighlight( return usr == sym1.usr && kind == sym1.kind; })) continue; - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) { DocumentHighlight highlight; highlight.range = loc->range; if (sym.role & Role::Write) @@ -148,7 +148,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!wfile) return; @@ -158,7 +158,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, if (refcnt > 0 && (param.all || sym.extent.Valid()) && param.startLine <= sym.range.start.line && sym.range.start.line <= param.endLine) - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) + if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) result.push_back(loc->range); std::sort(result.begin(), result.end()); reply(result); @@ -250,7 +250,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, Ignore(db->GetType(sym).AnyDef())) || (sym.kind == SymbolKind::Var && Ignore(db->GetVar(sym).AnyDef()))) continue; - if (auto loc = GetLsLocation(db, working_files, sym, file_id)) { + if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) { info->location = *loc; result.push_back(*info); } diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index 7777226f8..dd7e05481 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -16,8 +16,8 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.h" -#include "working_files.h" +#include "query_utils.hh" +#include "working_files.hh" namespace ccls { namespace { @@ -34,7 +34,7 @@ void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!wfile) return; std::vector result; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 91d84e6ea..343699051 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "working_files.h" +#include "working_files.hh" #include #include @@ -87,7 +87,7 @@ void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!wfile) return; Format(reply, wfile, {0, (unsigned)wfile->buffer_content.size()}); @@ -98,7 +98,7 @@ void MessageHandler::textDocument_onTypeFormatting( QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!wfile) return; std::string_view code = wfile->buffer_content; @@ -114,7 +114,7 @@ void MessageHandler::textDocument_rangeFormatting( QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!wfile) return; std::string_view code = wfile->buffer_content; diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index b645c1383..044e822bd 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.h" +#include "query_utils.hh" namespace ccls { namespace { @@ -97,12 +97,12 @@ void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); Hover result; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { std::optional ls_range = GetLsRange( - working_files->GetFileByFilename(file->def->path), sym.range); + wfiles->GetFileByFilename(file->def->path), sym.range); if (!ls_range) continue; diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 9c4d0f630..5ccad7ae6 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.h" +#include "query_utils.hh" #include @@ -43,7 +43,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { if (!file) return; std::vector result; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); if (!file) return; @@ -64,7 +64,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { if (Role(use.role & param.context.role) == param.context.role && !(use.role & param.context.excludeRole) && seen_uses.insert(use).second) - if (auto loc = GetLsLocation(db, working_files, use)) { + if (auto loc = GetLsLocation(db, wfiles, use)) { result.push_back(*loc); } }; diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 0b87efc57..84cefa501 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -14,17 +14,17 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.h" +#include "query_utils.hh" namespace ccls { namespace { -lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, +lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, const std::string &new_text) { std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { std::optional ls_location = - GetLsLocation(db, working_files, use); + GetLsLocation(db, wfiles, use); if (!ls_location) return; @@ -39,7 +39,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files, const std::string &path = file.def->path; path_to_edit[file_id].textDocument.uri = lsDocumentUri::FromPath(path); - WorkingFile *working_file = working_files->GetFileByFilename(path); + WorkingFile *working_file = wfiles->GetFileByFilename(path); if (working_file) path_to_edit[file_id].textDocument.version = working_file->version; } @@ -67,10 +67,10 @@ void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { if (!file) return; - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); lsWorkspaceEdit result; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { - result = BuildWorkspaceEdit(db, working_files, sym, param.newName); + result = BuildWorkspaceEdit(db, wfiles, sym, param.newName); break; } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 32b7e3ffe..63bd4c832 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -156,7 +156,7 @@ void MessageHandler::textDocument_signatureHelp( std::string path = param.textDocument.uri.GetPath(); lsPosition begin_pos = param.position; - if (WorkingFile *file = working_files->GetFileByFilename(path)) { + if (WorkingFile *file = wfiles->GetFileByFilename(path)) { std::string completion_text; lsPosition end_pos = param.position; begin_pos = file->FindStableCompletionSource(param.position, diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index b0dc591b1..c1229cf4a 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -14,12 +14,12 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "fuzzy_match.h" +#include "fuzzy_match.hh" #include "log.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.h" +#include "query_utils.hh" #include @@ -34,7 +34,7 @@ MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { for (const std::string &folder : g_config->workspaceFolders) project->Load(folder); - project->Index(working_files, lsRequestId()); + project->Index(wfiles, lsRequestId()); clang_complete->FlushAllSessions(); }; @@ -43,7 +43,7 @@ void MessageHandler::workspace_didChangeWatchedFiles( DidChangeWatchedFilesParam ¶m) { for (auto &event : param.changes) { std::string path = event.uri.GetPath(); - IndexMode mode = working_files->GetFileByFilename(path) + IndexMode mode = wfiles->GetFileByFilename(path) ? IndexMode::Normal : IndexMode::NonInteractive; switch (event.type) { @@ -88,7 +88,7 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( project->Load(root); } - project->Index(working_files, lsRequestId()); + project->Index(wfiles, lsRequestId()); clang_complete->FlushAllSessions(); } @@ -96,7 +96,7 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( namespace { // Lookup |symbol| in |db| and insert the value into |result|. bool AddSymbol( - DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed, + DB *db, WorkingFiles *wfiles, SymbolIdx sym, bool use_detailed, std::vector> *result) { std::optional info = GetSymbolInfo(db, sym, true); if (!info) @@ -112,7 +112,7 @@ bool AddSymbol( loc = decls[0]; } - std::optional ls_location = GetLsLocation(db, working_files, loc); + std::optional ls_location = GetLsLocation(db, wfiles, loc); if (!ls_location) return false; info->location = *ls_location; @@ -141,7 +141,7 @@ void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, std::string_view detailed_name = db->GetSymbolName(sym, true); int pos = ReverseSubseqMatch(query_without_space, detailed_name, sensitive); return pos >= 0 && - AddSymbol(db, working_files, sym, + AddSymbol(db, wfiles, sym, detailed_name.find(':', pos) != std::string::npos, &cands) && cands.size() >= g_config->workspaceSymbol.maxNum; diff --git a/src/pipeline.cc b/src/pipeline.cc index 586e4ece0..867ccf18f 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -16,17 +16,17 @@ limitations under the License. #include "pipeline.hh" #include "clang_complete.hh" -#include "config.h" -#include "include_complete.h" +#include "config.hh" +#include "include_complete.hh" #include "log.hh" #include "lsp.hh" -#include "match.h" +#include "match.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "platform.h" +#include "platform.hh" #include "project.hh" -#include "query_utils.h" -#include "serializers/json.h" +#include "query_utils.hh" +#include "serializers/json.hh" #include #include @@ -377,12 +377,12 @@ void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, indexer_waiter->Wait(index_request); } -void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { +void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { if (update->refresh) { LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; - std::lock_guard lock(working_files->files_mutex); - for (auto &f : working_files->files) { + std::lock_guard lock(wfiles->files_mutex); + for (auto &f : wfiles->files) { std::string filename = LowerPathIfInsensitive(f->filename); if (db->name2file_id.find(filename) == db->name2file_id.end()) continue; @@ -401,7 +401,7 @@ void Main_OnIndexed(DB *db, WorkingFiles *working_files, IndexUpdate *update) { if (update->files_def_update) { auto &def_u = *update->files_def_update; if (WorkingFile *wfile = - working_files->GetFileByFilename(def_u.first.path)) { + wfiles->GetFileByFilename(def_u.first.path)) { // FIXME With index.onChange: true, use buffer_content only for // request.path wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content @@ -487,11 +487,11 @@ void LaunchStdout() { void MainLoop() { Project project; - WorkingFiles working_files; + WorkingFiles wfiles; VFS vfs; CompletionManager clang_complete( - &project, &working_files, + &project, &wfiles, [&](std::string path, std::vector diagnostics) { lsPublishDiagnosticsParams params; params.uri = lsDocumentUri::FromPath(path); @@ -515,7 +515,7 @@ void MainLoop() { handler.db = &db; handler.project = &project; handler.vfs = &vfs; - handler.working_files = &working_files; + handler.wfiles = &wfiles; handler.clang_complete = &clang_complete; handler.include_complete = &include_complete; @@ -533,7 +533,7 @@ void MainLoop() { break; did_work = true; indexed = true; - Main_OnIndexed(&db, &working_files, &*update); + Main_OnIndexed(&db, &wfiles, &*update); } if (did_work) @@ -556,7 +556,7 @@ void Standalone(const std::string &root) { MessageHandler handler; handler.project = &project; - handler.working_files = &wfiles; + handler.wfiles = &wfiles; handler.vfs = &vfs; handler.include_complete = &complete; diff --git a/src/pipeline.hh b/src/pipeline.hh index 641b1f597..6bd4d4d45 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,7 +1,7 @@ #pragma once #include "lsp.hh" -#include "query.h" +#include "query.hh" #include #include diff --git a/src/platform.h b/src/platform.hh similarity index 100% rename from src/platform.h rename to src/platform.hh diff --git a/src/platform_posix.cc b/src/platform_posix.cc index fbbd07493..9dd79726c 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -14,9 +14,9 @@ limitations under the License. ==============================================================================*/ #if defined(__unix__) || defined(__APPLE__) -#include "platform.h" +#include "platform.hh" -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/platform_win.cc b/src/platform_win.cc index 797644c8f..31ba74e93 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -14,9 +14,9 @@ limitations under the License. ==============================================================================*/ #if defined(_WIN32) -#include "platform.h" +#include "platform.hh" -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/position.cc b/src/position.cc index 54e72c580..cbf1352fb 100644 --- a/src/position.cc +++ b/src/position.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "position.h" +#include "position.hh" #include "serializer.hh" diff --git a/src/position.h b/src/position.hh similarity index 98% rename from src/position.h rename to src/position.hh index 04f8cc5c0..7d4477175 100644 --- a/src/position.h +++ b/src/position.hh @@ -15,8 +15,8 @@ limitations under the License. #pragma once -#include "maybe.h" -#include "utils.h" +#include "maybe.hh" +#include "utils.hh" #include #include diff --git a/src/project.cc b/src/project.cc index 5c65f0a79..14ba02d93 100644 --- a/src/project.cc +++ b/src/project.cc @@ -17,12 +17,12 @@ limitations under the License. #include "filesystem.hh" #include "log.hh" -#include "match.h" +#include "match.hh" #include "pipeline.hh" -#include "platform.h" -#include "serializers/json.h" -#include "utils.h" -#include "working_files.h" +#include "platform.hh" +#include "serializers/json.hh" +#include "utils.hh" +#include "working_files.hh" #include #include diff --git a/src/project.hh b/src/project.hh index 0d6ed8c08..b5018525b 100644 --- a/src/project.hh +++ b/src/project.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "config.h" +#include "config.hh" #include "lsp.hh" #include diff --git a/src/query.cc b/src/query.cc index 360df79a2..25e02d480 100644 --- a/src/query.cc +++ b/src/query.cc @@ -13,11 +13,11 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "query.h" +#include "query.hh" -#include "indexer.h" +#include "indexer.hh" #include "serializer.hh" -#include "serializers/json.h" +#include "serializers/json.hh" #include #include diff --git a/src/query.h b/src/query.hh similarity index 99% rename from src/query.h rename to src/query.hh index 5da593aaf..a1627af5f 100644 --- a/src/query.h +++ b/src/query.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "indexer.h" +#include "indexer.hh" #include "serializer.hh" #include diff --git a/src/query_utils.cc b/src/query_utils.cc index dbc4bbdf9..fb13bbcaf 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "query_utils.h" +#include "query_utils.hh" #include "pipeline.hh" diff --git a/src/query_utils.h b/src/query_utils.hh similarity index 98% rename from src/query_utils.h rename to src/query_utils.hh index 1a202044b..5db3be65e 100644 --- a/src/query_utils.h +++ b/src/query_utils.hh @@ -15,8 +15,8 @@ limitations under the License. #pragma once -#include "query.h" -#include "working_files.h" +#include "query.hh" +#include "working_files.hh" #include diff --git a/src/serializer.cc b/src/serializer.cc index 9540aa7f7..f2ac8e0f8 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -16,10 +16,10 @@ limitations under the License. #include "serializer.hh" #include "filesystem.hh" -#include "indexer.h" +#include "indexer.hh" #include "log.hh" -#include "serializers/binary.h" -#include "serializers/json.h" +#include "serializers/binary.hh" +#include "serializers/json.hh" #include #include diff --git a/src/serializer.hh b/src/serializer.hh index 370a26d1a..0cf25b092 100644 --- a/src/serializer.hh +++ b/src/serializer.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "maybe.h" +#include "maybe.hh" #include diff --git a/src/serializers/binary.h b/src/serializers/binary.hh similarity index 100% rename from src/serializers/binary.h rename to src/serializers/binary.hh diff --git a/src/serializers/json.h b/src/serializers/json.hh similarity index 100% rename from src/serializers/json.h rename to src/serializers/json.hh diff --git a/src/test.cc b/src/test.cc index 2a31dd448..d4229790c 100644 --- a/src/test.cc +++ b/src/test.cc @@ -13,15 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "test.h" +#include "test.hh" #include "clang_complete.hh" #include "filesystem.hh" -#include "indexer.h" +#include "indexer.hh" #include "pipeline.hh" -#include "platform.h" +#include "platform.hh" #include "serializer.hh" -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/test.h b/src/test.hh similarity index 100% rename from src/test.h rename to src/test.hh diff --git a/src/threaded_queue.h b/src/threaded_queue.hh similarity index 99% rename from src/threaded_queue.h rename to src/threaded_queue.hh index 603ed5f87..ced88be43 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "utils.h" +#include "utils.hh" #include #include diff --git a/src/utils.cc b/src/utils.cc index 68c7c83be..8e2eb4d62 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -13,10 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "utils.h" +#include "utils.hh" #include "log.hh" -#include "platform.h" +#include "platform.hh" #include diff --git a/src/utils.h b/src/utils.hh similarity index 100% rename from src/utils.h rename to src/utils.hh diff --git a/src/working_files.cc b/src/working_files.cc index b7d19199f..5d6cbaaa6 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -13,10 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "working_files.h" +#include "working_files.hh" #include "log.hh" -#include "position.h" +#include "position.hh" #include #include diff --git a/src/working_files.h b/src/working_files.hh similarity index 99% rename from src/working_files.h rename to src/working_files.hh index 0784e5934..52339c9a7 100644 --- a/src/working_files.h +++ b/src/working_files.hh @@ -16,7 +16,7 @@ limitations under the License. #pragma once #include "lsp.hh" -#include "utils.h" +#include "utils.hh" #include #include From 5599ddd343f3446feaddf3ceaf1f82759c550d48 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 28 Oct 2018 21:39:17 -0700 Subject: [PATCH 276/378] Simplify and better compatibility with encodings retaining the feature of low bytes being 1-byte characters --- src/clang_complete.cc | 10 ++++------ src/messages/ccls_call.cc | 3 +-- src/messages/ccls_member.cc | 12 +++++------- src/messages/initialize.cc | 3 +-- src/messages/textDocument_hover.cc | 4 ++-- src/messages/textDocument_rename.cc | 7 +++---- src/pipeline.cc | 3 +-- src/pipeline.hh | 3 --- src/working_files.cc | 9 +++++---- src/working_files.hh | 2 +- 10 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 8c2e5eecb..17da71235 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -417,7 +417,7 @@ void *CompletionMain(void *manager_) { DiagnosticConsumer DC; WorkingFiles::Snapshot snapshot = - manager->wfiles_->AsSnapshot({StripFileType(path)}); + manager->wfiles_->AsSnapshot({StripFileType(path)}); std::vector> Bufs; auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, preamble.get(), snapshot, Bufs); @@ -574,13 +574,11 @@ std::shared_ptr CompletionSession::GetPreamble() { return preamble; } -CompletionManager::CompletionManager(Project *project, - WorkingFiles *wfiles, +CompletionManager::CompletionManager(Project *project, WorkingFiles *wfiles, OnDiagnostic on_diagnostic, OnDropped on_dropped) - : project_(project), wfiles_(wfiles), - on_diagnostic_(on_diagnostic), on_dropped_(on_dropped), - preloads(kMaxPreloadedSessions), + : project_(project), wfiles_(wfiles), on_diagnostic_(on_diagnostic), + on_dropped_(on_dropped), preloads(kMaxPreloadedSessions), sessions(kMaxCompletionSessions), PCH(std::make_shared()) { SpawnThread(ccls::CompletionMain, this); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index f22ee46b1..14766d2c6 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -204,8 +204,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *working_file = - wfiles->GetFileByFilename(file->def->path); + WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, param.position)) { if (sym.kind == SymbolKind::Func) { diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index c39fe7902..45c8fd822 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -145,13 +145,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, if (def1 && def1->spell) { // The declaration of target type. if (std::optional loc = - GetLsLocation(m->db, m->wfiles, *def1->spell)) + GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (def->spell) { // Builtin types have no declaration but the typedef declaration // itself is useful. if (std::optional loc = - GetLsLocation(m->db, m->wfiles, *def->spell)) + GetLsLocation(m->db, m->wfiles, *def->spell)) entry1.location = *loc; } if (def1 && qualified) @@ -172,8 +172,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, Out_cclsMember entry1; entry1.fieldName = def1->Name(false); if (def1->spell) { - if (auto loc = - GetLsLocation(m->db, m->wfiles, *def1->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (func1.declarations.size()) { if (auto loc = GetLsLocation(m->db, m->wfiles, @@ -193,12 +192,11 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, Out_cclsMember entry1; entry1.fieldName = def1->Name(false); if (def1->spell) { - if (auto loc = - GetLsLocation(m->db, m->wfiles, *def1->spell)) + if (auto loc = GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (type1.declarations.size()) { if (auto loc = GetLsLocation(m->db, m->wfiles, - type1.declarations[0])) + type1.declarations[0])) entry1.location = *loc; } entry->children.push_back(std::move(entry1)); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 1d5b7e70f..ccc80e9c5 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -360,8 +360,7 @@ void *Indexer(void *arg_) { delete arg; std::string name = "indexer" + std::to_string(idx); set_thread_name(name.c_str()); - pipeline::Indexer_Main(h->clang_complete, h->vfs, h->project, - h->wfiles); + pipeline::Indexer_Main(h->clang_complete, h->vfs, h->project, h->wfiles); return nullptr; } } // namespace diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 044e822bd..907de2e25 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -101,8 +101,8 @@ void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, Hover result; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { - std::optional ls_range = GetLsRange( - wfiles->GetFileByFilename(file->def->path), sym.range); + std::optional ls_range = + GetLsRange(wfiles->GetFileByFilename(file->def->path), sym.range); if (!ls_range) continue; diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 84cefa501..836847ddd 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -18,13 +18,12 @@ limitations under the License. namespace ccls { namespace { -lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, - SymbolRef sym, const std::string &new_text) { +lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, + const std::string &new_text) { std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { - std::optional ls_location = - GetLsLocation(db, wfiles, use); + std::optional ls_location = GetLsLocation(db, wfiles, use); if (!ls_location) return; diff --git a/src/pipeline.cc b/src/pipeline.cc index 867ccf18f..40873b2f3 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -400,8 +400,7 @@ void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { auto &def_u = *update->files_def_update; - if (WorkingFile *wfile = - wfiles->GetFileByFilename(def_u.first.path)) { + if (WorkingFile *wfile = wfiles->GetFileByFilename(def_u.first.path)) { // FIXME With index.onChange: true, use buffer_content only for // request.path wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content diff --git a/src/pipeline.hh b/src/pipeline.hh index 6bd4d4d45..494f87076 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -57,9 +57,6 @@ template void Notify(const char *method, T &result) { } void Reply(lsRequestId id, const std::function &fn); -template void Reply(lsRequestId id, T &result) { - Reply(id, [&](Writer &w) { Reflect(w, result); }); -} void ReplyError(lsRequestId id, const std::function &fn); template void ReplyError(lsRequestId id, T &result) { diff --git a/src/working_files.cc b/src/working_files.cc index 5d6cbaaa6..8f7939350 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -538,12 +538,13 @@ WorkingFiles::AsSnapshot(const std::vector &filter_paths) { // text documents. // We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). // This is good enough and fails only for UTF-16 surrogate pairs. -int GetOffsetForPosition(lsPosition position, std::string_view content) { +int GetOffsetForPosition(lsPosition pos, std::string_view content) { size_t i = 0; - for (; position.line > 0 && i < content.size(); i++) + for (; pos.line > 0 && i < content.size(); i++) if (content[i] == '\n') - position.line--; - for (; position.character > 0 && i < content.size(); position.character--) + pos.line--; + for (; pos.character > 0 && i < content.size() && content[i] != '\n'; + pos.character--) if (uint8_t(content[i++]) >= 128) { // Skip 0b10xxxxxx while (i < content.size() && uint8_t(content[i]) >= 128 && diff --git a/src/working_files.hh b/src/working_files.hh index 52339c9a7..0824eceed 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -132,7 +132,7 @@ struct WorkingFiles { std::mutex files_mutex; // Protects |files|. }; -int GetOffsetForPosition(lsPosition position, std::string_view content); +int GetOffsetForPosition(lsPosition pos, std::string_view content); std::string_view LexIdentifierAroundPos(lsPosition position, std::string_view content); From 26d76b75c71b75600eeff6addc36972057cf5542 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 30 Oct 2018 22:26:01 -0700 Subject: [PATCH 277/378] Report InvalidParams for serialization error --- src/message_handler.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/message_handler.cc b/src/message_handler.cc index b85bdd507..427dac757 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -22,9 +22,10 @@ limitations under the License. #include "query_utils.hh" #include "serializers/json.hh" -using namespace clang; - #include +#include + +using namespace clang; MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); @@ -204,8 +205,16 @@ void MessageHandler::Run(InMessage &msg) { if (it != method2request.end()) { try { it->second(reader, reply); + } catch (std::invalid_argument &ex) { + lsResponseError err; + err.code = lsErrorCodes::InvalidParams; + err.message = "invalid params of " + msg.method + ": " + ex.what(); + reply.Error(err); } catch (...) { - LOG_S(ERROR) << "failed to process request " << msg.method; + lsResponseError err; + err.code = lsErrorCodes::InternalError; + err.message = "failed to process " + msg.method; + reply.Error(err); } } else { lsResponseError err; From 90a94cbb4f72bb539787ee7dfb5130379d251507 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 29 Oct 2018 23:49:52 -0700 Subject: [PATCH 278/378] textDocument/references workspace/symbol: add folders For textDocument/reference, base/excludeRole/role has been lifted from params.context.* to params.* --- src/message_handler.cc | 2 +- src/message_handler.hh | 3 ++ src/messages/textDocument_definition.cc | 4 +-- src/messages/textDocument_references.cc | 41 +++++++++++++++---------- src/messages/workspace.cc | 40 ++++++++++++++++-------- src/query.cc | 18 +++++++++++ src/query.hh | 1 + src/query_utils.cc | 18 ++++------- src/query_utils.hh | 2 +- 9 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/message_handler.cc b/src/message_handler.cc index 427dac757..dd04f797f 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -60,7 +60,7 @@ MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type); MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam, changes); MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed); MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event); -MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query); +MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query, folders); namespace { struct CclsSemanticHighlightSymbol { diff --git a/src/message_handler.hh b/src/message_handler.hh index 8410390f1..d1d81ddc7 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -174,6 +174,9 @@ struct DidChangeWorkspaceFoldersParam { }; struct WorkspaceSymbolParam { std::string query; + + // ccls extensions + std::vector folders; }; // TODO llvm 8 llvm::unique_function diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 36eb2b765..00834fc30 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -22,10 +22,10 @@ limitations under the License. namespace ccls { namespace { -std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { +std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { case SymbolKind::Var: { - std::vector ret = GetNonDefDeclarations(db, sym); + std::vector ret = GetNonDefDeclarations(db, sym); // If there is no declaration, jump to its type. if (ret.empty()) { for (auto &def : db->GetVar(sym).def) diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 5ccad7ae6..fca73c83f 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -22,18 +22,23 @@ namespace ccls { namespace { struct ReferenceParam : public TextDocumentPositionParam { struct Context { - bool base = true; - // Exclude references with any |Role| bits set. - Role excludeRole = Role::None; // Include the declaration of the current symbol. bool includeDeclaration = false; - // Include references with all |Role| bits set. - Role role = Role::None; } context; + + // ccls extension + // If not empty, restrict to specified folders. + std::vector folders; + // For Type, also return references of base types. + bool base = true; + // Exclude references with any |Role| bits set. + Role excludeRole = Role::None; + // Include references with all |Role| bits set. + Role role = Role::None; }; -MAKE_REFLECT_STRUCT(ReferenceParam::Context, base, excludeRole, - includeDeclaration, role); -MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context); +MAKE_REFLECT_STRUCT(ReferenceParam::Context, includeDeclaration); +MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders, + base, excludeRole, role); } // namespace void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { @@ -42,10 +47,13 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - std::vector result; WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!file) + if (!wfile) return; + for (auto &folder : param.folders) + EnsureEndsInSlash(folder); + std::vector file_set = db->GetFileSet(param.folders); + std::vector result; std::unordered_set seen_uses; int line = param.position.line; @@ -56,24 +64,23 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { seen.insert(sym.usr); std::vector stack{sym.usr}; if (sym.kind != SymbolKind::Func) - param.context.base = false; + param.base = false; while (stack.size()) { sym.usr = stack.back(); stack.pop_back(); auto fn = [&](Use use, lsSymbolKind parent_kind) { - if (Role(use.role & param.context.role) == param.context.role && - !(use.role & param.context.excludeRole) && - seen_uses.insert(use).second) - if (auto loc = GetLsLocation(db, wfiles, use)) { + if (file_set[use.file_id] && + Role(use.role & param.role) == param.role && + !(use.role & param.excludeRole) && seen_uses.insert(use).second) + if (auto loc = GetLsLocation(db, wfiles, use)) result.push_back(*loc); - } }; WithEntity(db, sym, [&](const auto &entity) { lsSymbolKind parent_kind = lsSymbolKind::Unknown; for (auto &def : entity.def) if (def.spell) { parent_kind = GetSymbolKind(db, sym); - if (param.context.base) + if (param.base) for (Usr usr : def.GetBases()) if (!seen.count(usr)) { seen.insert(usr); diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index c1229cf4a..695b2ab45 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -22,6 +22,7 @@ limitations under the License. #include "query_utils.hh" #include +#include #include #include @@ -96,23 +97,35 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( namespace { // Lookup |symbol| in |db| and insert the value into |result|. bool AddSymbol( - DB *db, WorkingFiles *wfiles, SymbolIdx sym, bool use_detailed, + DB *db, WorkingFiles *wfiles, const std::vector &file_set, + SymbolIdx sym, bool use_detailed, std::vector> *result) { std::optional info = GetSymbolInfo(db, sym, true); if (!info) return false; - Use loc; - if (Maybe dr = GetDefinitionSpell(db, sym)) - loc = *dr; - else { - auto decls = GetNonDefDeclarations(db, sym); - if (decls.empty()) - return false; - loc = decls[0]; + Maybe dr; + bool in_folder = false; + WithEntity(db, sym, [&](const auto &entity) { + for (auto &def : entity.def) + if (def.spell) { + dr = def.spell; + if (!in_folder && (in_folder = file_set[def.spell->file_id])) + break; + } + }); + if (!dr) { + auto &decls = GetNonDefDeclarations(db, sym); + for (auto &dr1 : decls) { + dr = dr1; + if (!in_folder && (in_folder = file_set[dr1.file_id])) + break; + } } + if (!in_folder) + return false; - std::optional ls_location = GetLsLocation(db, wfiles, loc); + std::optional ls_location = GetLsLocation(db, wfiles, *dr); if (!ls_location) return false; info->location = *ls_location; @@ -124,7 +137,10 @@ bool AddSymbol( void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, ReplyOnce &reply) { std::vector result; - std::string query = param.query; + const std::string &query = param.query; + for (auto &folder : param.folders) + EnsureEndsInSlash(folder); + std::vector file_set = db->GetFileSet(param.folders); // {symbol info, matching detailed_name or short_name, index} std::vector> cands; @@ -141,7 +157,7 @@ void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, std::string_view detailed_name = db->GetSymbolName(sym, true); int pos = ReverseSubseqMatch(query_without_space, detailed_name, sensitive); return pos >= 0 && - AddSymbol(db, wfiles, sym, + AddSymbol(db, wfiles, file_set, sym, detailed_name.find(':', pos) != std::string::npos, &cands) && cands.size() >= g_config->workspaceSymbol.maxNum; diff --git a/src/query.cc b/src/query.cc index 25e02d480..1d1345808 100644 --- a/src/query.cc +++ b/src/query.cc @@ -468,4 +468,22 @@ std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) { } return ""; } + +std::vector DB::GetFileSet(const std::vector &folders) { + if (folders.empty()) + return std::vector(files.size(), 1); + std::vector file_set(files.size()); + for (QueryFile &file : files) + if (file.def) { + bool ok = false; + for (auto &folder : folders) + if (llvm::StringRef(file.def->path).startswith(folder)) { + ok = true; + break; + } + if (ok) + file_set[file.id] = 1; + } + return file_set; +} } // namespace ccls diff --git a/src/query.hh b/src/query.hh index a1627af5f..9cf093645 100644 --- a/src/query.hh +++ b/src/query.hh @@ -181,6 +181,7 @@ struct DB { void Update(const Lid2file_id &, int file_id, std::vector> &&us); std::string_view GetSymbolName(SymbolIdx sym, bool qualified); + std::vector GetFileSet(const std::vector &folders); bool HasFunc(Usr usr) const { return func_usr.count(usr); } bool HasType(Usr usr) const { return type_usr.count(usr); } diff --git a/src/query_utils.cc b/src/query_utils.cc index fb13bbcaf..24d39040f 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -95,25 +95,19 @@ std::vector GetVarDeclarations(DB *db, const std::vector &usrs, return ret; } -std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym) { - std::vector ret; +std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym) { + static std::vector empty; switch (sym.kind) { case SymbolKind::Func: - for (auto &d : db->GetFunc(sym).declarations) - ret.push_back(d); - break; + return db->GetFunc(sym).declarations; case SymbolKind::Type: - for (auto &d : db->GetType(sym).declarations) - ret.push_back(d); - break; + return db->GetType(sym).declarations; case SymbolKind::Var: - for (auto &d : db->GetVar(sym).declarations) - ret.push_back(d); - break; + return db->GetVar(sym).declarations; default: break; } - return ret; + return empty; } std::vector GetUsesForAllBases(DB *db, QueryFunc &root) { diff --git a/src/query_utils.hh b/src/query_utils.hh index 5db3be65e..0dd53fe37 100644 --- a/src/query_utils.hh +++ b/src/query_utils.hh @@ -30,7 +30,7 @@ std::vector GetTypeDeclarations(DB *, const std::vector &); std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); // Get non-defining declarations. -std::vector GetNonDefDeclarations(DB *db, SymbolIdx sym); +std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym); std::vector GetUsesForAllBases(DB *db, QueryFunc &root); std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); From 334557e9fe87d1ddd78c1959d0019b5b8429bac8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 1 Nov 2018 20:26:00 -0700 Subject: [PATCH 279/378] Fix EnumConstantDecl's kind & EnumDecl's vars --- index_tests/enums/enum_class_decl.cc | 12 ++++++++--- index_tests/enums/enum_decl.cc | 8 ++++---- index_tests/enums/enum_inherit.cc | 20 ++++++++++++------- index_tests/enums/enum_usage.cc | 12 ++++++++--- index_tests/macros/complex.cc | 4 ++-- index_tests/macros/foo.cc | 4 ++-- index_tests/multi_file/funky_enum.cc | 12 +++++------ index_tests/multi_file/impl.cc | 12 +++++------ index_tests/namespaces/anonymous_function.cc | 18 +---------------- index_tests/templates/specialization.cc | 8 ++++---- ...emplate_class_var_usage_folded_into_one.cc | 2 +- index_tests/usage/var_usage_call_function.cc | 6 +++--- .../usage/var_usage_class_member_static.cc | 2 +- .../vars/class_static_member_decl_only.cc | 2 +- index_tests/vars/deduce_auto_type.cc | 4 ++-- src/indexer.cc | 17 ++++++++-------- 16 files changed, 73 insertions(+), 70 deletions(-) diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index a49e0ed17..f1b8c10d3 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -36,7 +36,13 @@ enum class Foo : uint8_t { "bases": [], "funcs": [], "types": [], - "vars": [], + "vars": [{ + "L": 439339022761937396, + "R": -1 + }, { + "L": 15962370213938840720, + "R": -1 + }], "alias_of": 0, "kind": 10, "parent_kind": 0, @@ -52,7 +58,7 @@ enum class Foo : uint8_t { "short_name": "A", "hover": "Foo::A = 0", "spell": "3:3-3:4|3:3-3:4|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, "parent_kind": 10, "storage": 0, @@ -64,7 +70,7 @@ enum class Foo : uint8_t { "qual_name_offset": 0, "short_name": "B", "spell": "4:3-4:4|4:3-4:9|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, "parent_kind": 10, "storage": 0, diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index 16697d86b..fd84c0b6a 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -34,9 +34,9 @@ enum Foo { "short_name": "A", "hover": "A = 0", "spell": "2:3-2:4|2:3-2:4|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -46,9 +46,9 @@ enum Foo { "qual_name_offset": 0, "short_name": "B", "spell": "3:3-3:4|3:3-3:9|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index 3bf68d52b..9459dcfec 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -25,7 +25,13 @@ enum class E : int32_t { "bases": [], "funcs": [], "types": [], - "vars": [], + "vars": [{ + "L": 16614320383091394267, + "R": -1 + }, { + "L": 16847439761518576294, + "R": -1 + }], "alias_of": 0, "kind": 10, "parent_kind": 0, @@ -75,9 +81,9 @@ enum class E : int32_t { "short_name": "A", "hover": "A = 0", "spell": "2:3-2:4|2:3-2:4|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -87,9 +93,9 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "B", "spell": "3:3-3:4|3:3-3:9|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -100,7 +106,7 @@ enum class E : int32_t { "short_name": "E0", "hover": "E::E0 = 0", "spell": "9:3-9:5|9:3-9:5|1026|-1", - "type": 0, + "type": 2986879766914123941, "kind": 22, "parent_kind": 10, "storage": 0, @@ -112,7 +118,7 @@ enum class E : int32_t { "qual_name_offset": 0, "short_name": "E20", "spell": "10:3-10:6|10:3-10:11|1026|-1", - "type": 0, + "type": 2986879766914123941, "kind": 22, "parent_kind": 10, "storage": 0, diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index 9d3037107..c3a9a6416 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -20,7 +20,13 @@ Foo x = Foo::A; "bases": [], "funcs": [], "types": [], - "vars": [], + "vars": [{ + "L": 439339022761937396, + "R": -1 + }, { + "L": 15962370213938840720, + "R": -1 + }], "alias_of": 0, "kind": 10, "parent_kind": 0, @@ -36,7 +42,7 @@ Foo x = Foo::A; "short_name": "A", "hover": "Foo::A = 0", "spell": "2:3-2:4|2:3-2:4|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, "parent_kind": 10, "storage": 0, @@ -61,7 +67,7 @@ Foo x = Foo::A; "qual_name_offset": 0, "short_name": "B", "spell": "3:3-3:4|3:3-3:9|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, "parent_kind": 10, "storage": 0, diff --git a/index_tests/macros/complex.cc b/index_tests/macros/complex.cc index 413886651..55ac9624c 100644 --- a/index_tests/macros/complex.cc +++ b/index_tests/macros/complex.cc @@ -21,14 +21,14 @@ FOO(make1(), make2); "detailed_name": "int a()", "qual_name_offset": 4, "short_name": "a", - "spell": "12:1-12:20|12:1-12:20|2|-1", + "spell": "12:1-12:20|12:1-12:4|2|-1", "bases": [], "vars": [], "callees": ["12:5-12:10|14400399977994209582|3|16420"], "kind": 12, "parent_kind": 0, "storage": 0, - "declarations": ["12:1-12:20|12:1-12:20|1|-1"], + "declarations": ["12:1-12:20|12:1-12:4|1|-1"], "derived": [], "uses": ["2:7-2:8|64|0", "3:7-3:8|64|0"] }, { diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index c8744e745..a75078311 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -17,7 +17,7 @@ int x = A; "detailed_name": "Foo::Foo(Foo &&) = delete", "qual_name_offset": 0, "short_name": "Foo", - "spell": "5:12-5:15|5:12-5:15|1026|-1", + "spell": "5:12-5:15|5:3-5:11|1026|-1", "bases": [], "vars": [], "callees": [], @@ -94,7 +94,7 @@ int x = A; "qual_name_offset": 4, "short_name": "x", "hover": "int x = A", - "spell": "8:5-8:6|8:1-1:1|2|-1", + "spell": "8:5-8:6|8:1-8:10|2|-1", "type": 53, "kind": 13, "parent_kind": 0, diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index 7ceb5e713..b30c456d7 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -20,9 +20,9 @@ OUTPUT: funky_enum.h "hover": "A = 0", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "spell": "4:1-4:2|4:1-4:2|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -34,9 +34,9 @@ OUTPUT: funky_enum.h "hover": "C = 2", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "spell": "6:1-6:2|6:1-6:2|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -48,9 +48,9 @@ OUTPUT: funky_enum.h "hover": "B = 1", "comments": "This file cannot be built directory. It is included in an enum definition of\nanother file.", "spell": "5:1-5:2|5:1-5:2|1026|-1", - "type": 0, + "type": 16985894625255407295, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 927f871b2..9e6e477ae 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -146,9 +146,9 @@ OUTPUT: header.h "short_name": "A", "hover": "A = 0", "spell": "15:13-15:14|15:13-15:14|1026|-1", - "type": 0, + "type": 4481210672785600703, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -159,9 +159,9 @@ OUTPUT: header.h "short_name": "C", "hover": "C = 2", "spell": "15:19-15:20|15:19-15:20|1026|-1", - "type": 0, + "type": 4481210672785600703, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -184,9 +184,9 @@ OUTPUT: header.h "short_name": "B", "hover": "B = 1", "spell": "15:16-15:17|15:16-15:17|1026|-1", - "type": 0, + "type": 4481210672785600703, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 7a69afced..e8bebc888 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -22,23 +22,7 @@ void foo(); "derived": [], "uses": [] }], - "usr2type": [{ - "usr": 7144845543074395457, - "detailed_name": "", - "qual_name_offset": 0, - "short_name": "", - "bases": [], - "funcs": [5010253035933134245], - "types": [], - "vars": [], - "alias_of": 0, - "kind": 0, - "parent_kind": 0, - "declarations": [], - "derived": [], - "instances": [], - "uses": [] - }], + "usr2type": [], "usr2var": [] } */ diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 4b414b7d1..b943c207e 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -349,9 +349,9 @@ void foo(float Value); "short_name": "Enum1", "hover": "Enum1 = 1", "spell": "36:10-36:15|36:10-36:15|1026|-1", - "type": 0, + "type": 9201299975592934124, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": [] @@ -387,9 +387,9 @@ void foo(float Value); "short_name": "Enum0", "hover": "Enum0 = 0", "spell": "36:3-36:8|36:3-36:8|1026|-1", - "type": 0, + "type": 9201299975592934124, "kind": 22, - "parent_kind": 10, + "parent_kind": 0, "storage": 0, "declarations": [], "uses": ["43:20-43:25|4|-1"] diff --git a/index_tests/templates/template_class_var_usage_folded_into_one.cc b/index_tests/templates/template_class_var_usage_folded_into_one.cc index 8f8f0cd47..f2c4390ca 100644 --- a/index_tests/templates/template_class_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_class_var_usage_folded_into_one.cc @@ -67,7 +67,7 @@ int b = Foo::var; "hover": "static constexpr int Foo::var = 3", "type": 53, "kind": 13, - "parent_kind": 0, + "parent_kind": 23, "storage": 2, "declarations": ["3:24-3:27|3:3-3:31|1025|-1"], "uses": ["6:19-6:22|12|-1", "7:20-7:23|12|-1"] diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index 1b867cea7..0a0df74fb 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -46,10 +46,10 @@ void caller() { "usr2type": [], "usr2var": [{ "usr": 9121974011454213596, - "detailed_name": "auto x", - "qual_name_offset": 5, + "detailed_name": "void (*)() x", + "qual_name_offset": 11, "short_name": "x", - "hover": "auto x = &called", + "hover": "void (*)() x = &called", "spell": "4:8-4:9|4:3-4:19|2|-1", "type": 0, "kind": 13, diff --git a/index_tests/usage/var_usage_class_member_static.cc b/index_tests/usage/var_usage_class_member_static.cc index 9c8e4d57a..1206c2d8d 100644 --- a/index_tests/usage/var_usage_class_member_static.cc +++ b/index_tests/usage/var_usage_class_member_static.cc @@ -84,7 +84,7 @@ void foo() { "short_name": "x", "type": 53, "kind": 13, - "parent_kind": 0, + "parent_kind": 23, "storage": 2, "declarations": ["2:14-2:15|2:3-2:15|1025|-1"], "uses": ["8:15-8:16|12|-1"] diff --git a/index_tests/vars/class_static_member_decl_only.cc b/index_tests/vars/class_static_member_decl_only.cc index c0a3172a7..0cf61b2c6 100644 --- a/index_tests/vars/class_static_member_decl_only.cc +++ b/index_tests/vars/class_static_member_decl_only.cc @@ -48,7 +48,7 @@ class Foo { "short_name": "member", "type": 53, "kind": 13, - "parent_kind": 0, + "parent_kind": 5, "storage": 2, "declarations": ["2:14-2:20|2:3-2:20|1025|-1"], "uses": [] diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index a86eb701d..7e9c0cbc2 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -45,10 +45,10 @@ void f() { }], "usr2var": [{ "usr": 10601729374837386290, - "detailed_name": "auto x", + "detailed_name": "Foo *x", "qual_name_offset": 5, "short_name": "x", - "hover": "auto x = new Foo()", + "hover": "Foo *x = new Foo()", "spell": "3:8-3:9|3:3-3:21|2|-1", "type": 15041163540773201510, "kind": 13, diff --git a/src/indexer.cc b/src/indexer.cc index 43852a7f1..cbb4d29a8 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -854,21 +854,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (var->def.detailed_name[0] == '\0') SetVarName(D, info->short_name, info->qualified, var->def); QualType T; - if (auto *VD = dyn_cast(D)) + if (auto *VD = dyn_cast(D)) T = VD->getType(); - else if (auto *FD = dyn_cast(D)) - T = FD->getType(); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func) + SymbolKind kind = GetSymbolKind(DC, var->def.parent_kind); + if (kind == SymbolKind::Func) db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); - else if (auto *ND = dyn_cast(SemDC)) - db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1); + else if (kind == SymbolKind::Type && !isa(SemDC)) + db->ToType(GetUsr(DC)).def.vars.emplace_back(usr, -1); if (!T.isNull()) { if (auto *BT = T->getAs()) { Usr usr1 = static_cast(BT->getKind()); var->def.type = usr1; - db->ToType(usr1).instances.push_back(usr); + if (!isa(D)) + db->ToType(usr1).instances.push_back(usr); } else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) { if (isa(D1)) { // e.g. TemplateTypeParmDecl is not handled by @@ -896,7 +896,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexParam::DeclInfo *info1; Usr usr1 = GetUsr(D1, &info1); var->def.type = usr1; - db->ToType(usr1).instances.push_back(usr); + if (!isa(D)) + db->ToType(usr1).instances.push_back(usr); } } } else if (!var->def.spell && var->declarations.empty()) { From 42b6b7b3f01d2e788e3730ba91e8d6037a659dbf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 2 Nov 2018 15:17:46 -0700 Subject: [PATCH 280/378] project.cc: deduplicate more cases --- src/project.cc | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/project.cc b/src/project.cc index 14ba02d93..42b8959e6 100644 --- a/src/project.cc +++ b/src/project.cc @@ -87,7 +87,11 @@ enum OptionClass { struct ProjectProcessor { ProjectConfig *config; std::unordered_set command_set; - ProjectProcessor(ProjectConfig *config) : config(config) {} + StringSet<> excludeArgs; + ProjectProcessor(ProjectConfig *config) : config(config) { + for (auto &arg : g_config->clang.excludeArgs) + excludeArgs.insert(arg); + } void Process(Project::Entry &entry) { const std::string base_name = sys::path::filename(entry.filename); @@ -105,7 +109,7 @@ struct ProjectProcessor { args.push_back(arg + 5); } else if (strcmp(arg, "%clang") == 0) { args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); - } else if (!llvm::is_contained(g_config->clang.excludeArgs, arg)) { + } else if (!excludeArgs.count(arg)) { args.push_back(arg); } } @@ -115,22 +119,30 @@ struct ProjectProcessor { args.push_back(Intern(arg)); size_t hash = std::hash{}(entry.directory); + bool OPT_o = false; for (auto &arg : args) { - if (arg[0] != '-' && EndsWith(arg, base_name)) { + bool last_o = OPT_o; + OPT_o = false; + if (arg[0] == '-') { + OPT_o = arg[1] == 'o' && arg[2] == '\0'; + if (OPT_o || arg[1] == 'D' || arg[1] == 'W') + continue; + } else if (last_o) { + continue; + } else if (sys::path::filename(arg) == base_name) { LanguageId lang = lookupExtension(arg).first; if (lang != LanguageId::Unknown) { - hash_combine(hash, size_t(lang)); + hash_combine(hash, (size_t)lang); continue; } } - hash_combine(hash, std::hash{}(arg)); + hash_combine(hash, std::hash{}(arg)); } args.push_back(Intern("-working-directory=" + entry.directory)); - - if (!command_set.insert(hash).second) { - entry.args = std::move(args); + entry.args = args; + args.push_back("-fsyntax-only"); + if (!command_set.insert(hash).second) return; - } // a weird C++ deduction guide heap-use-after-free causes libclang to crash. IgnoringDiagConsumer DiagC; @@ -149,8 +161,6 @@ struct ProjectProcessor { } Driver.setCheckInputsExist(false); - args.push_back("-fsyntax-only"); - std::unique_ptr C(Driver.BuildCompilation(args)); const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1) @@ -180,7 +190,6 @@ struct ProjectProcessor { break; } } - entry.args = std::move(args); } }; From 18e5d5c49840630a38e0065e2e9f2f5a37229e4d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 3 Nov 2018 15:04:07 -0700 Subject: [PATCH 281/378] Simplify and work around vscode _sortTextLow --- src/messages/textDocument_completion.cc | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index dd4d0f486..227efa36f 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -91,19 +91,6 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) { return {ok, match[3], match[5], match[6], match}; } -template char *tofixedbase64(T input, char *out) { - const char *digits = "./0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - int len = (sizeof(T) * 8 - 1) / 6 + 1; - for (int i = len - 1; i >= 0; i--) { - out[i] = digits[input % 64]; - input /= 64; - } - out[len] = '\0'; - return out; -} - // Pre-filters completion responses before sending to vscode. This results in a // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. @@ -130,6 +117,7 @@ void FilterCandidates(lsCompletionList &result, result.isIncomplete = true; } + std::string sort(4, ' '); for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; if (has_open_paren && item.filterText) @@ -149,15 +137,12 @@ void FilterCandidates(lsCompletionList &result, } edits.erase(edits.begin()); } + for (auto i = sort.size(); i && ++sort[i - 1] == 'A';) + sort[--i] = ' '; + item.sortText = sort; // Compatibility item.insertText = item.textEdit.newText; } - - // Set sortText. Note that this happens after resizing - we could do it - // before, but then we should also sort by priority. - char buf[16]; - for (size_t i = 0; i < items.size(); ++i) - items[i].sortText = tofixedbase64(i, buf); }; // No complete text; don't run any filtering logic except to trim the items. From ac09b085ff3d0d9be1c5563a954d0f7c2d4a8253 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 3 Nov 2018 21:48:38 -0700 Subject: [PATCH 282/378] Misc --- src/main.cc | 4 ++++ src/message_handler.hh | 9 ++------- src/pipeline.cc | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main.cc b/src/main.cc index 606e7ca1a..8dc5f95f4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -21,6 +21,7 @@ limitations under the License. #include "test.hh" #include "working_files.hh" +#include #include #include #include @@ -69,6 +70,9 @@ void CloseLog() { fclose(ccls::log::file); } int main(int argc, char **argv) { TraceMe(); sys::PrintStackTraceOnErrorSignal(argv[0]); + cl::SetVersionPrinter([](raw_ostream &OS) { + OS << clang::getClangToolFullVersion("ccls") << "\n"; + }); for (auto &I : TopLevelSubCommand->OptionsMap) if (I.second->Category != &C) diff --git a/src/message_handler.hh b/src/message_handler.hh index d1d81ddc7..a24979dfa 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -21,18 +21,13 @@ limitations under the License. #include #include #include -#include #include namespace ccls { struct CompletionManager; -struct Config; -struct GroupMatch; struct VFS; struct IncludeComplete; -struct MultiQueueWaiter; struct Project; -struct DB; struct WorkingFile; struct WorkingFiles; @@ -196,12 +191,12 @@ struct ReplyOnce { }; struct MessageHandler { + CompletionManager *clang_complete = nullptr; DB *db = nullptr; + IncludeComplete *include_complete = nullptr; Project *project = nullptr; VFS *vfs = nullptr; WorkingFiles *wfiles = nullptr; - CompletionManager *clang_complete = nullptr; - IncludeComplete *include_complete = nullptr; llvm::StringMap> method2notification; llvm::StringMap> method2request; diff --git a/src/pipeline.cc b/src/pipeline.cc index 40873b2f3..f3e16906e 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -566,7 +566,7 @@ void Standalone(const std::string &root) { int entries = 0; for (auto &[_, folder] : project.root2folder) entries += folder.entries.size(); - printf("entries: %5d\n", entries); + printf("entries: %5d\n", entries); } while (1) { (void)on_indexed->DequeueAll(); From 11ba6b64ff1e1f1c055feea688b6166876b496b4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 3 Nov 2018 13:52:43 -0700 Subject: [PATCH 283/378] Remove `ls` prefix from many LSP interfaces Rename SymbolKind to Kind & lsSymbolKind to SymbolKind Use textDocumentSync: TextDocumentSyncOptions --- src/clang_complete.cc | 29 +- src/clang_complete.hh | 16 +- src/hierarchy.hh | 4 +- src/include_complete.cc | 20 +- src/include_complete.hh | 6 +- src/indexer.cc | 168 +++++------ src/indexer.hh | 28 +- src/lsp.cc | 37 +-- src/lsp.hh | 126 ++++----- src/match.cc | 2 +- src/message_handler.cc | 46 +-- src/message_handler.hh | 52 ++-- src/messages/ccls_call.cc | 9 +- src/messages/ccls_inheritance.cc | 17 +- src/messages/ccls_member.cc | 42 +-- src/messages/ccls_navigate.cc | 6 +- src/messages/ccls_reload.cc | 2 +- src/messages/ccls_vars.cc | 6 +- src/messages/initialize.cc | 314 +++++++-------------- src/messages/textDocument_code.cc | 70 ++--- src/messages/textDocument_completion.cc | 107 ++++--- src/messages/textDocument_definition.cc | 26 +- src/messages/textDocument_document.cc | 61 ++-- src/messages/textDocument_foldingRange.cc | 2 +- src/messages/textDocument_formatting.cc | 10 +- src/messages/textDocument_hover.cc | 14 +- src/messages/textDocument_references.cc | 12 +- src/messages/textDocument_rename.cc | 18 +- src/messages/textDocument_signatureHelp.cc | 8 +- src/messages/workspace.cc | 23 +- src/pipeline.cc | 42 +-- src/pipeline.hh | 8 +- src/project.cc | 2 +- src/project.hh | 2 +- src/query.cc | 62 ++-- src/query.hh | 2 +- src/query_utils.cc | 73 +++-- src/query_utils.hh | 24 +- src/test.cc | 8 +- src/working_files.cc | 4 +- src/working_files.hh | 6 +- 41 files changed, 681 insertions(+), 833 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 17da71235..5fc53b7a7 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -72,10 +72,9 @@ struct ProxyFileSystem : FileSystem { namespace ccls { -lsTextEdit ToTextEdit(const clang::SourceManager &SM, - const clang::LangOptions &L, - const clang::FixItHint &FixIt) { - lsTextEdit edit; +TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L, + const clang::FixItHint &FixIt) { + TextEdit edit; edit.newText = FixIt.CodeToInsert; auto r = FromCharSourceRange(SM, L, FixIt.RemoveRange); edit.range = @@ -223,7 +222,7 @@ class StoreDiags : public DiagnosticConsumer { Flush(); } void HandleDiagnostic(DiagnosticsEngine::Level Level, - const Diagnostic &Info) override { + const clang::Diagnostic &Info) override { DiagnosticConsumer::HandleDiagnostic(Level, Info); SourceLocation L = Info.getLocation(); if (!L.isValid()) return; @@ -371,8 +370,8 @@ void *CompletionPreloadMain(void *manager_) { int debounce = is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; if (debounce >= 0) { - lsTextDocumentIdentifier document; - document.uri = lsDocumentUri::FromPath(request.path); + TextDocumentIdentifier document; + document.uri = DocumentUri::FromPath(request.path); manager->DiagnosticsUpdate(request.path, debounce); } } @@ -502,24 +501,24 @@ void *DiagnosticMain(void *manager_) { for (auto &Buf : Bufs) Buf.release(); - auto Fill = [](const DiagBase &d, lsDiagnostic &ret) { + auto Fill = [](const DiagBase &d, Diagnostic &ret) { ret.range = lsRange{{d.range.start.line, d.range.start.column}, {d.range.end.line, d.range.end.column}}; switch (d.level) { case DiagnosticsEngine::Ignored: // llvm_unreachable case DiagnosticsEngine::Remark: - ret.severity = lsDiagnosticSeverity::Hint; + ret.severity = DiagnosticSeverity::Hint; break; case DiagnosticsEngine::Note: - ret.severity = lsDiagnosticSeverity::Information; + ret.severity = DiagnosticSeverity::Information; break; case DiagnosticsEngine::Warning: - ret.severity = lsDiagnosticSeverity::Warning; + ret.severity = DiagnosticSeverity::Warning; break; case DiagnosticsEngine::Error: case DiagnosticsEngine::Fatal: - ret.severity = lsDiagnosticSeverity::Error; + ret.severity = DiagnosticSeverity::Error; break; } ret.code = d.category; @@ -529,13 +528,13 @@ void *DiagnosticMain(void *manager_) { std::vector diags = DC.Take(); if (std::shared_ptr preamble = session->GetPreamble()) diags.insert(diags.end(), preamble->diags.begin(), preamble->diags.end()); - std::vector ls_diags; + std::vector ls_diags; for (auto &d : diags) { if (!d.concerned) continue; std::string buf; llvm::raw_string_ostream OS(buf); - lsDiagnostic &ls_diag = ls_diags.emplace_back(); + Diagnostic &ls_diag = ls_diags.emplace_back(); Fill(d, ls_diag); ls_diag.fixits_ = d.edits; OS << d.message; @@ -548,7 +547,7 @@ void *DiagnosticMain(void *manager_) { for (auto &n : d.notes) { if (!n.concerned) continue; - lsDiagnostic &ls_diag1 = ls_diags.emplace_back(); + Diagnostic &ls_diag1 = ls_diags.emplace_back(); Fill(n, ls_diag1); OS << n.message << "\n\n"; printDiag(OS, d); diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 336cff1c0..153193cb1 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -45,10 +45,10 @@ struct DiagBase { struct Note : DiagBase {}; struct Diag : DiagBase { std::vector notes; - std::vector edits; + std::vector edits; }; -lsTextEdit ToTextEdit(const clang::SourceManager &SM, +TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L, const clang::FixItHint &FixIt); @@ -75,18 +75,18 @@ struct CompletionSession struct CompletionManager { using OnDiagnostic = std::function diagnostics)>; + std::string path, std::vector diagnostics)>; // If OptConsumer is nullptr, the request has been cancelled. using OnComplete = std::function; - using OnDropped = std::function; + using OnDropped = std::function; struct PreloadRequest { std::string path; }; struct CompletionRequest { - CompletionRequest(const lsRequestId &id, - const lsTextDocumentIdentifier &document, + CompletionRequest(const RequestId &id, + const TextDocumentIdentifier &document, const lsPosition &position, std::unique_ptr Consumer, clang::CodeCompleteOptions CCOpts, @@ -95,8 +95,8 @@ struct CompletionManager { Consumer(std::move(Consumer)), CCOpts(CCOpts), on_complete(on_complete) {} - lsRequestId id; - lsTextDocumentIdentifier document; + RequestId id; + TextDocumentIdentifier document; lsPosition position; std::unique_ptr Consumer; clang::CodeCompleteOptions CCOpts; diff --git a/src/hierarchy.hh b/src/hierarchy.hh index b68a763ba..de1b17514 100644 --- a/src/hierarchy.hh +++ b/src/hierarchy.hh @@ -22,10 +22,10 @@ limitations under the License. namespace ccls { template -std::vector FlattenHierarchy(const std::optional &root) { +std::vector FlattenHierarchy(const std::optional &root) { if (!root) return {}; - std::vector ret; + std::vector ret; std::queue q; for (auto &entry : root->children) q.push(&entry); diff --git a/src/include_complete.cc b/src/include_complete.cc index 07c71b585..c806dcc84 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -34,7 +34,7 @@ namespace { struct CompletionCandidate { std::string absolute_path; - lsCompletionItem completion_item; + CompletionItem completion_item; }; std::string ElideLongPath(const std::string &path) { @@ -86,15 +86,15 @@ bool TrimPath(Project *project, std::string &path) { return angle; } -lsCompletionItem BuildCompletionItem(const std::string &path, - bool use_angle_brackets) { - lsCompletionItem item; +CompletionItem BuildCompletionItem(const std::string &path, + bool use_angle_brackets) { + CompletionItem item; item.label = ElideLongPath(path); item.detail = path; // the include path, used in de-duplicating item.textEdit.newText = path; - item.insertTextFormat = lsInsertTextFormat::PlainText; + item.insertTextFormat = InsertTextFormat::PlainText; item.use_angle_brackets_ = use_angle_brackets; - item.kind = lsCompletionItemKind::File; + item.kind = CompletionItemKind::File; item.priority_ = 0; return item; } @@ -136,7 +136,7 @@ void IncludeComplete::Rescan() { } void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, - lsCompletionItem &&item) { + CompletionItem &&item) { if (inserted_paths.insert({item.detail, inserted_paths.size()}).second) { completion_items.push_back(item); // insert if not found or with shorter include path @@ -147,7 +147,7 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, completion_items.size() - 1; } } else { - lsCompletionItem &inserted_item = + CompletionItem &inserted_item = completion_items[inserted_paths[item.detail]]; // Update |use_angle_brackets_|, prefer quotes. if (!item.use_angle_brackets_) @@ -163,7 +163,7 @@ void IncludeComplete::AddFile(const std::string &path) { std::string trimmed_path = path; bool use_angle_brackets = TrimPath(project_, trimmed_path); - lsCompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets); + CompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets); std::unique_lock lock(completion_items_mutex, std::defer_lock); if (is_scanning) @@ -202,7 +202,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, std::move(result.completion_item)); } -std::optional +std::optional IncludeComplete::FindCompletionItemForAbsolutePath( const std::string &absolute_path) { std::lock_guard lock(completion_items_mutex); diff --git a/src/include_complete.hh b/src/include_complete.hh index 818ed4401..6340c48d2 100644 --- a/src/include_complete.hh +++ b/src/include_complete.hh @@ -38,18 +38,18 @@ struct IncludeComplete { void InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets); - std::optional + std::optional FindCompletionItemForAbsolutePath(const std::string &absolute_path); // Insert item to |completion_items|. // Update |absolute_path_to_completion_item| and |inserted_paths|. void InsertCompletionItem(const std::string &absolute_path, - ccls::lsCompletionItem &&item); + ccls::CompletionItem &&item); // Guards |completion_items| when |is_scanning| is true. std::mutex completion_items_mutex; std::atomic is_scanning; - std::vector completion_items; + std::vector completion_items; // Absolute file path to the completion item in |completion_items|. // Keep the one with shortest include path. diff --git a/src/indexer.cc b/src/indexer.cc index cbb4d29a8..52aefbb07 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -117,110 +117,110 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, BInfo.second); } -SymbolKind GetSymbolKind(const Decl *D, lsSymbolKind &kind) { +Kind GetKind(const Decl *D, SymbolKind &kind) { switch (D->getKind()) { case Decl::LinkageSpec: - return SymbolKind::Invalid; + return Kind::Invalid; case Decl::Namespace: - kind = lsSymbolKind::Namespace; - return SymbolKind::Type; + kind = SymbolKind::Namespace; + return Kind::Type; case Decl::NamespaceAlias: - kind = lsSymbolKind::TypeAlias; - return SymbolKind::Type; + kind = SymbolKind::TypeAlias; + return Kind::Type; case Decl::ObjCCategory: case Decl::ObjCImplementation: case Decl::ObjCInterface: case Decl::ObjCProtocol: - kind = lsSymbolKind::Interface; - return SymbolKind::Type; + kind = SymbolKind::Interface; + return Kind::Type; case Decl::ObjCMethod: - kind = lsSymbolKind::Method; - return SymbolKind::Func; + kind = SymbolKind::Method; + return Kind::Func; case Decl::ObjCProperty: - kind = lsSymbolKind::Property; - return SymbolKind::Type; + kind = SymbolKind::Property; + return Kind::Type; case Decl::ClassTemplate: - kind = lsSymbolKind::Class; - return SymbolKind::Type; + kind = SymbolKind::Class; + return Kind::Type; case Decl::FunctionTemplate: - kind = lsSymbolKind::Function; - return SymbolKind::Func; + kind = SymbolKind::Function; + return Kind::Func; case Decl::TypeAliasTemplate: - kind = lsSymbolKind::TypeAlias; - return SymbolKind::Type; + kind = SymbolKind::TypeAlias; + return Kind::Type; case Decl::VarTemplate: - kind = lsSymbolKind::Variable; - return SymbolKind::Var; + kind = SymbolKind::Variable; + return Kind::Var; case Decl::TemplateTemplateParm: - kind = lsSymbolKind::TypeParameter; - return SymbolKind::Type; + kind = SymbolKind::TypeParameter; + return Kind::Type; case Decl::Enum: - kind = lsSymbolKind::Enum; - return SymbolKind::Type; + kind = SymbolKind::Enum; + return Kind::Type; case Decl::CXXRecord: case Decl::Record: - kind = lsSymbolKind::Class; + kind = SymbolKind::Class; // spec has no Union, use Class if (auto *RD = dyn_cast(D)) if (RD->getTagKind() == TTK_Struct) - kind = lsSymbolKind::Struct; - return SymbolKind::Type; + kind = SymbolKind::Struct; + return Kind::Type; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: - kind = lsSymbolKind::Class; - return SymbolKind::Type; + kind = SymbolKind::Class; + return Kind::Type; case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: - kind = lsSymbolKind::TypeAlias; - return SymbolKind::Type; + kind = SymbolKind::TypeAlias; + return Kind::Type; case Decl::Binding: - kind = lsSymbolKind::Variable; - return SymbolKind::Var; + kind = SymbolKind::Variable; + return Kind::Var; case Decl::Field: case Decl::ObjCIvar: - kind = lsSymbolKind::Field; - return SymbolKind::Var; + kind = SymbolKind::Field; + return Kind::Var; case Decl::Function: - kind = lsSymbolKind::Function; - return SymbolKind::Func; + kind = SymbolKind::Function; + return Kind::Func; case Decl::CXXMethod: { const auto *MD = cast(D); - kind = MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method; - return SymbolKind::Func; + kind = MD->isStatic() ? SymbolKind::StaticMethod : SymbolKind::Method; + return Kind::Func; } case Decl::CXXConstructor: - kind = lsSymbolKind::Constructor; - return SymbolKind::Func; + kind = SymbolKind::Constructor; + return Kind::Func; case Decl::CXXConversion: case Decl::CXXDestructor: - kind = lsSymbolKind::Method; - return SymbolKind::Func; + kind = SymbolKind::Method; + return Kind::Func; case Decl::Var: case Decl::Decomposition: - kind = lsSymbolKind::Variable; - return SymbolKind::Var; + kind = SymbolKind::Variable; + return Kind::Var; case Decl::ImplicitParam: case Decl::ParmVar: // ccls extension - kind = lsSymbolKind::Parameter; - return SymbolKind::Var; + kind = SymbolKind::Parameter; + return Kind::Var; case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: - kind = lsSymbolKind::Variable; - return SymbolKind::Var; + kind = SymbolKind::Variable; + return Kind::Var; case Decl::EnumConstant: - kind = lsSymbolKind::EnumMember; - return SymbolKind::Var; + kind = SymbolKind::EnumMember; + return Kind::Var; case Decl::UnresolvedUsingValue: - kind = lsSymbolKind::Variable; - return SymbolKind::Var; + kind = SymbolKind::Variable; + return Kind::Var; case Decl::TranslationUnit: - return SymbolKind::Invalid; + return Kind::Invalid; default: LOG_S(INFO) << "unhandled " << int(D->getKind()); - return SymbolKind::Invalid; + return Kind::Invalid; } } @@ -620,7 +620,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { return it->second.first; } - void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, + void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, Kind kind, SourceLocation Spell) const { const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); if (!FE) @@ -632,13 +632,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell)); Use use{{spell, Role::Dynamic}, lid}; switch (kind) { - case SymbolKind::Func: + case Kind::Func: db->ToFunc(usr).uses.push_back(use); break; - case SymbolKind::Type: + case Kind::Type: db->ToType(usr).uses.push_back(use); break; - case SymbolKind::Var: + case Kind::Var: db->ToVar(usr).uses.push_back(use); break; default: @@ -753,8 +753,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; - lsSymbolKind ls_kind; - SymbolKind kind = GetSymbolKind(D, ls_kind); + SymbolKind ls_kind; + Kind kind = GetKind(D, ls_kind); if (is_def) switch (D->getKind()) { @@ -788,7 +788,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { SourceRange R = OrigD->getSourceRange(); entity->def.spell = {use, FromTokenRangeDefaulted(SM, Lang, R, FE, loc)}; - GetSymbolKind(cast(SemDC), entity->def.parent_kind); + GetKind(cast(SemDC), entity->def.parent_kind); } else if (is_decl) { SourceRange R = OrigD->getSourceRange(); entity->declarations.push_back( @@ -801,13 +801,13 @@ class IndexDataConsumer : public index::IndexDataConsumer { entity->def.comments = Intern(GetComment(OrigD)); }; switch (kind) { - case SymbolKind::Invalid: + case Kind::Invalid: LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " << info->qualified << " in " << db->path << ":" << loc.start.line + 1; return true; - case SymbolKind::File: + case Kind::File: return true; - case SymbolKind::Func: + case Kind::Func: func = &db->ToFunc(usr); func->def.kind = ls_kind; // Mark as Role::Implicit to span one more column to the left/right. @@ -817,40 +817,40 @@ class IndexDataConsumer : public index::IndexDataConsumer { role = Role(role | Role::Implicit); do_def_decl(func); if (Spell != Loc) - AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); + AddMacroUse(db, SM, usr, Kind::Func, Spell); if (func->def.detailed_name[0] == '\0') SetName(D, info->short_name, info->qualified, func->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type) + if (GetKind(DC, ls_kind) == Kind::Type) db->ToType(GetUsr(DC)).def.funcs.push_back(usr); } else { const Decl *DC = cast(LexDC); - if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func) + if (GetKind(DC, ls_kind) == Kind::Func) db->ToFunc(GetUsr(DC)) - .def.callees.push_back({loc, usr, SymbolKind::Func, role}); + .def.callees.push_back({loc, usr, Kind::Func, role}); } break; - case SymbolKind::Type: + case Kind::Type: type = &db->ToType(usr); type->def.kind = ls_kind; do_def_decl(type); if (Spell != Loc) - AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); + AddMacroUse(db, SM, usr, Kind::Type, Spell); if (type->def.detailed_name[0] == '\0' && info->short_name.size()) SetName(D, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type) + if (GetKind(DC, ls_kind) == Kind::Type) db->ToType(GetUsr(DC)).def.types.push_back(usr); } break; - case SymbolKind::Var: + case Kind::Var: var = &db->ToVar(usr); var->def.kind = ls_kind; do_def_decl(var); if (Spell != Loc) - AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); + AddMacroUse(db, SM, usr, Kind::Var, Spell); if (var->def.detailed_name[0] == '\0') SetVarName(D, info->short_name, info->qualified, var->def); QualType T; @@ -858,10 +858,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { T = VD->getType(); if (is_def || is_decl) { const Decl *DC = cast(SemDC); - SymbolKind kind = GetSymbolKind(DC, var->def.parent_kind); - if (kind == SymbolKind::Func) + Kind kind = GetKind(DC, var->def.parent_kind); + if (kind == Kind::Func) db->ToFunc(GetUsr(DC)).def.vars.push_back(usr); - else if (kind == SymbolKind::Type && !isa(SemDC)) + else if (kind == Kind::Type && !isa(SemDC)) db->ToType(GetUsr(DC)).def.vars.emplace_back(usr, -1); if (!T.isNull()) { if (auto *BT = T->getAs()) { @@ -885,8 +885,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { FromTokenRange(SM, Lang, R1)}; type1.def.detailed_name = Intern(info1->short_name); type1.def.short_name_size = int16_t(info1->short_name.size()); - type1.def.kind = lsSymbolKind::TypeParameter; - type1.def.parent_kind = lsSymbolKind::Class; + type1.def.kind = SymbolKind::TypeParameter; + type1.def.parent_kind = SymbolKind::Class; var->def.type = usr1; type1.instances.push_back(usr); break; @@ -907,7 +907,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { var->def.spell = { Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}, FromTokenRange(SM, Lang, D->getSourceRange())}; - var->def.parent_kind = lsSymbolKind::Method; + var->def.parent_kind = SymbolKind::Method; } } break; @@ -976,7 +976,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: - type->def.kind = lsSymbolKind::Class; + type->def.kind = SymbolKind::Class; if (is_def) { if (auto *ORD = dyn_cast(OrigD)) CollectRecordMembers(*type, ORD); @@ -1104,8 +1104,8 @@ class IndexPPCallbacks : public PPCallbacks { auto [Name, usr] = GetMacro(Tok); IndexVar &var = db->ToVar(usr); Range range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); - var.def.kind = lsSymbolKind::Macro; - var.def.parent_kind = lsSymbolKind::File; + var.def.kind = SymbolKind::Macro; + var.def.parent_kind = SymbolKind::File; if (var.def.spell) var.declarations.push_back(*var.def.spell); const MacroInfo *MI = MD->getMacroInfo(); @@ -1368,7 +1368,7 @@ void Reflect(Reader &vis, SymbolRef &v) { v.range = Range::FromString(s); s = strchr(s, '|'); v.usr = strtoull(s + 1, &s, 10); - v.kind = static_cast(strtol(s + 1, &s, 10)); + v.kind = static_cast(strtol(s + 1, &s, 10)); v.role = static_cast(strtol(s + 1, &s, 10)); } else { Reflect(vis, v.range); diff --git a/src/indexer.hh b/src/indexer.hh index cce9c2e6f..30b11ddb0 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -47,7 +47,7 @@ enum class LanguageId; struct SymbolIdx { Usr usr; - SymbolKind kind; + Kind kind; bool operator==(const SymbolIdx &o) const { return usr == o.usr && kind == o.kind; @@ -62,10 +62,10 @@ MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind); struct SymbolRef { Range range; Usr usr; - SymbolKind kind; + Kind kind; Role role; operator SymbolIdx() const { return {usr, kind}; } - std::tuple ToTuple() const { + std::tuple ToTuple() const { return std::make_tuple(range, usr, kind, role); } bool operator==(const SymbolRef &o) const { return ToTuple() == o.ToTuple(); } @@ -74,7 +74,7 @@ struct SymbolRef { struct ExtentRef : SymbolRef { Range extent; - std::tuple ToTuple() const { + std::tuple ToTuple() const { return std::make_tuple(range, usr, kind, role, extent); } bool operator==(const ExtentRef &o) const { return ToTuple() == o.ToTuple(); } @@ -145,8 +145,8 @@ struct FuncDef : NameMixin { int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; - lsSymbolKind kind = lsSymbolKind::Unknown; - lsSymbolKind parent_kind = lsSymbolKind::Unknown; + SymbolKind kind = SymbolKind::Unknown; + SymbolKind parent_kind = SymbolKind::Unknown; uint8_t storage = clang::SC_None; std::vector GetBases() const { return bases; } @@ -183,8 +183,8 @@ struct TypeDef : NameMixin { int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; - lsSymbolKind kind = lsSymbolKind::Unknown; - lsSymbolKind parent_kind = lsSymbolKind::Unknown; + SymbolKind kind = SymbolKind::Unknown; + SymbolKind parent_kind = SymbolKind::Unknown; std::vector GetBases() const { return bases; } }; @@ -215,18 +215,18 @@ struct VarDef : NameMixin { int16_t qual_name_offset = 0; int16_t short_name_offset = 0; int16_t short_name_size = 0; - lsSymbolKind kind = lsSymbolKind::Unknown; - lsSymbolKind parent_kind = lsSymbolKind::Unknown; + SymbolKind kind = SymbolKind::Unknown; + SymbolKind parent_kind = SymbolKind::Unknown; // Note a variable may have instances of both |None| and |Extern| // (declaration). uint8_t storage = clang::SC_None; bool is_local() const { return spell && - (parent_kind == lsSymbolKind::Function || - parent_kind == lsSymbolKind::Method || - parent_kind == lsSymbolKind::StaticMethod || - parent_kind == lsSymbolKind::Constructor) && + (parent_kind == SymbolKind::Function || + parent_kind == SymbolKind::Method || + parent_kind == SymbolKind::StaticMethod || + parent_kind == SymbolKind::Constructor) && storage == clang::SC_None; } diff --git a/src/lsp.cc b/src/lsp.cc index 705d7817a..79f04d04f 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -21,55 +21,48 @@ limitations under the License. #include namespace ccls { -void Reflect(Reader &visitor, lsRequestId &value) { +void Reflect(Reader &visitor, RequestId &value) { if (visitor.IsInt64()) { - value.type = lsRequestId::kInt; + value.type = RequestId::kInt; value.value = int(visitor.GetInt64()); } else if (visitor.IsInt()) { - value.type = lsRequestId::kInt; + value.type = RequestId::kInt; value.value = visitor.GetInt(); } else if (visitor.IsString()) { - value.type = lsRequestId::kString; + value.type = RequestId::kString; value.value = atoll(visitor.GetString()); } else { - value.type = lsRequestId::kNone; + value.type = RequestId::kNone; value.value = -1; } } -void Reflect(Writer &visitor, lsRequestId &value) { +void Reflect(Writer &visitor, RequestId &value) { switch (value.type) { - case lsRequestId::kNone: + case RequestId::kNone: visitor.Null(); break; - case lsRequestId::kInt: + case RequestId::kInt: visitor.Int(value.value); break; - case lsRequestId::kString: + case RequestId::kString: auto s = std::to_string(value.value); visitor.String(s.c_str(), s.length()); break; } } -lsTextDocumentIdentifier -lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { - lsTextDocumentIdentifier result; - result.uri = uri; - return result; -} - -lsDocumentUri lsDocumentUri::FromPath(const std::string &path) { - lsDocumentUri result; +DocumentUri DocumentUri::FromPath(const std::string &path) { + DocumentUri result; result.SetPath(path); return result; } -bool lsDocumentUri::operator==(const lsDocumentUri &other) const { +bool DocumentUri::operator==(const DocumentUri &other) const { return raw_uri == other.raw_uri; } -void lsDocumentUri::SetPath(const std::string &path) { +void DocumentUri::SetPath(const std::string &path) { // file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests raw_uri = path; @@ -110,7 +103,7 @@ void lsDocumentUri::SetPath(const std::string &path) { raw_uri = std::move(t); } -std::string lsDocumentUri::GetPath() const { +std::string DocumentUri::GetPath() const { if (raw_uri.compare(0, 7, "file://")) { LOG_S(WARNING) << "Received potentially bad URI (not starting with file://): " @@ -147,7 +140,7 @@ std::string lsPosition::ToString() const { return std::to_string(line) + ":" + std::to_string(character); } -bool lsTextEdit::operator==(const lsTextEdit &that) { +bool TextEdit::operator==(const TextEdit &that) { return range == that.range && newText == that.newText; } } // namespace ccls diff --git a/src/lsp.hh b/src/lsp.hh index b28f322cc..2e370c877 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -25,7 +25,7 @@ limitations under the License. #include namespace ccls { -struct lsRequestId { +struct RequestId { // The client can send the request id as an int or a string. We should output // the same format we received. enum Type { kNone, kInt, kString }; @@ -35,17 +35,17 @@ struct lsRequestId { bool Valid() const { return type != kNone; } }; -void Reflect(Reader &visitor, lsRequestId &value); -void Reflect(Writer &visitor, lsRequestId &value); +void Reflect(Reader &visitor, RequestId &value); +void Reflect(Writer &visitor, RequestId &value); struct InMessage { - lsRequestId id; + RequestId id; std::string method; std::unique_ptr message; std::unique_ptr document; }; -enum class lsErrorCodes { +enum class ErrorCode { // Defined by JSON RPC ParseError = -32700, InvalidRequest = -32600, @@ -60,11 +60,11 @@ enum class lsErrorCodes { // Defined by the protocol. RequestCancelled = -32800, }; -MAKE_REFLECT_TYPE_PROXY(lsErrorCodes); +MAKE_REFLECT_TYPE_PROXY(ErrorCode); -struct lsResponseError { +struct ResponseError { // A number indicating the error type that occurred. - lsErrorCodes code; + ErrorCode code; // A string providing a short description of the error. std::string message; @@ -73,7 +73,7 @@ struct lsResponseError { // information about the error. Can be omitted. // std::optional data; }; -MAKE_REFLECT_STRUCT(lsResponseError, code, message); +MAKE_REFLECT_STRUCT(ResponseError, code, message); constexpr char ccls_xref[] = "ccls.xref"; constexpr char window_showMessage[] = "window/showMessage"; @@ -86,10 +86,10 @@ constexpr char window_showMessage[] = "window/showMessage"; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -struct lsDocumentUri { - static lsDocumentUri FromPath(const std::string &path); +struct DocumentUri { + static DocumentUri FromPath(const std::string &path); - bool operator==(const lsDocumentUri &other) const; + bool operator==(const DocumentUri &other) const; void SetPath(const std::string &path); std::string GetPath() const; @@ -98,7 +98,7 @@ struct lsDocumentUri { }; template -void Reflect(TVisitor &visitor, lsDocumentUri &value) { +void Reflect(TVisitor &visitor, DocumentUri &value) { Reflect(visitor, value.raw_uri); } @@ -127,20 +127,20 @@ struct lsRange { }; MAKE_REFLECT_STRUCT(lsRange, start, end); -struct lsLocation { - lsDocumentUri uri; +struct Location { + DocumentUri uri; lsRange range; - bool operator==(const lsLocation &o) const { + bool operator==(const Location &o) const { return uri == o.uri && range == o.range; } - bool operator<(const lsLocation &o) const { + bool operator<(const Location &o) const { return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri : range < o.range; } }; -MAKE_REFLECT_STRUCT(lsLocation, uri, range); +MAKE_REFLECT_STRUCT(Location, uri, range); -enum class lsSymbolKind : uint8_t { +enum class SymbolKind : uint8_t { Unknown = 0, File = 1, @@ -181,30 +181,28 @@ enum class lsSymbolKind : uint8_t { StaticMethod = 254, Macro = 255, }; -MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); +MAKE_REFLECT_TYPE_PROXY(SymbolKind); -struct lsSymbolInformation { +struct SymbolInformation { std::string_view name; - lsSymbolKind kind; - lsLocation location; + SymbolKind kind; + Location location; std::optional containerName; }; -struct lsTextDocumentIdentifier { - lsDocumentUri uri; +struct TextDocumentIdentifier { + DocumentUri uri; }; -MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri); +MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri); -struct lsVersionedTextDocumentIdentifier { - lsDocumentUri uri; +struct VersionedTextDocumentIdentifier { + DocumentUri uri; // The version number of this document. number | null std::optional version; - - lsTextDocumentIdentifier AsTextDocumentIdentifier() const; }; -MAKE_REFLECT_STRUCT(lsVersionedTextDocumentIdentifier, uri, version); +MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); -struct lsTextEdit { +struct TextEdit { // The range of the text document to be manipulated. To insert // text into a document create a range where start === end. lsRange range; @@ -213,13 +211,13 @@ struct lsTextEdit { // empty string. std::string newText; - bool operator==(const lsTextEdit &that); + bool operator==(const TextEdit &that); }; -MAKE_REFLECT_STRUCT(lsTextEdit, range, newText); +MAKE_REFLECT_STRUCT(TextEdit, range, newText); -struct lsTextDocumentItem { +struct TextDocumentItem { // The text document's URI. - lsDocumentUri uri; + DocumentUri uri; // The text document's language identifier. std::string languageId; @@ -231,28 +229,21 @@ struct lsTextDocumentItem { // The content of the opened text document. std::string text; }; -MAKE_REFLECT_STRUCT(lsTextDocumentItem, uri, languageId, version, text); +MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); -struct lsTextDocumentEdit { +struct TextDocumentEdit { // The text document to change. - lsVersionedTextDocumentIdentifier textDocument; + VersionedTextDocumentIdentifier textDocument; // The edits to be applied. - std::vector edits; + std::vector edits; }; -MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits); +MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits); -struct lsWorkspaceEdit { - // Holds changes to existing resources. - // changes ? : { [uri:string]: TextEdit[]; }; - // std::unordered_map> changes; - - // An array of `TextDocumentEdit`s to express changes to specific a specific - // version of a text document. Whether a client supports versioned document - // edits is expressed via `WorkspaceClientCapabilites.versionedWorkspaceEdit`. - std::vector documentChanges; +struct WorkspaceEdit { + std::vector documentChanges; }; -MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges); +MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges); struct TextDocumentContentChangeEvent { // The range of the document that changed. @@ -264,12 +255,12 @@ struct TextDocumentContentChangeEvent { }; struct TextDocumentDidChangeParam { - lsVersionedTextDocumentIdentifier textDocument; + VersionedTextDocumentIdentifier textDocument; std::vector contentChanges; }; struct WorkspaceFolder { - lsDocumentUri uri; + DocumentUri uri; std::string name; }; MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); @@ -278,7 +269,7 @@ MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; MAKE_REFLECT_TYPE_PROXY(MessageType) -enum class lsDiagnosticSeverity { +enum class DiagnosticSeverity { // Reports an error. Error = 1, // Reports a warning. @@ -288,15 +279,15 @@ enum class lsDiagnosticSeverity { // Reports a hint. Hint = 4 }; -MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity); +MAKE_REFLECT_TYPE_PROXY(DiagnosticSeverity); -struct lsDiagnostic { +struct Diagnostic { // The range at which the message applies. lsRange range; // The diagnostic's severity. Can be omitted. If omitted it is up to the // client to interpret diagnostics as error, warning, info or hint. - std::optional severity; + std::optional severity; // The diagnostic's code. Can be omitted. int code = 0; @@ -309,24 +300,15 @@ struct lsDiagnostic { std::string message; // Non-serialized set of fixits. - std::vector fixits_; + std::vector fixits_; }; -MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message); - -struct lsPublishDiagnosticsParams { - // The URI for which diagnostic information is reported. - lsDocumentUri uri; +MAKE_REFLECT_STRUCT(Diagnostic, range, severity, source, message); - // An array of diagnostic information items. - std::vector diagnostics; -}; -MAKE_REFLECT_STRUCT(lsPublishDiagnosticsParams, uri, diagnostics); - -struct lsShowMessageParams { +struct ShowMessageParam { MessageType type = MessageType::Error; std::string message; }; -MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message); +MAKE_REFLECT_STRUCT(ShowMessageParam, type, message); // Used to identify the language at a file level. The ordering is important, as // a file previously identified as `C`, will be changed to `Cpp` if it @@ -336,8 +318,8 @@ MAKE_REFLECT_TYPE_PROXY(LanguageId); // The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in // front of others. -enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; -MAKE_REFLECT_TYPE_PROXY(SymbolKind); +enum class Kind : uint8_t { Invalid, File, Type, Func, Var }; +MAKE_REFLECT_TYPE_PROXY(Kind); enum class Role : uint16_t { None = 0, diff --git a/src/match.cc b/src/match.cc index 125f2bba0..d9b7b2344 100644 --- a/src/match.cc +++ b/src/match.cc @@ -30,7 +30,7 @@ std::optional Matcher::Create(const std::string &search) { ); return m; } catch (const std::exception &e) { - lsShowMessageParams params; + ShowMessageParam params; params.type = MessageType::Error; params.message = "failed to parse EMCAScript regex " + search + " : " + e.what(); diff --git a/src/message_handler.cc b/src/message_handler.cc index dd04f797f..626983da0 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -43,9 +43,9 @@ MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); // completion -MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind); -MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter); -MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context); +MAKE_REFLECT_TYPE_PROXY(CompletionTriggerKind); +MAKE_REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter); +MAKE_REFLECT_STRUCT(CompletionParam, textDocument, position, context); // formatting MAKE_REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces); @@ -65,8 +65,8 @@ MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query, folders); namespace { struct CclsSemanticHighlightSymbol { int id = 0; - lsSymbolKind parentKind; - lsSymbolKind kind; + SymbolKind parentKind; + SymbolKind kind; uint8_t storage; std::vector> ranges; @@ -75,7 +75,7 @@ struct CclsSemanticHighlightSymbol { }; struct CclsSemanticHighlightParams { - lsDocumentUri uri; + DocumentUri uri; std::vector symbols; }; MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, @@ -83,7 +83,7 @@ MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, MAKE_REFLECT_STRUCT(CclsSemanticHighlightParams, uri, symbols); struct CclsSetSkippedRangesParams { - lsDocumentUri uri; + DocumentUri uri; std::vector skippedRanges; }; MAKE_REFLECT_STRUCT(CclsSetSkippedRangesParams, uri, skippedRanges); @@ -206,19 +206,19 @@ void MessageHandler::Run(InMessage &msg) { try { it->second(reader, reply); } catch (std::invalid_argument &ex) { - lsResponseError err; - err.code = lsErrorCodes::InvalidParams; + ResponseError err; + err.code = ErrorCode::InvalidParams; err.message = "invalid params of " + msg.method + ": " + ex.what(); reply.Error(err); } catch (...) { - lsResponseError err; - err.code = lsErrorCodes::InternalError; + ResponseError err; + err.code = ErrorCode::InternalError; err.message = "failed to process " + msg.method; reply.Error(err); } } else { - lsResponseError err; - err.code = lsErrorCodes::MethodNotFound; + ResponseError err; + err.code = ErrorCode::MethodNotFound; err.message = "unknown request " + msg.method; reply.Error(err); } @@ -258,12 +258,12 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply, for (auto &[root, folder] : project->root2folder) has_entry |= folder.path2entry_index.count(path); } - lsResponseError err; + ResponseError err; if (has_entry) { - err.code = lsErrorCodes::ServerNotInitialized; + err.code = ErrorCode::ServerNotInitialized; err.message = path + " is being indexed"; } else { - err.code = lsErrorCodes::InternalError; + err.code = ErrorCode::InternalError; err.message = "unable to find " + path; } reply.Error(err); @@ -274,7 +274,7 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply, void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) { CclsSetSkippedRangesParams params; - params.uri = lsDocumentUri::FromPath(wfile->filename); + params.uri = DocumentUri::FromPath(wfile->filename); for (Range skipped : file.def->skipped_ranges) if (auto ls_skipped = GetLsRange(wfile, skipped)) params.skippedRanges.push_back(*ls_skipped); @@ -294,13 +294,13 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { for (auto [sym, refcnt] : file.symbol2refcnt) { if (refcnt <= 0) continue; std::string_view detailed_name; - lsSymbolKind parent_kind = lsSymbolKind::Unknown; - lsSymbolKind kind = lsSymbolKind::Unknown; + SymbolKind parent_kind = SymbolKind::Unknown; + SymbolKind kind = SymbolKind::Unknown; uint8_t storage = SC_None; int idx; // This switch statement also filters out symbols that are not highlighted. switch (sym.kind) { - case SymbolKind::Func: { + case Kind::Func: { idx = db->func_usr[sym.usr]; const QueryFunc &func = db->funcs[idx]; const QueryFunc::Def *def = func.AnyDef(); @@ -334,7 +334,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { sym.range.end.column = start_col + concise_name.size(); break; } - case SymbolKind::Type: { + case Kind::Type: { idx = db->type_usr[sym.usr]; const QueryType &type = db->types[idx]; for (auto &def : type.def) { @@ -347,7 +347,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { } break; } - case SymbolKind::Var: { + case Kind::Var: { idx = db->var_usr[sym.usr]; const QueryVar &var = db->vars[idx]; for (auto &def : var.def) { @@ -422,7 +422,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { } CclsSemanticHighlightParams params; - params.uri = lsDocumentUri::FromPath(wfile->filename); + params.uri = DocumentUri::FromPath(wfile->filename); // Transform lsRange into pair (offset pairs) if (!g_config->highlight.lsRanges) { std::vector> scratch; diff --git a/src/message_handler.hh b/src/message_handler.hh index a24979dfa..00ad2aeb3 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -32,54 +32,54 @@ struct WorkingFile; struct WorkingFiles; namespace pipeline { -void Reply(lsRequestId id, const std::function &fn); -void ReplyError(lsRequestId id, const std::function &fn); +void Reply(RequestId id, const std::function &fn); +void ReplyError(RequestId id, const std::function &fn); } struct EmptyParam { bool placeholder; }; struct TextDocumentParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; }; struct DidOpenTextDocumentParam { - lsTextDocumentItem textDocument; + TextDocumentItem textDocument; }; struct TextDocumentPositionParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsPosition position; }; struct RenameParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsPosition position; std::string newName; }; // code* struct CodeActionParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsRange range; struct Context { - std::vector diagnostics; + std::vector diagnostics; } context; }; // completion -enum class lsCompletionTriggerKind { +enum class CompletionTriggerKind { Invoked = 1, TriggerCharacter = 2, TriggerForIncompleteCompletions = 3, }; -struct lsCompletionContext { - lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked; +struct CompletionContext { + CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked; std::optional triggerCharacter; }; -struct lsCompletionParams : TextDocumentPositionParam { - lsCompletionContext context; +struct CompletionParam : TextDocumentPositionParam { + CompletionContext context; }; -enum class lsCompletionItemKind { +enum class CompletionItemKind { Text = 1, Method = 2, Function = 3, @@ -106,21 +106,21 @@ enum class lsCompletionItemKind { Operator = 24, TypeParameter = 25, }; -enum class lsInsertTextFormat { +enum class InsertTextFormat { PlainText = 1, Snippet = 2 }; -struct lsCompletionItem { +struct CompletionItem { std::string label; - lsCompletionItemKind kind = lsCompletionItemKind::Text; + CompletionItemKind kind = CompletionItemKind::Text; std::string detail; std::optional documentation; std::string sortText; std::optional filterText; std::string insertText; - lsInsertTextFormat insertTextFormat = lsInsertTextFormat::PlainText; - lsTextEdit textEdit; - std::vector additionalTextEdits; + InsertTextFormat insertTextFormat = InsertTextFormat::PlainText; + TextEdit textEdit; + std::vector additionalTextEdits; std::vector parameters_; int score_; @@ -134,17 +134,17 @@ struct FormattingOptions { bool insertSpaces; }; struct DocumentFormattingParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; FormattingOptions options; }; struct DocumentOnTypeFormattingParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsPosition position; std::string ch; FormattingOptions options; }; struct DocumentRangeFormattingParam { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsRange range; FormattingOptions options; }; @@ -157,7 +157,7 @@ enum class FileChangeType { }; struct DidChangeWatchedFilesParam { struct Event { - lsDocumentUri uri; + DocumentUri uri; FileChangeType type; }; std::vector changes; @@ -179,7 +179,7 @@ template using Callback = std::function; struct ReplyOnce { - lsRequestId id; + RequestId id; template void operator()(Res &result) const { if (id.Valid()) pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); }); @@ -229,7 +229,7 @@ private: void shutdown(EmptyParam &, ReplyOnce &); void textDocument_codeAction(CodeActionParam &, ReplyOnce &); void textDocument_codeLens(TextDocumentParam &, ReplyOnce &); - void textDocument_completion(lsCompletionParams &, ReplyOnce &); + void textDocument_completion(CompletionParam &, ReplyOnce &); void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &); void textDocument_didChange(TextDocumentDidChangeParam &); void textDocument_didClose(TextDocumentParam &); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 14766d2c6..babf849c1 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -59,7 +59,7 @@ struct Out_cclsCall { Usr usr; std::string id; std::string_view name; - lsLocation location; + Location location; CallType callType = CallType::Direct; int numChildren; // Empty if the |levels| limit is reached. @@ -97,15 +97,14 @@ bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, if (callee) { if (const auto *def = func.AnyDef()) for (SymbolRef sym : def->callees) - if (sym.kind == SymbolKind::Func) + if (sym.kind == Kind::Func) handle(sym, def->file_id, call_type); } else { for (Use use : func.uses) { const QueryFile &file1 = m->db->files[use.file_id]; Maybe best; for (auto [sym, refcnt] : file1.symbol2refcnt) - if (refcnt > 0 && sym.extent.Valid() && - sym.kind == SymbolKind::Func && + if (refcnt > 0 && sym.extent.Valid() && sym.kind == Kind::Func && sym.extent.start <= use.range.start && use.range.end <= sym.extent.end && (!best || best->extent.start < sym.extent.start)) @@ -207,7 +206,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, param.position)) { - if (sym.kind == SymbolKind::Func) { + if (sym.kind == Kind::Func) { result = BuildInitial(this, sym.usr, param.callee, param.callType, param.qualified, param.levels); break; diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 4afecee06..558d537b5 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -27,7 +27,7 @@ struct Param : TextDocumentPositionParam { // should be specified for building the root and |levels| of nodes below. Usr usr; std::string id; - SymbolKind kind = SymbolKind::Invalid; + Kind kind = Kind::Invalid; // true: derived classes/functions; false: base classes/functions bool derived = false; @@ -42,9 +42,9 @@ MAKE_REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified, struct Out_cclsInheritance { Usr usr; std::string id; - SymbolKind kind; + Kind kind; std::string_view name; - lsLocation location; + Location location; // For unexpanded nodes, this is an upper bound because some entities may be // undefined. If it is 0, there are no members. int numChildren; @@ -111,7 +111,7 @@ bool ExpandHelper(MessageHandler *m, Out_cclsInheritance *entry, bool derived, bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived, bool qualified, int levels) { - if (entry->kind == SymbolKind::Func) + if (entry->kind == Kind::Func) return ExpandHelper(m, entry, derived, qualified, levels, m->db->Func(entry->usr)); else @@ -141,10 +141,9 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { result->id = std::to_string(param.usr); result->usr = param.usr; result->kind = param.kind; - if (!(((param.kind == SymbolKind::Func && m->db->HasFunc(param.usr)) || - (param.kind == SymbolKind::Type && m->db->HasType(param.usr))) && - Expand(m, &*result, param.derived, param.qualified, - param.levels))) + if (!(((param.kind == Kind::Func && m->db->HasFunc(param.usr)) || + (param.kind == Kind::Type && m->db->HasType(param.usr))) && + Expand(m, &*result, param.derived, param.qualified, param.levels))) result.reset(); } else { QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath()); @@ -153,7 +152,7 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { WorkingFile *wfile = m->wfiles->GetFileByFilename(file->def->path); for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) - if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { + if (sym.kind == Kind::Func || sym.kind == Kind::Type) { result = BuildInitial(m, sym, param.derived, param.qualified, param.levels); break; diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index 45c8fd822..fd7d2c4a4 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -36,9 +36,9 @@ struct Param : TextDocumentPositionParam { bool qualified = false; int levels = 1; - // If SymbolKind::Func and the point is at a type, list member functions - // instead of member variables. - SymbolKind kind = SymbolKind::Var; + // If Kind::Func and the point is at a type, list member functions instead of + // member variables. + Kind kind = Kind::Var; bool hierarchy = false; }; @@ -50,7 +50,7 @@ struct Out_cclsMember { std::string id; std::string_view name; std::string fieldName; - lsLocation location; + Location location; // For unexpanded nodes, this is an upper bound because some entities may be // undefined. If it is 0, there are no members. int numChildren = 0; @@ -61,7 +61,7 @@ MAKE_REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren, children); bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, - int levels, SymbolKind memberKind); + int levels, Kind memberKind); // Add a field to |entry| which is a Func/Type. void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var, @@ -89,14 +89,14 @@ void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var, entry1.fieldName += def1->Name(false); } if (def1->spell) { - if (std::optional loc = + if (std::optional loc = GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } if (def1->type) { entry1.id = std::to_string(def1->type); entry1.usr = def1->type; - if (Expand(m, &entry1, qualified, levels, SymbolKind::Var)) + if (Expand(m, &entry1, qualified, levels, Kind::Var)) entry->children.push_back(std::move(entry1)); } else { entry1.id = "0"; @@ -107,7 +107,7 @@ void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var, // Expand a type node by adding members recursively to it. bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, - int levels, SymbolKind memberKind) { + int levels, Kind memberKind) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { entry->name = ClangBuiltinTypeName(int(entry->usr)); return true; @@ -129,7 +129,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, const auto *def = type->AnyDef(); if (!def) continue; - if (def->kind != lsSymbolKind::Namespace) + if (def->kind != SymbolKind::Namespace) for (Usr usr : def->bases) { auto &type1 = m->db->Type(usr); if (type1.def.size()) { @@ -144,13 +144,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, entry1.usr = def->alias_of; if (def1 && def1->spell) { // The declaration of target type. - if (std::optional loc = + if (std::optional loc = GetLsLocation(m->db, m->wfiles, *def1->spell)) entry1.location = *loc; } else if (def->spell) { // Builtin types have no declaration but the typedef declaration // itself is useful. - if (std::optional loc = + if (std::optional loc = GetLsLocation(m->db, m->wfiles, *def->spell)) entry1.location = *loc; } @@ -162,7 +162,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, entry1.fieldName = std::string(entry1.name); entry->children.push_back(std::move(entry1)); } - } else if (memberKind == SymbolKind::Func) { + } else if (memberKind == Kind::Func) { llvm::DenseSet seen1; for (auto &def : type->def) for (Usr usr : def.funcs) @@ -182,7 +182,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, entry->children.push_back(std::move(entry1)); } } - } else if (memberKind == SymbolKind::Type) { + } else if (memberKind == Kind::Type) { llvm::DenseSet seen1; for (auto &def : type->def) for (Usr usr : def.types) @@ -219,13 +219,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, return true; } -std::optional BuildInitial(MessageHandler *m, SymbolKind kind, +std::optional BuildInitial(MessageHandler *m, Kind kind, Usr root_usr, bool qualified, - int levels, SymbolKind memberKind) { + int levels, Kind memberKind) { switch (kind) { default: return {}; - case SymbolKind::Func: { + case Kind::Func: { const auto *def = m->db->Func(root_usr).AnyDef(); if (!def) return {}; @@ -244,7 +244,7 @@ std::optional BuildInitial(MessageHandler *m, SymbolKind kind, } return entry; } - case SymbolKind::Type: { + case Kind::Type: { const auto *def = m->db->Type(root_usr).AnyDef(); if (!def) return {}; @@ -288,15 +288,15 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { switch (sym.kind) { - case SymbolKind::Func: - case SymbolKind::Type: + case Kind::Func: + case Kind::Type: result = BuildInitial(this, sym.kind, sym.usr, param.qualified, param.levels, param.kind); break; - case SymbolKind::Var: { + case Kind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); if (def && def->type) - result = BuildInitial(this, SymbolKind::Type, def->type, param.qualified, + result = BuildInitial(this, Kind::Type, def->type, param.qualified, param.levels, param.kind); break; } diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index be76d8baf..0743891a1 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -19,7 +19,7 @@ limitations under the License. namespace ccls { namespace { struct Param { - lsTextDocumentIdentifier textDocument; + TextDocumentIdentifier textDocument; lsPosition position; std::string direction; }; @@ -95,10 +95,10 @@ void MessageHandler::ccls_navigate(Reader &reader, res = sym.extent; break; } - std::vector result; + std::vector result; if (res) if (auto ls_range = GetLsRange(wfile, *res)) { - lsLocation &ls_loc = result.emplace_back(); + Location &ls_loc = result.emplace_back(); ls_loc.uri = param.textDocument.uri; ls_loc.range = *ls_range; } diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 4bb292e01..0ec1bb855 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -40,7 +40,7 @@ void MessageHandler::ccls_reload(Reader &reader) { if (param.whitelist.empty() && param.blacklist.empty()) { vfs->Clear(); db->clear(); - project->Index(wfiles, lsRequestId()); + project->Index(wfiles, RequestId()); clang_complete->FlushAllSessions(); return; } diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 8b4531f2a..b8917e612 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -36,21 +36,21 @@ void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { return; WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); - std::vector result; + std::vector result; for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, param.position)) { Usr usr = sym.usr; switch (sym.kind) { default: break; - case SymbolKind::Var: { + case Kind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); if (!def || !def->type) continue; usr = def->type; [[fallthrough]]; } - case SymbolKind::Type: + case Kind::Type: result = GetLsLocations( db, wfiles, GetVarDeclarations(db, db->Type(usr).instances, param.kind)); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index ccc80e9c5..cc2d76c20 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -38,105 +38,37 @@ using namespace llvm; extern std::string g_init_options; namespace { +enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 }; +MAKE_REFLECT_TYPE_PROXY(TextDocumentSyncKind) -// Code Lens options. -struct lsCodeLensOptions { - // Code lens has a resolve provider as well. - bool resolveProvider = false; -}; -MAKE_REFLECT_STRUCT(lsCodeLensOptions, resolveProvider); - -// Completion options. -struct lsCompletionOptions { - // The server provides support to resolve additional - // information for a completion item. - bool resolveProvider = false; - - // The characters that trigger completion automatically. - // vscode doesn't support trigger character sequences, so we use ':' - // for - // '::' and '>' for '->'. See - // https://github.com/Microsoft/language-server-protocol/issues/138. - std::vector triggerCharacters = {".", ":", ">", "#", - "<", "\"", "/"}; -}; -MAKE_REFLECT_STRUCT(lsCompletionOptions, resolveProvider, triggerCharacters); - -// Format document on type options -struct lsDocumentOnTypeFormattingOptions { - // A character on which formatting should be triggered, like `}`. - std::string firstTriggerCharacter = "}"; - - // More trigger characters. - std::vector moreTriggerCharacter; -}; -MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter, - moreTriggerCharacter); - - -// Save options. -struct lsSaveOptions { - // The client is supposed to include the content on save. - bool includeText = false; -}; -MAKE_REFLECT_STRUCT(lsSaveOptions, includeText); - -// Signature help options. -struct lsSignatureHelpOptions { - // The characters that trigger signature help automatically. - // NOTE: If updating signature help tokens make sure to also update - // WorkingFile::FindClosestCallNameInBuffer. - std::vector triggerCharacters = {"(", ","}; -}; -MAKE_REFLECT_STRUCT(lsSignatureHelpOptions, triggerCharacters); - -// Defines how the host (editor) should sync document changes to the language -// server. -enum class lsTextDocumentSyncKind { - // Documents should not be synced at all. - None = 0, - - // Documents are synced by always sending the full content - // of the document. - Full = 1, - - // Documents are synced by sending the full content on open. - // After that only incremental updates to the document are - // send. - Incremental = 2 -}; -MAKE_REFLECT_TYPE_PROXY(lsTextDocumentSyncKind) - -struct lsTextDocumentSyncOptions { - // Open and close notifications are sent to the server. - bool openClose = false; - // Change notificatins are sent to the server. See TextDocumentSyncKind.None, - // TextDocumentSyncKind.Full and TextDocumentSyncKindIncremental. - lsTextDocumentSyncKind change = lsTextDocumentSyncKind::Incremental; - // Will save notifications are sent to the server. - std::optional willSave; - // Will save wait until requests are sent to the server. - std::optional willSaveWaitUntil; - // Save notifications are sent to the server. - std::optional save; -}; -MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave, - willSaveWaitUntil, save); - -struct lsServerCapabilities { - // Defines how text documents are synced. Is either a detailed structure - // defining each notification or for backwards compatibility the - // TextDocumentSyncKind number. - // TODO: It seems like the new API is broken and doesn't work. - // std::optional textDocumentSync; - lsTextDocumentSyncKind textDocumentSync = lsTextDocumentSyncKind::Incremental; +struct ServerCap { + struct SaveOptions { + bool includeText = false; + }; + struct TextDocumentSyncOptions { + bool openClose = true; + TextDocumentSyncKind change = TextDocumentSyncKind::Incremental; + bool willSave = false; + bool willSaveWaitUntil = false; + SaveOptions save; + } textDocumentSync; // The server provides hover support. bool hoverProvider = true; - // The server provides completion support. - lsCompletionOptions completionProvider; - // The server provides signature help support. - lsSignatureHelpOptions signatureHelpProvider; + struct CompletionOptions { + bool resolveProvider = false; + + // The characters that trigger completion automatically. + // vscode doesn't support trigger character sequences, so we use ':' + // for + // '::' and '>' for '->'. See + // https://github.com/Microsoft/language-server-protocol/issues/138. + std::vector triggerCharacters = {".", ":", ">", "#", + "<", "\"", "/"}; + } completionProvider; + struct SignatureHelpOptions { + std::vector triggerCharacters = {"(", ","}; + } signatureHelpProvider; bool definitionProvider = true; bool typeDefinitionProvider = true; bool implementationProvider = true; @@ -145,10 +77,15 @@ struct lsServerCapabilities { bool documentSymbolProvider = true; bool workspaceSymbolProvider = true; bool codeActionProvider = true; - lsCodeLensOptions codeLensProvider; + struct CodeLensOptions { + bool resolveProvider = false; + } codeLensProvider; bool documentFormattingProvider = true; bool documentRangeFormattingProvider = true; - lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider; + struct DocumentOnTypeFormattingOptions { + std::string firstTriggerCharacter = "}"; + std::vector moreTriggerCharacter; + } documentOnTypeFormattingProvider; bool renameProvider = true; struct DocumentLinkOptions { bool resolveProvider = true; @@ -165,12 +102,21 @@ struct lsServerCapabilities { } workspaceFolders; } workspace; }; -MAKE_REFLECT_STRUCT(lsServerCapabilities::DocumentLinkOptions, resolveProvider); -MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands); -MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders, - supported, changeNotifications); -MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace, workspaceFolders); -MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, +MAKE_REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider, + triggerCharacters); +MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); +MAKE_REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider); +MAKE_REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions, + firstTriggerCharacter, moreTriggerCharacter); +MAKE_REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands); +MAKE_REFLECT_STRUCT(ServerCap::SaveOptions, includeText); +MAKE_REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters); +MAKE_REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change, + willSave, willSaveWaitUntil, save); +MAKE_REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported, + changeNotifications); +MAKE_REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders); +MAKE_REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider, signatureHelpProvider, definitionProvider, implementationProvider, typeDefinitionProvider, referencesProvider, @@ -182,72 +128,38 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider, documentLinkProvider, foldingRangeProvider, executeCommandProvider, workspace); +struct DynamicReg { + bool dynamicRegistration = false; +}; +MAKE_REFLECT_STRUCT(DynamicReg, dynamicRegistration); + // Workspace specific client capabilities. -struct lsWorkspaceClientCapabilites { +struct WorkspaceClientCap { // The client supports applying batch edits to the workspace. std::optional applyEdit; - struct lsWorkspaceEdit { + struct WorkspaceEdit { // The client supports versioned document changes in `WorkspaceEdit`s std::optional documentChanges; }; // Capabilities specific to `WorkspaceEdit`s - std::optional workspaceEdit; - - struct lsGenericDynamicReg { - // Did foo notification supports dynamic registration. - std::optional dynamicRegistration; - }; - - // Capabilities specific to the `workspace/didChangeConfiguration` - // notification. - std::optional didChangeConfiguration; - - // Capabilities specific to the `workspace/didChangeWatchedFiles` - // notification. - std::optional didChangeWatchedFiles; - - // Capabilities specific to the `workspace/symbol` request. - std::optional symbol; - - // Capabilities specific to the `workspace/executeCommand` request. - std::optional executeCommand; + std::optional workspaceEdit; + DynamicReg didChangeConfiguration; + DynamicReg didChangeWatchedFiles; + DynamicReg symbol; + DynamicReg executeCommand; }; -MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit, - documentChanges); -MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg, - dynamicRegistration); -MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, applyEdit, workspaceEdit, +MAKE_REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges); +MAKE_REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit, didChangeConfiguration, didChangeWatchedFiles, symbol, executeCommand); // Text document specific client capabilities. -struct lsTextDocumentClientCapabilities { - struct lsSynchronization { - // Whether text document synchronization supports dynamic registration. - std::optional dynamicRegistration; - - // The client supports sending will save notifications. - std::optional willSave; - - // The client supports sending a will save request and - // waits for a response providing text edits which will - // be applied to the document before it is saved. - std::optional willSaveWaitUntil; - - // The client supports did save notifications. - std::optional didSave; - }; - - lsSynchronization synchronization; - - struct lsCompletion { - // Whether completion supports dynamic registration. - std::optional dynamicRegistration; - - struct lsCompletionItem { +struct TextDocumentClientCap { + struct Completion { + struct CompletionItem { // Client supports snippets as insert text. // // A snippet can define tab stops and placeholders with `$1`, `$2` @@ -258,99 +170,65 @@ struct lsTextDocumentClientCapabilities { } completionItem; } completion; - struct lsDocumentSymbol { + struct DocumentSymbol { bool hierarchicalDocumentSymbolSupport = false; } documentSymbol; - - struct lsGenericDynamicReg { - // Whether foo supports dynamic registration. - std::optional dynamicRegistration; - }; - - struct CodeLensRegistrationOptions : public lsGenericDynamicReg { - // Code lens has a resolve provider as well. - bool resolveProvider; - }; - - // Capabilities specific to the `textDocument/codeLens` - std::optional codeLens; - - // Capabilities specific to the `textDocument/rename` - std::optional rename; }; -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, - dynamicRegistration, willSave, willSaveWaitUntil, didSave); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion, - dynamicRegistration, completionItem); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsDocumentSymbol, +MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem, + snippetSupport); +MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem); +MAKE_REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol, hierarchicalDocumentSymbolSupport); -MAKE_REFLECT_STRUCT( - lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem, - snippetSupport); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg, - dynamicRegistration); -MAKE_REFLECT_STRUCT( - lsTextDocumentClientCapabilities::CodeLensRegistrationOptions, - dynamicRegistration, resolveProvider); -MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, completion, - documentSymbol, rename, synchronization); - -struct lsClientCapabilities { - // Workspace specific client capabilities. - lsWorkspaceClientCapabilites workspace; - - // Text document specific client capabilities. - lsTextDocumentClientCapabilities textDocument; +MAKE_REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol); + +struct ClientCap { + WorkspaceClientCap workspace; + TextDocumentClientCap textDocument; }; -MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); +MAKE_REFLECT_STRUCT(ClientCap, workspace, textDocument); -struct lsInitializeParams { +struct InitializeParam { // The rootUri of the workspace. Is null if no // folder is open. If both `rootPath` and `rootUri` are set // `rootUri` wins. - std::optional rootUri; + std::optional rootUri; - // User provided initialization options. Config initializationOptions; + ClientCap capabilities; - // The capabilities provided by the client (editor or tool) - lsClientCapabilities capabilities; - - enum class lsTrace { + enum class Trace { // NOTE: serialized as a string, one of 'off' | 'messages' | 'verbose'; Off, // off Messages, // messages Verbose // verbose }; - - // The initial trace setting. If omitted trace is disabled ('off'). - lsTrace trace = lsTrace::Off; + Trace trace = Trace::Off; std::vector workspaceFolders; }; -void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { +void Reflect(Reader &reader, InitializeParam::Trace &value) { if (!reader.IsString()) { - value = lsInitializeParams::lsTrace::Off; + value = InitializeParam::Trace::Off; return; } std::string v = reader.GetString(); if (v == "off") - value = lsInitializeParams::lsTrace::Off; + value = InitializeParam::Trace::Off; else if (v == "messages") - value = lsInitializeParams::lsTrace::Messages; + value = InitializeParam::Trace::Messages; else if (v == "verbose") - value = lsInitializeParams::lsTrace::Verbose; + value = InitializeParam::Trace::Verbose; } -MAKE_REFLECT_STRUCT(lsInitializeParams, rootUri, initializationOptions, +MAKE_REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, capabilities, trace, workspaceFolders); -struct lsInitializeResult { - lsServerCapabilities capabilities; +struct InitializeResult { + ServerCap capabilities; }; -MAKE_REFLECT_STRUCT(lsInitializeResult, capabilities); +MAKE_REFLECT_STRUCT(InitializeResult, capabilities); void *Indexer(void *arg_) { MessageHandler *h; @@ -365,7 +243,7 @@ void *Indexer(void *arg_) { } } // namespace -void Initialize(MessageHandler *m, lsInitializeParams ¶m, ReplyOnce &reply) { +void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { std::string project_path = NormalizePath(param.rootUri->GetPath()); LOG_S(INFO) << "initialize in directory " << project_path << " with uri " << param.rootUri->raw_uri; @@ -413,7 +291,7 @@ void Initialize(MessageHandler *m, lsInitializeParams ¶m, ReplyOnce &reply) // Send initialization before starting indexers, so we don't send a // status update too early. { - lsInitializeResult result; + InitializeResult result; reply(result); } @@ -460,7 +338,7 @@ void Initialize(MessageHandler *m, lsInitializeParams ¶m, ReplyOnce &reply) } void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { - lsInitializeParams param; + InitializeParam param; Reflect(reader, param); if (!param.rootUri) return; @@ -468,8 +346,8 @@ void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { } void StandaloneInitialize(MessageHandler &handler, const std::string &root) { - lsInitializeParams param; - param.rootUri = lsDocumentUri::FromPath(root); + InitializeParam param; + param.rootUri = DocumentUri::FromPath(root); ReplyOnce reply; Initialize(&handler, param, reply); } diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index 6bd2929b9..3f645c26a 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -27,7 +27,7 @@ namespace { struct CodeAction { std::string title; const char *kind = "quickfix"; - lsWorkspaceEdit edit; + WorkspaceEdit edit; }; MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); } @@ -39,9 +39,9 @@ void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, return; } std::vector result; - std::vector diagnostics; + std::vector diagnostics; wfiles->DoAction([&]() { diagnostics = wfile->diagnostics_; }); - for (lsDiagnostic &diag : diagnostics) + for (Diagnostic &diag : diagnostics) if (diag.fixits_.size()) { CodeAction &cmd = result.emplace_back(); cmd.title = "FixIt: " + diag.message; @@ -56,21 +56,21 @@ void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, namespace { struct Cmd_xref { Usr usr; - SymbolKind kind; + Kind kind; std::string field; }; -struct lsCommand { +struct Command { std::string title; std::string command; std::vector arguments; }; -struct lsCodeLens { +struct CodeLens { lsRange range; - std::optional command; + std::optional command; }; MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); -MAKE_REFLECT_STRUCT(lsCommand, title, command, arguments); -MAKE_REFLECT_STRUCT(lsCodeLens, range, command); +MAKE_REFLECT_STRUCT(Command, title, command, arguments); +MAKE_REFLECT_STRUCT(CodeLens, range, command); template std::string ToString(T &v) { @@ -82,7 +82,7 @@ std::string ToString(T &v) { } struct CommonCodeLensParams { - std::vector *result; + std::vector *result; DB *db; WorkingFile *wfile; }; @@ -90,7 +90,7 @@ struct CommonCodeLensParams { void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, ReplyOnce &reply) { - std::vector result; + std::vector result; std::string path = param.textDocument.uri.GetPath(); QueryFile *file = FindFile(reply, path); @@ -107,9 +107,9 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, std::optional ls_range = GetLsRange(wfile, range); if (!ls_range) return; - lsCodeLens &code_lens = result.emplace_back(); + CodeLens &code_lens = result.emplace_back(); code_lens.range = *ls_range; - code_lens.command = lsCommand(); + code_lens.command = Command(); code_lens.command->command = std::string(ccls_xref); bool plural = num > 1 && singular[strlen(singular) - 1] != 'd'; code_lens.command->title = @@ -122,49 +122,49 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, if (refcnt <= 0 || !sym.extent.Valid() || !seen.insert(sym.range).second) continue; switch (sym.kind) { - case SymbolKind::Func: { + case Kind::Func: { QueryFunc &func = db->GetFunc(sym); const QueryFunc::Def *def = func.AnyDef(); if (!def) continue; std::vector base_uses = GetUsesForAllBases(db, func); std::vector derived_uses = GetUsesForAllDerived(db, func); - Add("ref", {sym.usr, SymbolKind::Func, "uses"}, sym.range, - func.uses.size(), base_uses.empty()); + Add("ref", {sym.usr, Kind::Func, "uses"}, sym.range, func.uses.size(), + base_uses.empty()); if (base_uses.size()) - Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, sym.range, + Add("b.ref", {sym.usr, Kind::Func, "bases uses"}, sym.range, base_uses.size()); if (derived_uses.size()) - Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, sym.range, + Add("d.ref", {sym.usr, Kind::Func, "derived uses"}, sym.range, derived_uses.size()); if (base_uses.empty()) - Add("base", {sym.usr, SymbolKind::Func, "bases"}, sym.range, + Add("base", {sym.usr, Kind::Func, "bases"}, sym.range, def->bases.size()); - Add("derived", {sym.usr, SymbolKind::Func, "derived"}, sym.range, + Add("derived", {sym.usr, Kind::Func, "derived"}, sym.range, func.derived.size()); break; } - case SymbolKind::Type: { + case Kind::Type: { QueryType &type = db->GetType(sym); - Add("ref", {sym.usr, SymbolKind::Type, "uses"}, sym.range, - type.uses.size(), true); - Add("derived", {sym.usr, SymbolKind::Type, "derived"}, sym.range, + Add("ref", {sym.usr, Kind::Type, "uses"}, sym.range, type.uses.size(), + true); + Add("derived", {sym.usr, Kind::Type, "derived"}, sym.range, type.derived.size()); - Add("var", {sym.usr, SymbolKind::Type, "instances"}, sym.range, + Add("var", {sym.usr, Kind::Type, "instances"}, sym.range, type.instances.size()); break; } - case SymbolKind::Var: { + case Kind::Var: { QueryVar &var = db->GetVar(sym); const QueryVar::Def *def = var.AnyDef(); if (!def || (def->is_local() && !g_config->codeLens.localVariables)) continue; - Add("ref", {sym.usr, SymbolKind::Var, "uses"}, sym.range, var.uses.size(), - def->kind != lsSymbolKind::Macro); + Add("ref", {sym.usr, Kind::Var, "uses"}, sym.range, var.uses.size(), + def->kind != SymbolKind::Macro); break; } - case SymbolKind::File: - case SymbolKind::Invalid: + case Kind::File: + case Kind::Invalid: llvm_unreachable(""); }; } @@ -174,7 +174,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, void MessageHandler::workspace_executeCommand(Reader &reader, ReplyOnce &reply) { - lsCommand param; + Command param; Reflect(reader, param); if (param.arguments.empty()) { return; @@ -185,14 +185,14 @@ void MessageHandler::workspace_executeCommand(Reader &reader, if (param.command == ccls_xref) { Cmd_xref cmd; Reflect(json_reader, cmd); - std::vector result; + std::vector result; auto Map = [&](auto &&uses) { for (auto &use : uses) if (auto loc = GetLsLocation(db, wfiles, use)) result.push_back(std::move(*loc)); }; switch (cmd.kind) { - case SymbolKind::Func: { + case Kind::Func: { QueryFunc &func = db->Func(cmd.usr); if (cmd.field == "bases") { if (auto *def = func.AnyDef()) @@ -208,7 +208,7 @@ void MessageHandler::workspace_executeCommand(Reader &reader, } break; } - case SymbolKind::Type: { + case Kind::Type: { QueryType &type = db->Type(cmd.usr); if (cmd.field == "derived") { Map(GetTypeDeclarations(db, type.derived)); @@ -219,7 +219,7 @@ void MessageHandler::workspace_executeCommand(Reader &reader, } break; } - case SymbolKind::Var: { + case Kind::Var: { QueryVar &var = db->Var(cmd.usr); if (cmd.field == "uses") Map(var.uses); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 227efa36f..481c8dfce 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -30,21 +30,21 @@ namespace ccls { using namespace clang; using namespace llvm; -struct lsCompletionList { - bool isIncomplete = false; - std::vector items; -}; - -MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat); -MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind); -MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation, +MAKE_REFLECT_TYPE_PROXY(InsertTextFormat); +MAKE_REFLECT_TYPE_PROXY(CompletionItemKind); +MAKE_REFLECT_STRUCT(CompletionItem, label, kind, detail, documentation, sortText, filterText, insertText, insertTextFormat, textEdit, additionalTextEdits); -MAKE_REFLECT_STRUCT(lsCompletionList, isIncomplete, items); namespace { +struct CompletionList { + bool isIncomplete = false; + std::vector items; +}; +MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items); + void DecorateIncludePaths(const std::smatch &match, - std::vector *items) { + std::vector *items) { std::string spaces_after_include = " "; if (match[3].compare("include") == 0 && match[5].length()) spaces_after_include = match[4].str(); @@ -53,7 +53,7 @@ void DecorateIncludePaths(const std::smatch &match, match[1].str() + '#' + match[2].str() + "include" + spaces_after_include; std::string suffix = match[7].str(); - for (lsCompletionItem &item : *items) { + for (CompletionItem &item : *items) { char quote0, quote1; if (match[5].compare("<") == 0 || (match[5].length() == 0 && item.use_angle_brackets_)) @@ -94,9 +94,9 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) { // Pre-filters completion responses before sending to vscode. This results in a // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. -void FilterCandidates(lsCompletionList &result, - const std::string &complete_text, lsPosition begin_pos, - lsPosition end_pos, const std::string &buffer_line) { +void FilterCandidates(CompletionList &result, const std::string &complete_text, + lsPosition begin_pos, lsPosition end_pos, + const std::string &buffer_line) { assert(begin_pos.line == end_pos.line); auto &items = result.items; @@ -167,12 +167,12 @@ void FilterCandidates(lsCompletionList &result, : FuzzyMatcher::kMinScore; } items.erase(std::remove_if(items.begin(), items.end(), - [](const lsCompletionItem &item) { + [](const CompletionItem &item) { return item.score_ <= FuzzyMatcher::kMinScore; }), items.end()); std::sort(items.begin(), items.end(), - [](const lsCompletionItem &lhs, const lsCompletionItem &rhs) { + [](const CompletionItem &lhs, const CompletionItem &rhs) { int t = int(lhs.additionalTextEdits.size() - rhs.additionalTextEdits.size()); if (t) @@ -190,45 +190,45 @@ void FilterCandidates(lsCompletionList &result, finalize(); } -lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { +CompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { case CXCursor_UnexposedDecl: - return lsCompletionItemKind::Text; + return CompletionItemKind::Text; case CXCursor_StructDecl: case CXCursor_UnionDecl: - return lsCompletionItemKind::Struct; + return CompletionItemKind::Struct; case CXCursor_ClassDecl: - return lsCompletionItemKind::Class; + return CompletionItemKind::Class; case CXCursor_EnumDecl: - return lsCompletionItemKind::Enum; + return CompletionItemKind::Enum; case CXCursor_FieldDecl: - return lsCompletionItemKind::Field; + return CompletionItemKind::Field; case CXCursor_EnumConstantDecl: - return lsCompletionItemKind::EnumMember; + return CompletionItemKind::EnumMember; case CXCursor_FunctionDecl: - return lsCompletionItemKind::Function; + return CompletionItemKind::Function; case CXCursor_VarDecl: case CXCursor_ParmDecl: - return lsCompletionItemKind::Variable; + return CompletionItemKind::Variable; case CXCursor_ObjCInterfaceDecl: - return lsCompletionItemKind::Interface; + return CompletionItemKind::Interface; case CXCursor_ObjCInstanceMethodDecl: case CXCursor_CXXMethod: case CXCursor_ObjCClassMethodDecl: - return lsCompletionItemKind::Method; + return CompletionItemKind::Method; case CXCursor_FunctionTemplate: - return lsCompletionItemKind::Function; + return CompletionItemKind::Function; case CXCursor_Constructor: case CXCursor_Destructor: case CXCursor_ConversionFunction: - return lsCompletionItemKind::Constructor; + return CompletionItemKind::Constructor; case CXCursor_ObjCIvarDecl: - return lsCompletionItemKind::Variable; + return CompletionItemKind::Variable; case CXCursor_ClassTemplate: case CXCursor_ClassTemplatePartialSpecialization: @@ -240,50 +240,43 @@ lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { case CXCursor_ObjCProtocolDecl: case CXCursor_ObjCImplementationDecl: case CXCursor_ObjCCategoryImplDecl: - return lsCompletionItemKind::Class; + return CompletionItemKind::Class; case CXCursor_ObjCPropertyDecl: - return lsCompletionItemKind::Property; + return CompletionItemKind::Property; case CXCursor_MacroInstantiation: case CXCursor_MacroDefinition: - return lsCompletionItemKind::Interface; + return CompletionItemKind::Interface; case CXCursor_Namespace: case CXCursor_NamespaceAlias: case CXCursor_NamespaceRef: - return lsCompletionItemKind::Module; + return CompletionItemKind::Module; case CXCursor_MemberRef: case CXCursor_TypeRef: case CXCursor_ObjCSuperClassRef: case CXCursor_ObjCProtocolRef: case CXCursor_ObjCClassRef: - return lsCompletionItemKind::Reference; - - // return lsCompletionItemKind::Unit; - // return lsCompletionItemKind::Value; - // return lsCompletionItemKind::Keyword; - // return lsCompletionItemKind::Snippet; - // return lsCompletionItemKind::Color; - // return lsCompletionItemKind::File; + return CompletionItemKind::Reference; case CXCursor_NotImplemented: case CXCursor_OverloadCandidate: - return lsCompletionItemKind::Text; + return CompletionItemKind::Text; case CXCursor_TemplateTypeParameter: case CXCursor_TemplateTemplateParameter: - return lsCompletionItemKind::TypeParameter; + return CompletionItemKind::TypeParameter; default: LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; - return lsCompletionItemKind::Text; + return CompletionItemKind::Text; } } void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS, - std::vector &out) { + std::vector &out) { assert(!out.empty()); auto first = out.size() - 1; bool ignore = false; @@ -342,7 +335,7 @@ void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS, } out[i].textEdit.newText += "${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; - out[i].insertTextFormat = lsInsertTextFormat::Snippet; + out[i].insertTextFormat = InsertTextFormat::Snippet; } else if (Kind != CodeCompletionString::CK_Informative) { out[i].textEdit.newText += text; } @@ -364,7 +357,7 @@ class CompletionConsumer : public CodeCompleteConsumer { public: bool from_cache; - std::vector ls_items; + std::vector ls_items; CompletionConsumer(const CodeCompleteOptions &Opts, bool from_cache) : CodeCompleteConsumer(Opts, false), @@ -396,7 +389,7 @@ class CompletionConsumer : public CodeCompleteConsumer { CodeCompletionString *CCS = R.CreateCodeCompletionString( S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); - lsCompletionItem ls_item; + CompletionItem ls_item; ls_item.kind = GetCompletionKind(R.CursorKind); if (const char *brief = CCS->getBriefComment()) ls_item.documentation = brief; @@ -408,7 +401,7 @@ class CompletionConsumer : public CodeCompleteConsumer { for (size_t j = first_idx; j < ls_items.size(); j++) { if (g_config->client.snippetSupport && - ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet) + ls_items[j].insertTextFormat == InsertTextFormat::Snippet) ls_items[j].textEdit.newText += "$0"; ls_items[j].priority_ = CCS->getPriority(); if (!g_config->completion.detailedLabel) { @@ -419,7 +412,7 @@ class CompletionConsumer : public CodeCompleteConsumer { #if LLVM_VERSION_MAJOR >= 7 for (const FixItHint &FixIt : R.FixIts) { auto &AST = S.getASTContext(); - lsTextEdit ls_edit = + TextEdit ls_edit = ccls::ToTextEdit(AST.getSourceManager(), AST.getLangOpts(), FixIt); for (size_t j = first_idx; j < ls_items.size(); j++) ls_items[j].additionalTextEdits.push_back(ls_edit); @@ -433,10 +426,10 @@ class CompletionConsumer : public CodeCompleteConsumer { }; } // namespace -void MessageHandler::textDocument_completion(lsCompletionParams ¶m, +void MessageHandler::textDocument_completion(CompletionParam ¶m, ReplyOnce &reply) { - static CompleteConsumerCache> cache; - lsCompletionList result; + static CompleteConsumerCache> cache; + CompletionList result; std::string path = param.textDocument.uri.GetPath(); WorkingFile *file = wfiles->GetFileByFilename(path); if (!file) { @@ -452,7 +445,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams ¶m, // Check for - and : before completing -> or ::, since vscode does not // support multi-character trigger characters. - if (param.context.triggerKind == lsCompletionTriggerKind::TriggerCharacter && + if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter && param.context.triggerCharacter) { bool did_fail_check = false; @@ -496,7 +489,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams ¶m, ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); if (preprocess.ok && preprocess.keyword.compare("include") == 0) { - lsCompletionList result; + CompletionList result; { std::unique_lock lock( include_complete->completion_items_mutex, std::defer_lock); @@ -521,7 +514,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams ¶m, if (!OptConsumer) return; auto *Consumer = static_cast(OptConsumer); - lsCompletionList result; + CompletionList result; result.items = Consumer->ls_items; FilterCandidates(result, completion_text, begin_pos, end_pos, diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 00834fc30..df212ba5c 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -24,14 +24,14 @@ namespace ccls { namespace { std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { switch (sym.kind) { - case SymbolKind::Var: { + case Kind::Var: { std::vector ret = GetNonDefDeclarations(db, sym); // If there is no declaration, jump to its type. if (ret.empty()) { for (auto &def : db->GetVar(sym).def) if (def.type) { - if (Maybe use = GetDefinitionSpell( - db, SymbolIdx{def.type, SymbolKind::Type})) { + if (Maybe use = + GetDefinitionSpell(db, SymbolIdx{def.type, Kind::Type})) { ret.push_back(*use); break; } @@ -52,7 +52,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, if (!file) return; - std::vector result; + std::vector result; Maybe on_def; WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); lsPosition &ls_pos = param.position; @@ -100,7 +100,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { result.push_back( - lsLocation{lsDocumentUri::FromPath(include.resolved_path)}); + Location{DocumentUri::FromPath(include.resolved_path)}); range = {{0, 0}, {0, 0}}; break; } @@ -122,7 +122,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, // not in the same file, line distance> to find the best match. std::tuple best_score{INT_MAX, 0, true, 0}; SymbolIdx best_sym; - best_sym.kind = SymbolKind::Invalid; + best_sym.kind = Kind::Invalid; auto fn = [&](SymbolIdx sym) { std::string_view short_name = db->GetSymbolName(sym, false), name = short_query.size() < query.size() @@ -148,14 +148,14 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, } }; for (auto &func : db->funcs) - fn({func.usr, SymbolKind::Func}); + fn({func.usr, Kind::Func}); for (auto &type : db->types) - fn({type.usr, SymbolKind::Type}); + fn({type.usr, Kind::Type}); for (auto &var : db->vars) if (var.def.size() && !var.def[0].is_local()) - fn({var.usr, SymbolKind::Var}); + fn({var.usr, Kind::Var}); - if (best_sym.kind != SymbolKind::Invalid) { + if (best_sym.kind != Kind::Invalid) { Maybe dr = GetDefinitionSpell(db, best_sym); assert(dr); if (auto loc = GetLsLocation(db, wfiles, *dr)) @@ -174,7 +174,7 @@ void MessageHandler::textDocument_typeDefinition( return; WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); - std::vector result; + std::vector result; auto Add = [&](const QueryType &type) { for (const auto &def : type.def) if (def.spell) { @@ -189,13 +189,13 @@ void MessageHandler::textDocument_typeDefinition( for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, param.position)) { switch (sym.kind) { - case SymbolKind::Var: { + case Kind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); if (def && def->type) Add(db->Type(def->type)); break; } - case SymbolKind::Type: { + case Kind::Type: { for (auto &def : db->GetType(sym).def) if (def.alias_of) { Add(db->Type(def.alias_of)); diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 866599ebc..8b8599d94 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -22,7 +22,7 @@ limitations under the License. MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { -MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); +MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); namespace { struct DocumentHighlight { @@ -57,7 +57,7 @@ void MessageHandler::textDocument_documentHighlight( if (refcnt <= 0) continue; Usr usr = sym.usr; - SymbolKind kind = sym.kind; + Kind kind = sym.kind; if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) { return usr == sym1.usr && kind == sym1.kind; })) @@ -80,11 +80,11 @@ void MessageHandler::textDocument_documentHighlight( } namespace { -struct lsDocumentLink { +struct DocumentLink { lsRange range; - lsDocumentUri target; + DocumentUri target; }; -MAKE_REFLECT_STRUCT(lsDocumentLink, range, target); +MAKE_REFLECT_STRUCT(DocumentLink, range, target); } // namespace void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, @@ -93,10 +93,10 @@ void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, if (!file) return; - std::vector result; + std::vector result; for (const IndexInclude &include : file->def->includes) result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}}, - lsDocumentUri::FromPath(include.resolved_path)}); + DocumentUri::FromPath(include.resolved_path)}); reply(result); } // namespace ccls @@ -110,18 +110,18 @@ struct DocumentSymbolParam : TextDocumentParam { }; MAKE_REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine); -struct lsDocumentSymbol { +struct DocumentSymbol { std::string name; std::string detail; - lsSymbolKind kind; + SymbolKind kind; lsRange range; lsRange selectionRange; - std::vector> children; + std::vector> children; }; -void Reflect(Writer &vis, std::unique_ptr &v); -MAKE_REFLECT_STRUCT(lsDocumentSymbol, name, detail, kind, range, selectionRange, +void Reflect(Writer &vis, std::unique_ptr &v); +MAKE_REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange, children); -void Reflect(Writer &vis, std::unique_ptr &v) { +void Reflect(Writer &vis, std::unique_ptr &v) { Reflect(vis, *v); } @@ -131,7 +131,7 @@ bool Ignore(const Def *def) { } template <> bool Ignore(const QueryType::Def *def) { - return !def || def->kind == lsSymbolKind::TypeParameter; + return !def || def->kind == SymbolKind::TypeParameter; } template<> bool Ignore(const QueryVar::Def *def) { @@ -163,8 +163,8 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, std::sort(result.begin(), result.end()); reply(result); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { - std::unordered_map> sym2ds; - std::vector, lsDocumentSymbol *>> funcs, + std::unordered_map> sym2ds; + std::vector, DocumentSymbol *>> funcs, types; for (auto [sym, refcnt] : file->symbol2refcnt) { if (refcnt <= 0 || !sym.extent.Valid()) @@ -173,7 +173,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, if (!r.second) continue; auto &ds = r.first->second; - ds = std::make_unique(); + ds = std::make_unique(); std::vector def_ptrs; WithEntity(db, sym, [&, sym = sym](const auto &entity) { auto *def = entity.AnyDef(); @@ -192,25 +192,25 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, for (auto &def : entity.def) if (def.file_id == file_id && !Ignore(&def)) { ds->kind = def.kind; - if (def.spell || def.kind == lsSymbolKind::Namespace) + if (def.spell || def.kind == SymbolKind::Namespace) def_ptrs.push_back(&def); } }); if (def_ptrs.empty() || !(param.all || sym.role & Role::Definition || - ds->kind == lsSymbolKind::Namespace)) { + ds->kind == SymbolKind::Namespace)) { ds.reset(); continue; } - if (sym.kind == SymbolKind::Func) + if (sym.kind == Kind::Func) funcs.emplace_back(std::move(def_ptrs), ds.get()); - else if (sym.kind == SymbolKind::Type) + else if (sym.kind == Kind::Type) types.emplace_back(std::move(def_ptrs), ds.get()); } for (auto &[def_ptrs, ds] : funcs) for (const void *def_ptr : def_ptrs) for (Usr usr1 : ((const QueryFunc::Def *)def_ptr)->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + auto it = sym2ds.find(SymbolIdx{usr1, Kind::Var}); if (it != sym2ds.end() && it->second) ds->children.push_back(std::move(it->second)); } @@ -218,37 +218,36 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, for (const void *def_ptr : def_ptrs) { auto *def = (const QueryType::Def *)def_ptr; for (Usr usr1 : def->funcs) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func}); + auto it = sym2ds.find(SymbolIdx{usr1, Kind::Func}); if (it != sym2ds.end() && it->second) ds->children.push_back(std::move(it->second)); } for (Usr usr1 : def->types) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type}); + auto it = sym2ds.find(SymbolIdx{usr1, Kind::Type}); if (it != sym2ds.end() && it->second) ds->children.push_back(std::move(it->second)); } for (auto [usr1, _] : def->vars) { - auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var}); + auto it = sym2ds.find(SymbolIdx{usr1, Kind::Var}); if (it != sym2ds.end() && it->second) ds->children.push_back(std::move(it->second)); } } - std::vector> result; + std::vector> result; for (auto &[_, ds] : sym2ds) if (ds) result.push_back(std::move(ds)); reply(result); } else { - std::vector result; + std::vector result; for (auto [sym, refcnt] : file->symbol2refcnt) { if (refcnt <= 0 || !sym.extent.Valid() || !(param.all || sym.role & Role::Definition)) continue; - if (std::optional info = + if (std::optional info = GetSymbolInfo(db, sym, false)) { - if ((sym.kind == SymbolKind::Type && - Ignore(db->GetType(sym).AnyDef())) || - (sym.kind == SymbolKind::Var && Ignore(db->GetVar(sym).AnyDef()))) + if ((sym.kind == Kind::Type && Ignore(db->GetType(sym).AnyDef())) || + (sym.kind == Kind::Var && Ignore(db->GetVar(sym).AnyDef()))) continue; if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) { info->location = *loc; diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index dd7e05481..24af7dd8a 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -42,7 +42,7 @@ void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && sym.extent.Valid() && - (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) && + (sym.kind == Kind::Func || sym.kind == Kind::Type) && (ls_range = GetLsRange(wfile, sym.extent))) { FoldingRange &fold = result.emplace_back(); fold.startLine = ls_range->start.line; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 343699051..211eac78e 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -41,9 +41,9 @@ FormatCode(std::string_view code, std::string_view file, tooling::Range Range) { File)); } -std::vector -ReplacementsToEdits(std::string_view code, const tooling::Replacements &Repls) { - std::vector ret; +std::vector ReplacementsToEdits(std::string_view code, + const tooling::Replacements &Repls) { + std::vector ret; int i = 0, line = 0, col = 0; auto move = [&](int p) { for (; i < p; i++) @@ -74,8 +74,8 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { auto result = ReplacementsToEdits(code, *ReplsOrErr); reply(result); } else { - lsResponseError err; - err.code = lsErrorCodes::UnknownErrorCode; + ResponseError err; + err.code = ErrorCode::UnknownErrorCode; err.message = llvm::toString(ReplsOrErr.takeError()); reply.Error(err); } diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 907de2e25..3fdce20a0 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -18,16 +18,16 @@ limitations under the License. namespace ccls { namespace { -struct lsMarkedString { +struct MarkedString { std::optional language; std::string value; }; struct Hover { - std::vector contents; + std::vector contents; std::optional range; }; -void Reflect(Writer &visitor, lsMarkedString &value) { +void Reflect(Writer &visitor, MarkedString &value) { // If there is a language, emit a `{language:string, value:string}` object. If // not, emit a string. if (value.language) { @@ -54,10 +54,10 @@ const char *LanguageIdentifier(LanguageId lang) { } // Returns the hover or detailed name for `sym`, if any. -std::pair, std::optional> +std::pair, std::optional> GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { const char *comments = nullptr; - std::optional ls_comments, hover; + std::optional ls_comments, hover; WithEntity(db, sym, [&](const auto &entity) { std::remove_reference_t *def = nullptr; for (auto &d : entity.def) { @@ -74,7 +74,7 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { comments = def->comments; } if (def) { - lsMarkedString m; + MarkedString m; m.language = LanguageIdentifier(lang); if (def->hover[0]) { m.value = def->hover; @@ -84,7 +84,7 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { hover = m; } if (comments) - ls_comments = lsMarkedString{std::nullopt, comments}; + ls_comments = MarkedString{std::nullopt, comments}; } }); return {hover, ls_comments}; diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index fca73c83f..d37e28b32 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -53,7 +53,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { for (auto &folder : param.folders) EnsureEndsInSlash(folder); std::vector file_set = db->GetFileSet(param.folders); - std::vector result; + std::vector result; std::unordered_set seen_uses; int line = param.position.line; @@ -63,12 +63,12 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { std::unordered_set seen; seen.insert(sym.usr); std::vector stack{sym.usr}; - if (sym.kind != SymbolKind::Func) + if (sym.kind != Kind::Func) param.base = false; while (stack.size()) { sym.usr = stack.back(); stack.pop_back(); - auto fn = [&](Use use, lsSymbolKind parent_kind) { + auto fn = [&](Use use, SymbolKind parent_kind) { if (file_set[use.file_id] && Role(use.role & param.role) == param.role && !(use.role & param.excludeRole) && seen_uses.insert(use).second) @@ -76,7 +76,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { result.push_back(*loc); }; WithEntity(db, sym, [&](const auto &entity) { - lsSymbolKind parent_kind = lsSymbolKind::Unknown; + SymbolKind parent_kind = SymbolKind::Unknown; for (auto &def : entity.def) if (def.spell) { parent_kind = GetSymbolKind(db, sym); @@ -120,8 +120,8 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { for (const IndexInclude &include : file1.def->includes) if (include.resolved_path == path) { // Another file |file1| has the same include line. - lsLocation &loc = result.emplace_back(); - loc.uri = lsDocumentUri::FromPath(file1.def->path); + Location &loc = result.emplace_back(); + loc.uri = DocumentUri::FromPath(file1.def->path); loc.range.start.line = loc.range.end.line = include.line; break; } diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 836847ddd..fb50c86c6 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -18,32 +18,32 @@ limitations under the License. namespace ccls { namespace { -lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, - const std::string &new_text) { - std::unordered_map path_to_edit; +WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, + const std::string &new_text) { + std::unordered_map path_to_edit; EachOccurrence(db, sym, true, [&](Use use) { - std::optional ls_location = GetLsLocation(db, wfiles, use); + std::optional ls_location = GetLsLocation(db, wfiles, use); if (!ls_location) return; int file_id = use.file_id; if (path_to_edit.find(file_id) == path_to_edit.end()) { - path_to_edit[file_id] = lsTextDocumentEdit(); + path_to_edit[file_id] = TextDocumentEdit(); QueryFile &file = db->files[file_id]; if (!file.def) return; const std::string &path = file.def->path; - path_to_edit[file_id].textDocument.uri = lsDocumentUri::FromPath(path); + path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path); WorkingFile *working_file = wfiles->GetFileByFilename(path); if (working_file) path_to_edit[file_id].textDocument.version = working_file->version; } - lsTextEdit edit; + TextEdit edit; edit.range = ls_location->range; edit.newText = new_text; @@ -53,7 +53,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, edits.push_back(edit); }); - lsWorkspaceEdit edit; + WorkspaceEdit edit; for (const auto &changes : path_to_edit) edit.documentChanges.push_back(changes.second); return edit; @@ -67,7 +67,7 @@ void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { return; WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - lsWorkspaceEdit result; + WorkspaceEdit result; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { result = BuildWorkspaceEdit(db, wfiles, sym, param.newName); break; diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 63bd4c832..1f27f28ed 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -31,14 +31,14 @@ struct SignatureInformation { std::optional documentation; std::vector parameters; }; -struct lsSignatureHelp { +struct SignatureHelp { std::vector signatures; int activeSignature = 0; int activeParameter = 0; }; MAKE_REFLECT_STRUCT(ParameterInformation, label); MAKE_REFLECT_STRUCT(SignatureInformation, label, documentation, parameters); -MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature, +MAKE_REFLECT_STRUCT(SignatureHelp, signatures, activeSignature, activeParameter); std::string BuildOptional(const CodeCompletionString &CCS, @@ -76,7 +76,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { CodeCompletionTUInfo CCTUInfo; public: bool from_cache; - lsSignatureHelp ls_sighelp; + SignatureHelp ls_sighelp; SignatureHelpConsumer(const clang::CodeCompleteOptions &CCOpts, bool from_cache) : CodeCompleteConsumer(CCOpts, false), @@ -152,7 +152,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { void MessageHandler::textDocument_signatureHelp( TextDocumentPositionParam ¶m, ReplyOnce &reply) { - static CompleteConsumerCache cache; + static CompleteConsumerCache cache; std::string path = param.textDocument.uri.GetPath(); lsPosition begin_pos = param.position; diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 695b2ab45..084433933 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -30,12 +30,12 @@ limitations under the License. #include namespace ccls { -MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); +MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { for (const std::string &folder : g_config->workspaceFolders) project->Load(folder); - project->Index(wfiles, lsRequestId()); + project->Index(wfiles, RequestId()); clang_complete->FlushAllSessions(); }; @@ -89,7 +89,7 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( project->Load(root); } - project->Index(wfiles, lsRequestId()); + project->Index(wfiles, RequestId()); clang_complete->FlushAllSessions(); } @@ -99,8 +99,8 @@ namespace { bool AddSymbol( DB *db, WorkingFiles *wfiles, const std::vector &file_set, SymbolIdx sym, bool use_detailed, - std::vector> *result) { - std::optional info = GetSymbolInfo(db, sym, true); + std::vector> *result) { + std::optional info = GetSymbolInfo(db, sym, true); if (!info) return false; @@ -125,7 +125,7 @@ bool AddSymbol( if (!in_folder) return false; - std::optional ls_location = GetLsLocation(db, wfiles, *dr); + std::optional ls_location = GetLsLocation(db, wfiles, *dr); if (!ls_location) return false; info->location = *ls_location; @@ -136,14 +136,14 @@ bool AddSymbol( void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, ReplyOnce &reply) { - std::vector result; + std::vector result; const std::string &query = param.query; for (auto &folder : param.folders) EnsureEndsInSlash(folder); std::vector file_set = db->GetFileSet(param.folders); // {symbol info, matching detailed_name or short_name, index} - std::vector> cands; + std::vector> cands; bool sensitive = g_config->workspaceSymbol.caseSensitivity; // Find subsequence matches. @@ -163,14 +163,13 @@ void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, cands.size() >= g_config->workspaceSymbol.maxNum; }; for (auto &func : db->funcs) - if (Add({func.usr, SymbolKind::Func})) + if (Add({func.usr, Kind::Func})) goto done_add; for (auto &type : db->types) - if (Add({type.usr, SymbolKind::Type})) + if (Add({type.usr, Kind::Type})) goto done_add; for (auto &var : db->vars) - if (var.def.size() && !var.def[0].is_local() && - Add({var.usr, SymbolKind::Var})) + if (var.def.size() && !var.def[0].is_local() && Add({var.usr, Kind::Var})) goto done_add; done_add: diff --git a/src/pipeline.cc b/src/pipeline.cc index f3e16906e..5baab1c06 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -45,6 +45,14 @@ using namespace llvm; #endif namespace ccls { +namespace { +struct PublishDiagnosticParam { + DocumentUri uri; + std::vector diagnostics; +}; +MAKE_REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics); +} // namespace + void VFS::Clear() { std::lock_guard lock(mutex); state.clear(); @@ -81,7 +89,7 @@ struct Index_Request { std::string path; std::vector args; IndexMode mode; - lsRequestId id; + RequestId id; int64_t ts = tick++; }; @@ -303,8 +311,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (!ok) { if (request.id.Valid()) { - lsResponseError err; - err.code = lsErrorCodes::InternalError; + ResponseError err; + err.code = ErrorCode::InternalError; err.message = "failed to index " + path_to_index; pipeline::ReplyError(request.id, err); } @@ -453,7 +461,7 @@ void LaunchStdin() { if (!reader.HasMember("jsonrpc") || std::string(reader["jsonrpc"]->GetString()) != "2.0") return; - lsRequestId id; + RequestId id; std::string method; ReflectMember(reader, "id", id); ReflectMember(reader, "method", method); @@ -491,16 +499,16 @@ void MainLoop() { CompletionManager clang_complete( &project, &wfiles, - [&](std::string path, std::vector diagnostics) { - lsPublishDiagnosticsParams params; - params.uri = lsDocumentUri::FromPath(path); + [&](std::string path, std::vector diagnostics) { + PublishDiagnosticParam params; + params.uri = DocumentUri::FromPath(path); params.diagnostics = diagnostics; Notify("textDocument/publishDiagnostics", params); }, - [](lsRequestId id) { + [](RequestId id) { if (id.Valid()) { - lsResponseError err; - err.code = lsErrorCodes::InternalError; + ResponseError err; + err.code = ErrorCode::InternalError; err.message = "drop older completion request"; ReplyError(id, err); } @@ -584,7 +592,7 @@ void Standalone(const std::string &root) { } void Index(const std::string &path, const std::vector &args, - IndexMode mode, lsRequestId id) { + IndexMode mode, RequestId id) { pending_index_requests++; index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); } @@ -615,7 +623,7 @@ void Notify(const char *method, const std::function &fn) { for_stdout->PushBack(output.GetString()); } -static void Reply(lsRequestId id, const char *key, +static void Reply(RequestId id, const char *key, const std::function &fn) { rapidjson::StringBuffer output; rapidjson::Writer w(output); @@ -624,13 +632,13 @@ static void Reply(lsRequestId id, const char *key, w.String("2.0"); w.Key("id"); switch (id.type) { - case lsRequestId::kNone: + case RequestId::kNone: w.Null(); break; - case lsRequestId::kInt: + case RequestId::kInt: w.Int(id.value); break; - case lsRequestId::kString: + case RequestId::kString: auto s = std::to_string(id.value); w.String(s.c_str(), s.length()); break; @@ -642,11 +650,11 @@ static void Reply(lsRequestId id, const char *key, for_stdout->PushBack(output.GetString()); } -void Reply(lsRequestId id, const std::function &fn) { +void Reply(RequestId id, const std::function &fn) { Reply(id, "result", fn); } -void ReplyError(lsRequestId id, const std::function &fn) { +void ReplyError(RequestId id, const std::function &fn) { Reply(id, "error", fn); } } // namespace pipeline diff --git a/src/pipeline.hh b/src/pipeline.hh index 494f87076..93b51d1d3 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -47,7 +47,7 @@ void MainLoop(); void Standalone(const std::string &root); void Index(const std::string &path, const std::vector &args, - IndexMode mode, lsRequestId id = {}); + IndexMode mode, RequestId id = {}); std::optional LoadIndexedContent(const std::string& path); @@ -56,10 +56,10 @@ template void Notify(const char *method, T &result) { Notify(method, [&](Writer &w) { Reflect(w, result); }); } -void Reply(lsRequestId id, const std::function &fn); +void Reply(RequestId id, const std::function &fn); -void ReplyError(lsRequestId id, const std::function &fn); -template void ReplyError(lsRequestId id, T &result) { +void ReplyError(RequestId id, const std::function &fn); +template void ReplyError(RequestId id, T &result) { ReplyError(id, [&](Writer &w) { Reflect(w, result); }); } } // namespace pipeline diff --git a/src/project.cc b/src/project.cc index 42b8959e6..ec48e16dd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -463,7 +463,7 @@ Project::Entry Project::FindEntry(const std::string &path, return result; } -void Project::Index(WorkingFiles *wfiles, lsRequestId id) { +void Project::Index(WorkingFiles *wfiles, RequestId id) { auto &gi = g_config->index; GroupMatch match(gi.whitelist, gi.blacklist), match_i(gi.initialWhitelist, gi.initialBlacklist); diff --git a/src/project.hh b/src/project.hh index b5018525b..a95951225 100644 --- a/src/project.hh +++ b/src/project.hh @@ -75,6 +75,6 @@ struct Project { void SetArgsForFile(const std::vector &args, const std::string &path); - void Index(WorkingFiles *wfiles, lsRequestId id); + void Index(WorkingFiles *wfiles, RequestId id); }; } // namespace ccls diff --git a/src/query.cc b/src/query.cc index 1d1345808..00b32cecc 100644 --- a/src/query.cc +++ b/src/query.cc @@ -158,10 +158,10 @@ void DB::clear() { } template -void DB::RemoveUsrs(SymbolKind kind, int file_id, +void DB::RemoveUsrs(Kind kind, int file_id, const std::vector> &to_remove) { switch (kind) { - case SymbolKind::Func: { + case Kind::Func: { for (auto &[usr, _] : to_remove) { // FIXME if (!HasFunc(usr)) @@ -175,7 +175,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id, } break; } - case SymbolKind::Type: { + case Kind::Type: { for (auto &[usr, _] : to_remove) { // FIXME if (!HasType(usr)) @@ -189,7 +189,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id, } break; } - case SymbolKind::Var: { + case Kind::Var: { for (auto &[usr, _] : to_remove) { // FIXME if (!HasVar(usr)) @@ -232,8 +232,8 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { } // References (Use &use) in this function are important to update file_id. - auto Ref = [&](std::unordered_map &lid2fid, Usr usr, - SymbolKind kind, Use &use, int delta) { + auto Ref = [&](std::unordered_map &lid2fid, Usr usr, Kind kind, + Use &use, int delta) { use.file_id = use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; ExtentRef sym{{use.range, usr, kind, use.role}}; @@ -243,8 +243,8 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { if (!v) files[use.file_id].symbol2refcnt.erase(sym); }; - auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, - SymbolKind kind, DeclRef &dr, int delta) { + auto RefDecl = [&](std::unordered_map &lid2fid, Usr usr, Kind kind, + DeclRef &dr, int delta) { dr.file_id = dr.file_id == -1 ? u->file_id : lid2fid.find(dr.file_id)->second; ExtentRef sym{{dr.range, usr, kind, dr.role}, dr.extent}; @@ -256,7 +256,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { }; auto UpdateUses = - [&](Usr usr, SymbolKind kind, + [&](Usr usr, Kind kind, llvm::DenseMap &entity_usr, auto &entities, auto &p, bool hint_implicit) { auto R = entity_usr.try_emplace(usr, entity_usr.size()); @@ -303,19 +303,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { } for (auto &[usr, def] : u->funcs_removed) if (def.spell) - RefDecl(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); - RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); + RefDecl(prev_lid2file_id, usr, Kind::Func, *def.spell, -1); + RemoveUsrs(Kind::Func, u->file_id, u->funcs_removed); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); for (auto &[usr, del_add]: u->funcs_declarations) { for (DeclRef &dr : del_add.first) - RefDecl(prev_lid2file_id, usr, SymbolKind::Func, dr, -1); + RefDecl(prev_lid2file_id, usr, Kind::Func, dr, -1); for (DeclRef &dr : del_add.second) - RefDecl(lid2file_id, usr, SymbolKind::Func, dr, 1); + RefDecl(lid2file_id, usr, Kind::Func, dr, 1); } REMOVE_ADD(func, declarations); REMOVE_ADD(func, derived); for (auto &[usr, p] : u->funcs_uses) - UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p, true); + UpdateUses(usr, Kind::Func, func_usr, funcs, p, true); if ((t = types.size() + u->types_hint) > types.capacity()) { t = size_t(t * grow); @@ -324,20 +324,20 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { } for (auto &[usr, def] : u->types_removed) if (def.spell) - RefDecl(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); - RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); + RefDecl(prev_lid2file_id, usr, Kind::Type, *def.spell, -1); + RemoveUsrs(Kind::Type, u->file_id, u->types_removed); Update(lid2file_id, u->file_id, std::move(u->types_def_update)); for (auto &[usr, del_add]: u->types_declarations) { for (DeclRef &dr : del_add.first) - RefDecl(prev_lid2file_id, usr, SymbolKind::Type, dr, -1); + RefDecl(prev_lid2file_id, usr, Kind::Type, dr, -1); for (DeclRef &dr : del_add.second) - RefDecl(lid2file_id, usr, SymbolKind::Type, dr, 1); + RefDecl(lid2file_id, usr, Kind::Type, dr, 1); } REMOVE_ADD(type, declarations); REMOVE_ADD(type, derived); REMOVE_ADD(type, instances); for (auto &[usr, p] : u->types_uses) - UpdateUses(usr, SymbolKind::Type, type_usr, types, p, false); + UpdateUses(usr, Kind::Type, type_usr, types, p, false); if ((t = vars.size() + u->vars_hint) > vars.capacity()) { t = size_t(t * grow); @@ -346,18 +346,18 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { } for (auto &[usr, def] : u->vars_removed) if (def.spell) - RefDecl(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); - RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); + RefDecl(prev_lid2file_id, usr, Kind::Var, *def.spell, -1); + RemoveUsrs(Kind::Var, u->file_id, u->vars_removed); Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); for (auto &[usr, del_add]: u->vars_declarations) { for (DeclRef &dr : del_add.first) - RefDecl(prev_lid2file_id, usr, SymbolKind::Var, dr, -1); + RefDecl(prev_lid2file_id, usr, Kind::Var, dr, -1); for (DeclRef &dr : del_add.second) - RefDecl(lid2file_id, usr, SymbolKind::Var, dr, 1); + RefDecl(lid2file_id, usr, Kind::Var, dr, 1); } REMOVE_ADD(var, declarations); for (auto &[usr, p] : u->vars_uses) - UpdateUses(usr, SymbolKind::Var, var_usr, vars, p, false); + UpdateUses(usr, Kind::Var, var_usr, vars, p, false); #undef REMOVE_ADD } @@ -386,7 +386,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Func, def.spell->role}, + {def.spell->range, u.first, Kind::Func, def.spell->role}, def.spell->extent}]++; } @@ -409,7 +409,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Type, def.spell->role}, + {def.spell->range, u.first, Kind::Type, def.spell->role}, def.spell->extent}]++; } auto R = type_usr.try_emplace({u.first}, type_usr.size()); @@ -431,7 +431,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, if (def.spell) { AssignFileId(lid2file_id, file_id, *def.spell); files[def.spell->file_id].symbol2refcnt[{ - {def.spell->range, u.first, SymbolKind::Var, def.spell->role}, + {def.spell->range, u.first, Kind::Var, def.spell->role}, def.spell->extent}]++; } auto R = var_usr.try_emplace({u.first}, var_usr.size()); @@ -449,19 +449,19 @@ std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) { switch (sym.kind) { default: break; - case SymbolKind::File: + case Kind::File: if (files[usr].def) return files[usr].def->path; break; - case SymbolKind::Func: + case Kind::Func: if (const auto *def = Func(usr).AnyDef()) return def->Name(qualified); break; - case SymbolKind::Type: + case Kind::Type: if (const auto *def = Type(usr).AnyDef()) return def->Name(qualified); break; - case SymbolKind::Var: + case Kind::Var: if (const auto *def = Var(usr).AnyDef()) return def->Name(qualified); break; diff --git a/src/query.hh b/src/query.hh index 9cf093645..33cb5a663 100644 --- a/src/query.hh +++ b/src/query.hh @@ -168,7 +168,7 @@ struct DB { void clear(); template - void RemoveUsrs(SymbolKind kind, int file_id, + void RemoveUsrs(Kind kind, int file_id, const std::vector> &to_remove); // Insert the contents of |update| into |db|. void ApplyIndexUpdate(IndexUpdate *update); diff --git a/src/query_utils.cc b/src/query_utils.cc index 24d39040f..9bda5df2e 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -76,13 +76,13 @@ std::vector GetVarDeclarations(DB *db, const std::vector &usrs, if (def.spell) { has_def = true; // See messages/ccls_vars.cc - if (def.kind == lsSymbolKind::Field) { + if (def.kind == SymbolKind::Field) { if (!(kind & 1)) break; - } else if (def.kind == lsSymbolKind::Variable) { + } else if (def.kind == SymbolKind::Variable) { if (!(kind & 2)) break; - } else if (def.kind == lsSymbolKind::Parameter) { + } else if (def.kind == SymbolKind::Parameter) { if (!(kind & 4)) break; } @@ -98,11 +98,11 @@ std::vector GetVarDeclarations(DB *db, const std::vector &usrs, std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym) { static std::vector empty; switch (sym.kind) { - case SymbolKind::Func: + case Kind::Func: return db->GetFunc(sym).declarations; - case SymbolKind::Type: + case Kind::Type: return db->GetType(sym).declarations; - case SymbolKind::Var: + case Kind::Var: return db->GetVar(sym).declarations; default: break; @@ -181,45 +181,44 @@ std::optional GetLsRange(WorkingFile *wfile, lsPosition{*end, end_column}}; } -lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { +DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { QueryFile &file = db->files[file_id]; if (file.def) { *path = file.def->path; - return lsDocumentUri::FromPath(*path); + return DocumentUri::FromPath(*path); } else { *path = ""; - return lsDocumentUri::FromPath(""); + return DocumentUri::FromPath(""); } } -lsDocumentUri GetLsDocumentUri(DB *db, int file_id) { +DocumentUri GetLsDocumentUri(DB *db, int file_id) { QueryFile &file = db->files[file_id]; if (file.def) { - return lsDocumentUri::FromPath(file.def->path); + return DocumentUri::FromPath(file.def->path); } else { - return lsDocumentUri::FromPath(""); + return DocumentUri::FromPath(""); } } -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, - Use use) { +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) { std::string path; - lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); + DocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); std::optional range = GetLsRange(wfiles->GetFileByFilename(path), use.range); if (!range) return std::nullopt; - return lsLocation{uri, *range}; + return Location{uri, *range}; } -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, - SymbolRef sym, int file_id) { +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, + SymbolRef sym, int file_id) { return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id}); } -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, - const std::vector &uses) { - std::vector ret; +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, + const std::vector &uses) { + std::vector ret; for (Use use : uses) if (auto loc = GetLsLocation(db, wfiles, use)) ret.push_back(*loc); @@ -230,12 +229,12 @@ std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, return ret; } -lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { - lsSymbolKind ret; - if (sym.kind == SymbolKind::File) - ret = lsSymbolKind::File; +SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { + SymbolKind ret; + if (sym.kind == Kind::File) + ret = SymbolKind::File; else { - ret = lsSymbolKind::Unknown; + ret = SymbolKind::Unknown; WithEntity(db, sym, [&](const auto &entity) { for (auto &def : entity.def) { ret = def.kind; @@ -246,23 +245,23 @@ lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { return ret; } -std::optional GetSymbolInfo(DB *db, SymbolIdx sym, - bool detailed) { +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, + bool detailed) { switch (sym.kind) { - case SymbolKind::Invalid: + case Kind::Invalid: break; - case SymbolKind::File: { + case Kind::File: { QueryFile &file = db->GetFile(sym); if (!file.def) break; - lsSymbolInformation info; + SymbolInformation info; info.name = file.def->path; - info.kind = lsSymbolKind::File; + info.kind = SymbolKind::File; return info; } default: { - lsSymbolInformation info; + SymbolInformation info; EachEntityDef(db, sym, [&](const auto &def) { if (detailed) info.name = def.detailed_name; @@ -302,10 +301,10 @@ std::vector FindSymbolsAtLocation(WorkingFile *wfile, // important for macros which generate code so that we can resolving the // macro argument takes priority over the entire macro body. // - // Order SymbolKind::Var before SymbolKind::Type. Macro calls are treated as - // Var currently. If a macro expands to tokens led by a SymbolKind::Type, the - // macro and the Type have the same range. We want to find the macro - // definition instead of the Type definition. + // Order Kind::Var before Kind::Type. Macro calls are treated as Var + // currently. If a macro expands to tokens led by a Kind::Type, the macro and + // the Type have the same range. We want to find the macro definition instead + // of the Type definition. // // Then order functions before other types, which makes goto definition work // better on constructors. diff --git a/src/query_utils.hh b/src/query_utils.hh index 0dd53fe37..c19000420 100644 --- a/src/query_utils.hh +++ b/src/query_utils.hh @@ -36,16 +36,16 @@ std::vector GetUsesForAllBases(DB *db, QueryFunc &root); std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); std::optional GetLsRange(WorkingFile *working_file, const Range &location); -lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); -lsDocumentUri GetLsDocumentUri(DB *db, int file_id); +DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); +DocumentUri GetLsDocumentUri(DB *db, int file_id); -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, SymbolRef sym, int file_id); -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, const std::vector &uses); // Returns a symbol. The symbol will *NOT* have a location assigned. -std::optional GetSymbolInfo(DB *db, SymbolIdx sym, +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, bool detailed); std::vector FindSymbolsAtLocation(WorkingFile *working_file, @@ -55,16 +55,16 @@ std::vector FindSymbolsAtLocation(WorkingFile *working_file, template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { switch (sym.kind) { - case SymbolKind::Invalid: - case SymbolKind::File: + case Kind::Invalid: + case Kind::File: break; - case SymbolKind::Func: + case Kind::Func: fn(db->GetFunc(sym)); break; - case SymbolKind::Type: + case Kind::Type: fn(db->GetType(sym)); break; - case SymbolKind::Var: + case Kind::Var: fn(db->GetVar(sym)); break; } @@ -93,7 +93,7 @@ void EachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) { }); } -lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym); +SymbolKind GetSymbolKind(DB *db, SymbolIdx sym); template void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { diff --git a/src/test.cc b/src/test.cc index d4229790c..44ebe7e1d 100644 --- a/src/test.cc +++ b/src/test.cc @@ -267,10 +267,10 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { bool success = true; bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment - // this can be done by constructing ClangIndex index(1, 1); - CompletionManager completion( - nullptr, nullptr, [&](std::string, std::vector) {}, - [](lsRequestId id) {}); + // this can be done by conRequestIdex index(1, 1); + CompletionManager completion(nullptr, nullptr, + [&](std::string, std::vector) {}, + [](RequestId id) {}); GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string &path) { diff --git a/src/working_files.cc b/src/working_files.cc index 8f7939350..aeec375d7 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -451,7 +451,7 @@ void WorkingFiles::DoActionOnFile( action(file); } -WorkingFile *WorkingFiles::OnOpen(const lsTextDocumentItem &open) { +WorkingFile *WorkingFiles::OnOpen(const TextDocumentItem &open) { std::lock_guard lock(files_mutex); std::string filename = open.uri.GetPath(); @@ -505,7 +505,7 @@ void WorkingFiles::OnChange(const TextDocumentDidChangeParam &change) { } } -void WorkingFiles::OnClose(const lsTextDocumentIdentifier &close) { +void WorkingFiles::OnClose(const TextDocumentIdentifier &close) { std::lock_guard lock(files_mutex); std::string filename = close.uri.GetPath(); diff --git a/src/working_files.hh b/src/working_files.hh index 0824eceed..31826dc2e 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -43,7 +43,7 @@ struct WorkingFile { // A set of diagnostics that have been reported for this file. // NOTE: _ is appended because it must be accessed under the WorkingFiles // lock! - std::vector diagnostics_; + std::vector diagnostics_; WorkingFile(const std::string &filename, const std::string &buffer_content); @@ -117,9 +117,9 @@ struct WorkingFiles { void DoActionOnFile(const std::string &filename, const std::function &action); - WorkingFile *OnOpen(const lsTextDocumentItem &open); + WorkingFile *OnOpen(const TextDocumentItem &open); void OnChange(const TextDocumentDidChangeParam &change); - void OnClose(const lsTextDocumentIdentifier &close); + void OnClose(const TextDocumentIdentifier &close); // If |filter_paths| is non-empty, only files which contain any of the given // strings. For example, {"foo", "bar"} means that every result has either the From e0e00cb48a0e74ebc5c4ea0d8179d7b86df373a7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 4 Nov 2018 10:30:18 -0800 Subject: [PATCH 284/378] Reduce MAKE_REFLECT_STRUCT in lsp.hh Position -> Pos; lsPosition -> Position --- src/clang_complete.cc | 8 +- src/clang_complete.hh | 8 +- src/clang_tu.cc | 4 +- src/indexer.hh | 28 ++++- src/lsp.cc | 6 +- src/lsp.hh | 116 ++------------------- src/match.cc | 2 +- src/message_handler.cc | 26 ++--- src/message_handler.hh | 56 ++++++---- src/messages/ccls_navigate.cc | 8 +- src/messages/textDocument_completion.cc | 8 +- src/messages/textDocument_definition.cc | 4 +- src/messages/textDocument_rename.cc | 7 +- src/messages/textDocument_signatureHelp.cc | 4 +- src/position.cc | 16 +-- src/position.hh | 22 ++-- src/query_utils.cc | 10 +- src/query_utils.hh | 2 +- src/serializer.cc | 1 + src/working_files.cc | 19 ++-- src/working_files.hh | 12 +-- 21 files changed, 147 insertions(+), 220 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 5fc53b7a7..ffaa286d8 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -508,17 +508,17 @@ void *DiagnosticMain(void *manager_) { case DiagnosticsEngine::Ignored: // llvm_unreachable case DiagnosticsEngine::Remark: - ret.severity = DiagnosticSeverity::Hint; + ret.severity = 4; break; case DiagnosticsEngine::Note: - ret.severity = DiagnosticSeverity::Information; + ret.severity = 3; break; case DiagnosticsEngine::Warning: - ret.severity = DiagnosticSeverity::Warning; + ret.severity = 2; break; case DiagnosticsEngine::Error: case DiagnosticsEngine::Fatal: - ret.severity = DiagnosticSeverity::Error; + ret.severity = 1; break; } ret.code = d.category; diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 153193cb1..e158aa0db 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -87,7 +87,7 @@ struct CompletionManager { struct CompletionRequest { CompletionRequest(const RequestId &id, const TextDocumentIdentifier &document, - const lsPosition &position, + const Position &position, std::unique_ptr Consumer, clang::CodeCompleteOptions CCOpts, const OnComplete &on_complete) @@ -97,7 +97,7 @@ struct CompletionManager { RequestId id; TextDocumentIdentifier document; - lsPosition position; + Position position; std::unique_ptr Consumer; clang::CodeCompleteOptions CCOpts; OnComplete on_complete; @@ -177,7 +177,7 @@ template struct CompleteConsumerCache { // NOTE: Make sure to access these variables under |WithLock|. std::optional path; - std::optional position; + std::optional position; T result; std::mutex mutex; @@ -186,7 +186,7 @@ struct CompleteConsumerCache { std::lock_guard lock(mutex); action(); } - bool IsCacheValid(const std::string path, lsPosition position) { + bool IsCacheValid(const std::string path, Position position) { std::lock_guard lock(mutex); return this->path == path && this->position == position; } diff --git a/src/clang_tu.cc b/src/clang_tu.cc index cc3437f6f..91fa2e389 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -41,8 +41,8 @@ std::string PathFromFileEntry(const FileEntry &file) { return ret; } -static Position Decomposed2LineAndCol(const SourceManager &SM, - std::pair I) { +static Pos Decomposed2LineAndCol(const SourceManager &SM, + std::pair I) { int l = SM.getLineNumber(I.first, I.second) - 1, c = SM.getColumnNumber(I.first, I.second) - 1; return {(int16_t)std::min(l, INT16_MAX), (int16_t)std::min(c, INT16_MAX)}; diff --git a/src/indexer.hh b/src/indexer.hh index 30b11ddb0..55bc1ffb0 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -43,7 +43,32 @@ template <> struct hash { namespace ccls { using Usr = uint64_t; -enum class LanguageId; + +// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in +// front of others. +enum class Kind : uint8_t { Invalid, File, Type, Func, Var }; +MAKE_REFLECT_TYPE_PROXY(Kind); + +enum class Role : uint16_t { + None = 0, + Declaration = 1 << 0, + Definition = 1 << 1, + Reference = 1 << 2, + Read = 1 << 3, + Write = 1 << 4, + Call = 1 << 5, + Dynamic = 1 << 6, + Address = 1 << 7, + Implicit = 1 << 8, + All = (1 << 9) - 1, +}; +MAKE_REFLECT_TYPE_PROXY(Role); +inline uint16_t operator&(Role lhs, Role rhs) { + return uint16_t(lhs) & uint16_t(rhs); +} +inline Role operator|(Role lhs, Role rhs) { + return Role(uint16_t(lhs) | uint16_t(rhs)); +} struct SymbolIdx { Usr usr; @@ -56,7 +81,6 @@ struct SymbolIdx { return usr != o.usr ? usr < o.usr : kind < o.kind; } }; -MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind); // |id,kind| refer to the referenced entity. struct SymbolRef { diff --git a/src/lsp.cc b/src/lsp.cc index 79f04d04f..9adc2f425 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -136,11 +136,7 @@ std::string DocumentUri::GetPath() const { return ret; } -std::string lsPosition::ToString() const { +std::string Position::ToString() const { return std::to_string(line) + ":" + std::to_string(character); } - -bool TextEdit::operator==(const TextEdit &that) { - return range == that.range && newText == that.newText; -} } // namespace ccls diff --git a/src/lsp.hh b/src/lsp.hh index 2e370c877..27c9727f1 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -60,7 +60,6 @@ enum class ErrorCode { // Defined by the protocol. RequestCancelled = -32800, }; -MAKE_REFLECT_TYPE_PROXY(ErrorCode); struct ResponseError { // A number indicating the error type that occurred. @@ -73,19 +72,10 @@ struct ResponseError { // information about the error. Can be omitted. // std::optional data; }; -MAKE_REFLECT_STRUCT(ResponseError, code, message); constexpr char ccls_xref[] = "ccls.xref"; constexpr char window_showMessage[] = "window/showMessage"; -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -////////////////////////////// PRIMITIVE TYPES ////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - struct DocumentUri { static DocumentUri FromPath(const std::string &path); @@ -102,22 +92,21 @@ void Reflect(TVisitor &visitor, DocumentUri &value) { Reflect(visitor, value.raw_uri); } -struct lsPosition { +struct Position { int line = 0; int character = 0; - bool operator==(const lsPosition &o) const { + bool operator==(const Position &o) const { return line == o.line && character == o.character; } - bool operator<(const lsPosition &o) const { + bool operator<(const Position &o) const { return line != o.line ? line < o.line : character < o.character; } std::string ToString() const; }; -MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { - lsPosition start; - lsPosition end; + Position start; + Position end; bool operator==(const lsRange &o) const { return start == o.start && end == o.end; } @@ -125,7 +114,6 @@ struct lsRange { return !(start == o.start) ? start < o.start : end < o.end; } }; -MAKE_REFLECT_STRUCT(lsRange, start, end); struct Location { DocumentUri uri; @@ -138,7 +126,6 @@ struct Location { : range < o.range; } }; -MAKE_REFLECT_STRUCT(Location, uri, range); enum class SymbolKind : uint8_t { Unknown = 0, @@ -181,7 +168,6 @@ enum class SymbolKind : uint8_t { StaticMethod = 254, Macro = 255, }; -MAKE_REFLECT_TYPE_PROXY(SymbolKind); struct SymbolInformation { std::string_view name; @@ -193,57 +179,24 @@ struct SymbolInformation { struct TextDocumentIdentifier { DocumentUri uri; }; -MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri); struct VersionedTextDocumentIdentifier { DocumentUri uri; // The version number of this document. number | null std::optional version; }; -MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); struct TextEdit { - // The range of the text document to be manipulated. To insert - // text into a document create a range where start === end. lsRange range; - - // The string to be inserted. For delete operations use an - // empty string. std::string newText; - - bool operator==(const TextEdit &that); }; -MAKE_REFLECT_STRUCT(TextEdit, range, newText); struct TextDocumentItem { - // The text document's URI. DocumentUri uri; - - // The text document's language identifier. std::string languageId; - - // The version number of this document (it will strictly increase after each - // change, including undo/redo). int version; - - // The content of the opened text document. std::string text; }; -MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); - -struct TextDocumentEdit { - // The text document to change. - VersionedTextDocumentIdentifier textDocument; - - // The edits to be applied. - std::vector edits; -}; -MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits); - -struct WorkspaceEdit { - std::vector documentChanges; -}; -MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges); struct TextDocumentContentChangeEvent { // The range of the document that changed. @@ -263,84 +216,27 @@ struct WorkspaceFolder { DocumentUri uri; std::string name; }; -MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); -// Show a message to the user. enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; MAKE_REFLECT_TYPE_PROXY(MessageType) -enum class DiagnosticSeverity { - // Reports an error. - Error = 1, - // Reports a warning. - Warning = 2, - // Reports an information. - Information = 3, - // Reports a hint. - Hint = 4 -}; -MAKE_REFLECT_TYPE_PROXY(DiagnosticSeverity); - struct Diagnostic { - // The range at which the message applies. lsRange range; - - // The diagnostic's severity. Can be omitted. If omitted it is up to the - // client to interpret diagnostics as error, warning, info or hint. - std::optional severity; - - // The diagnostic's code. Can be omitted. + int severity = 0; int code = 0; - - // A human-readable string describing the source of this - // diagnostic, e.g. 'typescript' or 'super lint'. std::string source = "ccls"; - - // The diagnostic's message. std::string message; - - // Non-serialized set of fixits. std::vector fixits_; }; -MAKE_REFLECT_STRUCT(Diagnostic, range, severity, source, message); struct ShowMessageParam { MessageType type = MessageType::Error; std::string message; }; -MAKE_REFLECT_STRUCT(ShowMessageParam, type, message); // Used to identify the language at a file level. The ordering is important, as // a file previously identified as `C`, will be changed to `Cpp` if it // encounters a c++ declaration. enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 }; -MAKE_REFLECT_TYPE_PROXY(LanguageId); - -// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in -// front of others. -enum class Kind : uint8_t { Invalid, File, Type, Func, Var }; -MAKE_REFLECT_TYPE_PROXY(Kind); - -enum class Role : uint16_t { - None = 0, - Declaration = 1 << 0, - Definition = 1 << 1, - Reference = 1 << 2, - Read = 1 << 3, - Write = 1 << 4, - Call = 1 << 5, - Dynamic = 1 << 6, - Address = 1 << 7, - Implicit = 1 << 8, - All = (1 << 9) - 1, -}; -MAKE_REFLECT_TYPE_PROXY(Role); -inline uint16_t operator&(Role lhs, Role rhs) { - return uint16_t(lhs) & uint16_t(rhs); -} - -inline Role operator|(Role lhs, Role rhs) { - return Role(uint16_t(lhs) | uint16_t(rhs)); -} } // namespace ccls diff --git a/src/match.cc b/src/match.cc index d9b7b2344..dc8515515 100644 --- a/src/match.cc +++ b/src/match.cc @@ -15,7 +15,7 @@ limitations under the License. #include "match.hh" -#include "lsp.hh" +#include "message_handler.hh" #include "pipeline.hh" namespace ccls { diff --git a/src/message_handler.cc b/src/message_handler.cc index 626983da0..ddb030316 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -30,6 +30,8 @@ using namespace clang; MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { +MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); +MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); MAKE_REFLECT_STRUCT(EmptyParam, placeholder); MAKE_REFLECT_STRUCT(TextDocumentParam, textDocument); MAKE_REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument); @@ -38,10 +40,6 @@ MAKE_REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges); MAKE_REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position); MAKE_REFLECT_STRUCT(RenameParam, textDocument, position, newName); -// code* -MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); -MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); - // completion MAKE_REFLECT_TYPE_PROXY(CompletionTriggerKind); MAKE_REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter); @@ -74,24 +72,23 @@ struct CclsSemanticHighlightSymbol { std::vector lsRanges; }; -struct CclsSemanticHighlightParams { +struct CclsSemanticHighlight { DocumentUri uri; std::vector symbols; }; MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, ranges, lsRanges); -MAKE_REFLECT_STRUCT(CclsSemanticHighlightParams, uri, symbols); +MAKE_REFLECT_STRUCT(CclsSemanticHighlight, uri, symbols); -struct CclsSetSkippedRangesParams { +struct CclsSetSkippedRanges { DocumentUri uri; std::vector skippedRanges; }; -MAKE_REFLECT_STRUCT(CclsSetSkippedRangesParams, uri, skippedRanges); - +MAKE_REFLECT_STRUCT(CclsSetSkippedRanges, uri, skippedRanges); struct ScanLineEvent { - lsPosition pos; - lsPosition end_pos; // Second key when there is a tie for insertion events. + Position pos; + Position end_pos; // Second key when there is a tie for insertion events. int id; CclsSemanticHighlightSymbol *symbol; bool operator<(const ScanLineEvent &other) const { @@ -273,7 +270,7 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply, } void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) { - CclsSetSkippedRangesParams params; + CclsSetSkippedRanges params; params.uri = DocumentUri::FromPath(wfile->filename); for (Range skipped : file.def->skipped_ranges) if (auto ls_skipped = GetLsRange(wfile, skipped)) @@ -365,8 +362,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { continue; // applies to for loop } - std::optional loc = GetLsRange(wfile, sym.range); - if (loc) { + if (std::optional loc = GetLsRange(wfile, sym.range)) { auto it = grouped_symbols.find(sym); if (it != grouped_symbols.end()) { it->second.lsRanges.push_back(*loc); @@ -421,7 +417,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { deleted[~events[i].id] = 1; } - CclsSemanticHighlightParams params; + CclsSemanticHighlight params; params.uri = DocumentUri::FromPath(wfile->filename); // Transform lsRange into pair (offset pairs) if (!g_config->highlight.lsRanges) { diff --git a/src/message_handler.hh b/src/message_handler.hh index 00ad2aeb3..bac8b1b9b 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -36,35 +36,40 @@ void Reply(RequestId id, const std::function &fn); void ReplyError(RequestId id, const std::function &fn); } +struct CodeActionParam { + TextDocumentIdentifier textDocument; + lsRange range; + struct Context { + std::vector diagnostics; + } context; +}; struct EmptyParam { bool placeholder; }; -struct TextDocumentParam { - TextDocumentIdentifier textDocument; -}; struct DidOpenTextDocumentParam { TextDocumentItem textDocument; }; - -struct TextDocumentPositionParam { - TextDocumentIdentifier textDocument; - lsPosition position; -}; - struct RenameParam { TextDocumentIdentifier textDocument; - lsPosition position; + Position position; std::string newName; }; - -// code* -struct CodeActionParam { +struct TextDocumentParam { TextDocumentIdentifier textDocument; - lsRange range; - struct Context { - std::vector diagnostics; - } context; }; +struct TextDocumentPositionParam { + TextDocumentIdentifier textDocument; + Position position; +}; +struct TextDocumentEdit { + VersionedTextDocumentIdentifier textDocument; + std::vector edits; +}; +MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits); +struct WorkspaceEdit { + std::vector documentChanges; +}; +MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges); // completion enum class CompletionTriggerKind { @@ -139,7 +144,7 @@ struct DocumentFormattingParam { }; struct DocumentOnTypeFormattingParam { TextDocumentIdentifier textDocument; - lsPosition position; + Position position; std::string ch; FormattingOptions options; }; @@ -173,6 +178,21 @@ struct WorkspaceSymbolParam { // ccls extensions std::vector folders; }; +MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); + +MAKE_REFLECT_TYPE_PROXY(ErrorCode); +MAKE_REFLECT_STRUCT(ResponseError, code, message); +MAKE_REFLECT_STRUCT(Position, line, character); +MAKE_REFLECT_STRUCT(lsRange, start, end); +MAKE_REFLECT_STRUCT(Location, uri, range); +MAKE_REFLECT_TYPE_PROXY(SymbolKind); +MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri); +MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); +MAKE_REFLECT_STRUCT(TextEdit, range, newText); +MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); +MAKE_REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); +MAKE_REFLECT_STRUCT(ShowMessageParam, type, message); +MAKE_REFLECT_TYPE_PROXY(LanguageId); // TODO llvm 8 llvm::unique_function template diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 0743891a1..03f895f05 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -20,12 +20,12 @@ namespace ccls { namespace { struct Param { TextDocumentIdentifier textDocument; - lsPosition position; + Position position; std::string direction; }; MAKE_REFLECT_STRUCT(Param, textDocument, position, direction); -Maybe FindParent(QueryFile *file, Position pos) { +Maybe FindParent(QueryFile *file, Pos pos) { Maybe parent; for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && sym.extent.Valid() && sym.extent.start <= pos && @@ -47,12 +47,12 @@ void MessageHandler::ccls_navigate(Reader &reader, return; WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - lsPosition ls_pos = param.position; + Position ls_pos = param.position; if (wfile && wfile->index_lines.size()) if (auto line = wfile->GetIndexPosFromBufferPos(ls_pos.line, &ls_pos.character, false)) ls_pos.line = *line; - Position pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; + Pos pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; Maybe res; switch (param.direction[0]) { diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 481c8dfce..5c49f5a50 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -95,7 +95,7 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) { // significantly snappier completion experience as vscode is easily overloaded // when given 1000+ completion items. void FilterCandidates(CompletionList &result, const std::string &complete_text, - lsPosition begin_pos, lsPosition end_pos, + Position begin_pos, Position end_pos, const std::string &buffer_line) { assert(begin_pos.line == end_pos.line); auto &items = result.items; @@ -126,7 +126,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; if (edits.size() && edits[0].range.end == begin_pos) { - lsPosition start = edits[0].range.start, end = edits[0].range.end; + Position start = edits[0].range.start, end = edits[0].range.end; item.textEdit.range.start = start; item.textEdit.newText = edits[0].newText + item.textEdit.newText; if (start.line == begin_pos.line && item.filterText) { @@ -482,8 +482,8 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, } std::string completion_text; - lsPosition end_pos = param.position; - lsPosition begin_pos = file->FindStableCompletionSource( + Position end_pos = param.position; + Position begin_pos = file->FindStableCompletionSource( param.position, &completion_text, &end_pos); ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index df212ba5c..cd52afaf8 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -55,7 +55,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, std::vector result; Maybe on_def; WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - lsPosition &ls_pos = param.position; + Position &ls_pos = param.position; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { // Special cases which are handled: @@ -107,7 +107,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, } // Find the best match of the identifier at point. if (!range) { - lsPosition position = param.position; + Position position = param.position; const std::string &buffer = wfile->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); std::string_view short_query = query; diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index fb50c86c6..944c90e1c 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -43,14 +43,9 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, path_to_edit[file_id].textDocument.version = working_file->version; } - TextEdit edit; + TextEdit &edit = path_to_edit[file_id].edits.emplace_back(); edit.range = ls_location->range; edit.newText = new_text; - - // vscode complains if we submit overlapping text edits. - auto &edits = path_to_edit[file_id].edits; - if (std::find(edits.begin(), edits.end(), edit) == edits.end()) - edits.push_back(edit); }); WorkspaceEdit edit; diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 1f27f28ed..b3fa946fa 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -155,10 +155,10 @@ void MessageHandler::textDocument_signatureHelp( static CompleteConsumerCache cache; std::string path = param.textDocument.uri.GetPath(); - lsPosition begin_pos = param.position; + Position begin_pos = param.position; if (WorkingFile *file = wfiles->GetFileByFilename(path)) { std::string completion_text; - lsPosition end_pos = param.position; + Position end_pos = param.position; begin_pos = file->FindStableCompletionSource(param.position, &completion_text, &end_pos); } diff --git a/src/position.cc b/src/position.cc index cbf1352fb..2a124c5bd 100644 --- a/src/position.cc +++ b/src/position.cc @@ -22,7 +22,7 @@ limitations under the License. #include namespace ccls { -Position Position::FromString(const std::string &encoded) { +Pos Pos::FromString(const std::string &encoded) { char *p = const_cast(encoded.c_str()); int16_t line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); @@ -31,14 +31,14 @@ Position Position::FromString(const std::string &encoded) { return {line, column}; } -std::string Position::ToString() { +std::string Pos::ToString() { char buf[99]; snprintf(buf, sizeof buf, "%d:%d", line + 1, column + 1); return buf; } Range Range::FromString(const std::string &encoded) { - Position start, end; + Pos start, end; char *p = const_cast(encoded.c_str()); start.line = int16_t(strtol(p, &p, 10)) - 1; assert(*p == ':'); @@ -57,11 +57,11 @@ Range Range::FromString(const std::string &encoded) { bool Range::Contains(int line, int column) const { if (line > INT16_MAX) return false; - Position p{int16_t(line), int16_t(std::min(column, INT16_MAX))}; + Pos p{int16_t(line), int16_t(std::min(column, INT16_MAX))}; return !(p < start) && p < end; } -Range Range::RemovePrefix(Position position) const { +Range Range::RemovePrefix(Pos position) const { return {std::min(std::max(position, start), end), end}; } @@ -73,15 +73,15 @@ std::string Range::ToString() { } // Position -void Reflect(Reader &visitor, Position &value) { +void Reflect(Reader &visitor, Pos &value) { if (visitor.Format() == SerializeFormat::Json) { - value = Position::FromString(visitor.GetString()); + value = Pos::FromString(visitor.GetString()); } else { Reflect(visitor, value.line); Reflect(visitor, value.column); } } -void Reflect(Writer &visitor, Position &value) { +void Reflect(Writer &visitor, Pos &value) { if (visitor.Format() == SerializeFormat::Json) { std::string output = value.ToString(); visitor.String(output.c_str(), output.size()); diff --git a/src/position.hh b/src/position.hh index 7d4477175..794c7af2b 100644 --- a/src/position.hh +++ b/src/position.hh @@ -22,37 +22,37 @@ limitations under the License. #include namespace ccls { -struct Position { +struct Pos { int16_t line = -1; int16_t column = -1; - static Position FromString(const std::string &encoded); + static Pos FromString(const std::string &encoded); bool Valid() const { return line >= 0; } std::string ToString(); // Compare two Positions and check if they are equal. Ignores the value of // |interesting|. - bool operator==(const Position &o) const { + bool operator==(const Pos &o) const { return line == o.line && column == o.column; } - bool operator<(const Position &o) const { + bool operator<(const Pos &o) const { if (line != o.line) return line < o.line; return column < o.column; } - bool operator<=(const Position &o) const { return !(o < *this); } + bool operator<=(const Pos &o) const { return !(o < *this); } }; struct Range { - Position start; - Position end; + Pos start; + Pos end; static Range FromString(const std::string &encoded); bool Valid() const { return start.Valid(); } bool Contains(int line, int column) const; - Range RemovePrefix(Position position) const; + Range RemovePrefix(Pos position) const; std::string ToString(); @@ -67,8 +67,8 @@ struct Range { // Reflection class Reader; class Writer; -void Reflect(Reader &visitor, Position &value); -void Reflect(Writer &visitor, Position &value); +void Reflect(Reader &visitor, Pos &value); +void Reflect(Writer &visitor, Pos &value); void Reflect(Reader &visitor, Range &value); void Reflect(Writer &visitor, Range &value); } // namespace ccls @@ -87,4 +87,4 @@ template <> struct hash { }; } // namespace std -MAKE_HASHABLE(ccls::Position, t.line, t.column); +MAKE_HASHABLE(ccls::Pos, t.line, t.column); diff --git a/src/query_utils.cc b/src/query_utils.cc index 9bda5df2e..34411f21b 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -155,8 +155,8 @@ std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { std::optional GetLsRange(WorkingFile *wfile, const Range &location) { if (!wfile || wfile->index_lines.empty()) - return lsRange{lsPosition{location.start.line, location.start.column}, - lsPosition{location.end.line, location.end.column}}; + return lsRange{Position{location.start.line, location.start.column}, + Position{location.end.line, location.end.column}}; int start_column = location.start.column, end_column = location.end.column; std::optional start = wfile->GetBufferPosFromIndexPos( @@ -177,8 +177,7 @@ std::optional GetLsRange(WorkingFile *wfile, if (*start == *end && start_column > end_column) end_column = start_column; - return lsRange{lsPosition{*start, start_column}, - lsPosition{*end, end_column}}; + return lsRange{Position{*start, start_column}, Position{*end, end_column}}; } DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { @@ -278,8 +277,7 @@ std::optional GetSymbolInfo(DB *db, SymbolIdx sym, } std::vector FindSymbolsAtLocation(WorkingFile *wfile, - QueryFile *file, - lsPosition &ls_pos, + QueryFile *file, Position &ls_pos, bool smallest) { std::vector symbols; // If multiVersion > 0, index may not exist and thus index_lines is empty. diff --git a/src/query_utils.hh b/src/query_utils.hh index c19000420..1bf69f622 100644 --- a/src/query_utils.hh +++ b/src/query_utils.hh @@ -50,7 +50,7 @@ std::optional GetSymbolInfo(DB *db, SymbolIdx sym, std::vector FindSymbolsAtLocation(WorkingFile *working_file, QueryFile *file, - lsPosition &ls_pos, + Position &ls_pos, bool smallest = false); template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { diff --git a/src/serializer.cc b/src/serializer.cc index f2ac8e0f8..3c152ebc2 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -18,6 +18,7 @@ limitations under the License. #include "filesystem.hh" #include "indexer.hh" #include "log.hh" +#include "message_handler.hh" #include "serializers/binary.hh" #include "serializers/json.hh" diff --git a/src/working_files.cc b/src/working_files.cc index aeec375d7..6c7ac4632 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -33,7 +33,7 @@ constexpr int kMaxDiff = 20; // |kMaxColumnAlignSize|. constexpr int kMaxColumnAlignSize = 200; -lsPosition GetPositionForOffset(const std::string &content, int offset) { +Position GetPositionForOffset(const std::string &content, int offset) { if (offset >= content.size()) offset = (int)content.size() - 1; @@ -341,9 +341,10 @@ std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int *column, index_lines, is_end); } -std::string WorkingFile::FindClosestCallNameInBuffer( - lsPosition position, int *active_parameter, - lsPosition *completion_position) const { +std::string +WorkingFile::FindClosestCallNameInBuffer(Position position, + int *active_parameter, + Position *completion_position) const { *active_parameter = 0; int offset = GetOffsetForPosition(position, buffer_content); @@ -389,10 +390,10 @@ std::string WorkingFile::FindClosestCallNameInBuffer( return buffer_content.substr(offset, start_offset - offset + 1); } -lsPosition -WorkingFile::FindStableCompletionSource(lsPosition position, +Position +WorkingFile::FindStableCompletionSource(Position position, std::string *existing_completion, - lsPosition *replace_end_pos) const { + Position *replace_end_pos) const { int start_offset = GetOffsetForPosition(position, buffer_content); int offset = start_offset; @@ -538,7 +539,7 @@ WorkingFiles::AsSnapshot(const std::vector &filter_paths) { // text documents. // We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). // This is good enough and fails only for UTF-16 surrogate pairs. -int GetOffsetForPosition(lsPosition pos, std::string_view content) { +int GetOffsetForPosition(Position pos, std::string_view content) { size_t i = 0; for (; pos.line > 0 && i < content.size(); i++) if (content[i] == '\n') @@ -554,7 +555,7 @@ int GetOffsetForPosition(lsPosition pos, std::string_view content) { return int(i); } -std::string_view LexIdentifierAroundPos(lsPosition position, +std::string_view LexIdentifierAroundPos(Position position, std::string_view content) { int start = GetOffsetForPosition(position, content); int end = start + 1; diff --git a/src/working_files.hh b/src/working_files.hh index 31826dc2e..f0df1c6fe 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -72,8 +72,8 @@ struct WorkingFile { // |completion_position| will be point to a good code completion location to // for fetching signatures. std::string - FindClosestCallNameInBuffer(lsPosition position, int *active_parameter, - lsPosition *completion_position = nullptr) const; + FindClosestCallNameInBuffer(Position position, int *active_parameter, + Position *completion_position = nullptr) const; // Returns a relatively stable completion position (it jumps back until there // is a non-alphanumeric character). @@ -82,9 +82,9 @@ struct WorkingFile { // global completion. // The out param |existing_completion| is set to any existing completion // content the user has entered. - lsPosition FindStableCompletionSource(lsPosition position, + Position FindStableCompletionSource(Position position, std::string *existing_completion, - lsPosition *replace_end_pos) const; + Position *replace_end_pos) const; private: // Compute index_to_buffer and buffer_to_index. @@ -132,8 +132,8 @@ struct WorkingFiles { std::mutex files_mutex; // Protects |files|. }; -int GetOffsetForPosition(lsPosition pos, std::string_view content); +int GetOffsetForPosition(Position pos, std::string_view content); -std::string_view LexIdentifierAroundPos(lsPosition position, +std::string_view LexIdentifierAroundPos(Position position, std::string_view content); } // namespace ccls From 58c701d98a2801bd3a80c4fa145857133119cd2f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 7 Nov 2018 17:20:41 -0800 Subject: [PATCH 285/378] Improve semantic highlight in templates --- src/message_handler.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/message_handler.cc b/src/message_handler.cc index ddb030316..969c691b5 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -91,15 +91,19 @@ struct ScanLineEvent { Position end_pos; // Second key when there is a tie for insertion events. int id; CclsSemanticHighlightSymbol *symbol; - bool operator<(const ScanLineEvent &other) const { + bool operator<(const ScanLineEvent &o) const { // See the comments below when insertion/deletion events are inserted. - if (!(pos == other.pos)) - return pos < other.pos; - if (!(other.end_pos == end_pos)) - return other.end_pos < end_pos; + if (!(pos == o.pos)) + return pos < o.pos; + if (!(o.end_pos == end_pos)) + return o.end_pos < end_pos; // This comparison essentially order Macro after non-Macro, // So that macros will not be rendered as Var/Type/... - return symbol->kind < other.symbol->kind; + if (symbol->kind != o.symbol->kind) + return symbol->kind < o.symbol->kind; + // If symbol A and B occupy the same place, we want one to be placed + // before the other consistantly. + return symbol->id < o.symbol->id; } }; } // namespace From 94d2b5821e34b51db1409b4adfbcee31fb077bbc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 8 Nov 2018 11:32:27 -0800 Subject: [PATCH 286/378] Work around relative --sysroot= --- src/messages/initialize.cc | 4 +++- src/project.cc | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cc2d76c20..7c93511eb 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -269,7 +269,9 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { LOG_S(INFO) << "initializationOptions: " << output.GetString(); if (g_config->cacheDirectory.size()) { - g_config->cacheDirectory = NormalizePath(g_config->cacheDirectory); + SmallString<256> Path(g_config->cacheDirectory); + sys::fs::make_absolute(Path); + g_config->cacheDirectory = Path.str(); EnsureEndsInSlash(g_config->cacheDirectory); } } diff --git a/src/project.cc b/src/project.cc index ec48e16dd..911e84d25 100644 --- a/src/project.cc +++ b/src/project.cc @@ -15,6 +15,7 @@ limitations under the License. #include "project.hh" +#include "clang_tu.hh" // llvm::vfs #include "filesystem.hh" #include "log.hh" #include "match.hh" @@ -328,6 +329,7 @@ LoadEntriesFromDirectory(ProjectConfig *project, std::vector result; ProjectProcessor proc(project); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { + static bool once; Project::Entry entry; entry.root = project->root; DoPathMapping(entry.root); @@ -342,7 +344,18 @@ LoadEntriesFromDirectory(ProjectConfig *project, DoPathMapping(arg); entry.args.push_back(Intern(arg)); } + + // Work around relative --sysroot= as it isn't affected by + // -working-directory=. chdir is thread hostile but this function runs + // before indexers do actual work and it works when there is only one + // workspace folder. + if (!once) { + once = true; + llvm::vfs::getRealFileSystem()->setCurrentWorkingDirectory( + entry.directory); + } proc.Process(entry); + if (Seen.insert(entry.filename).second) result.push_back(entry); } From eeeb03c0688cb059b0974fbc7a61aee73bac1309 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 8 Nov 2018 21:18:41 -0800 Subject: [PATCH 287/378] If clang >= 8, delete search path detection and use Sema::CodeCompleteIncludedFile --- src/clang_complete.cc | 58 ++++------ src/include_complete.cc | 2 +- src/messages/textDocument_completion.cc | 146 ++++++++++++------------ src/project.cc | 2 + 4 files changed, 96 insertions(+), 112 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index ffaa286d8..5ccad32c5 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -143,13 +143,6 @@ struct PreambleData { }; namespace { - -std::string StripFileType(const std::string &path) { - SmallString<128> Ret; - sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path)); - return sys::path::convert_to_slash(Ret); -} - bool LocationInRange(SourceLocation L, CharSourceRange R, const SourceManager &M) { assert(R.isCharRange()); @@ -272,23 +265,16 @@ class StoreDiags : public DiagnosticConsumer { std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, - const PreambleData *preamble, const WorkingFiles::Snapshot &snapshot, - std::vector> &Bufs) { - std::string main = ResolveIfRelative( - session.file.directory, - sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile())); - for (auto &file : snapshot.files) { - Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); - if (preamble && file.filename == main) { + const PreambleData *preamble, const std::string &path, + std::unique_ptr &Buf) { + if (preamble) { #if LLVM_VERSION_MAJOR >= 7 - preamble->Preamble.OverridePreamble(*CI, FS, Bufs.back().get()); + preamble->Preamble.OverridePreamble(*CI, FS, Buf.get()); #else - preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get()); + preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get()); #endif - continue; - } - CI->getPreprocessorOpts().addRemappedFile(file.filename, - Bufs.back().get()); + } else { + CI->getPreprocessorOpts().addRemappedFile(path, Buf.get()); } auto Clang = std::make_unique(session.PCH); @@ -358,8 +344,6 @@ void *CompletionPreloadMain(void *manager_) { continue; const auto &args = session->file.args; - WorkingFiles::Snapshot snapshot = - session->wfiles->AsSnapshot({StripFileType(session->file.filename)}); auto stat_cache = std::make_unique(); IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); @@ -415,19 +399,24 @@ void *CompletionMain(void *manager_) { CI->getLangOpts()->CommentOpts.ParseAllComments = true; DiagnosticConsumer DC; - WorkingFiles::Snapshot snapshot = - manager->wfiles_->AsSnapshot({StripFileType(path)}); - std::vector> Bufs; + std::string content = manager->wfiles_->GetContent(path); + auto Buf = llvm::MemoryBuffer::getMemBuffer(content); + bool in_preamble = + GetOffsetForPosition( + {request->position.line, request->position.character}, content) < + ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0).Size; + if (in_preamble) + preamble.reset(); auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, - preamble.get(), snapshot, Bufs); + preamble.get(), path, Buf); if (!Clang) continue; + Clang->getPreprocessorOpts().SingleFileParseMode = in_preamble; Clang->setCodeCompletionConsumer(request->Consumer.release()); if (!Parse(*Clang)) continue; - for (auto &Buf : Bufs) - Buf.release(); + Buf.release(); request->on_complete(&Clang->getCodeCompletionConsumer()); } @@ -482,6 +471,7 @@ void *DiagnosticMain(void *manager_) { std::shared_ptr preamble = session->GetPreamble(); IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; + std::unique_ptr CI = BuildCompilerInvocation(session->file.args, FS); if (!CI) @@ -489,17 +479,15 @@ void *DiagnosticMain(void *manager_) { CI->getDiagnosticOpts().IgnoreWarnings = false; CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; StoreDiags DC(path); - WorkingFiles::Snapshot snapshot = - manager->wfiles_->AsSnapshot({StripFileType(path)}); - std::vector> Bufs; + std::string content = manager->wfiles_->GetContent(path); + auto Buf = llvm::MemoryBuffer::getMemBuffer(content); auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, - preamble.get(), snapshot, Bufs); + preamble.get(), path, Buf); if (!Clang) continue; if (!Parse(*Clang)) continue; - for (auto &Buf : Bufs) - Buf.release(); + Buf.release(); auto Fill = [](const DiagBase &d, Diagnostic &ret) { ret.range = lsRange{{d.range.start.line, d.range.start.column}, diff --git a/src/include_complete.cc b/src/include_complete.cc index c806dcc84..fab2279bd 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -104,7 +104,7 @@ IncludeComplete::IncludeComplete(Project *project) : is_scanning(false), project_(project) {} void IncludeComplete::Rescan() { - if (is_scanning) + if (is_scanning || LLVM_VERSION_MAJOR >= 8) return; completion_items.clear(); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 5c49f5a50..5748b8bd2 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -24,7 +24,9 @@ limitations under the License. #include #include +#if LLVM_VERSION_MAJOR < 8 #include +#endif namespace ccls { using namespace clang; @@ -43,6 +45,7 @@ struct CompletionList { }; MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items); +#if LLVM_VERSION_MAJOR < 8 void DecorateIncludePaths(const std::smatch &match, std::vector *items) { std::string spaces_after_include = " "; @@ -90,6 +93,7 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) { bool ok = std::regex_match(line, match, pattern); return {ok, match[3], match[5], match[6], match}; } +#endif // Pre-filters completion responses before sending to vscode. This results in a // significantly snappier completion experience as vscode is easily overloaded @@ -121,7 +125,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; if (has_open_paren && item.filterText) - item.textEdit.newText = item.filterText.value(); + item.textEdit.newText = *item.filterText; // https://github.com/Microsoft/language-server-protocol/issues/543 // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; @@ -133,7 +137,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, item.filterText = buffer_line.substr(start.character, end.character - start.character) + - item.filterText.value(); + *item.filterText; } edits.erase(edits.begin()); } @@ -391,6 +395,10 @@ class CompletionConsumer : public CodeCompleteConsumer { includeBriefComments()); CompletionItem ls_item; ls_item.kind = GetCompletionKind(R.CursorKind); +#if LLVM_VERSION_MAJOR >= 8 + if (Context.getKind() == CodeCompletionContext::CCC_IncludedFile) + ls_item.kind = CompletionItemKind::File; +#endif if (const char *brief = CCS->getBriefComment()) ls_item.documentation = brief; ls_item.detail = CCS->getParentContextName().str(); @@ -443,51 +451,44 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, param.position.line < file->buffer_lines.size()) buffer_line = file->buffer_lines[param.position.line]; - // Check for - and : before completing -> or ::, since vscode does not - // support multi-character trigger characters. + clang::CodeCompleteOptions CCOpts; + CCOpts.IncludeBriefComments = true; + CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#"); +#if LLVM_VERSION_MAJOR >= 7 + CCOpts.IncludeFixIts = true; +#endif + CCOpts.IncludeMacros = true; + if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter && param.context.triggerCharacter) { - bool did_fail_check = false; - - std::string character = *param.context.triggerCharacter; - int preceding_index = param.position.character - 2; - - // If the character is '"', '<' or '/', make sure that the line starts - // with '#'. - if (character == "\"" || character == "<" || character == "/") { - size_t i = 0; - while (i < buffer_line.size() && isspace(buffer_line[i])) - ++i; - if (i >= buffer_line.size() || buffer_line[i] != '#') - did_fail_check = true; - } - // If the character is > or : and we are at the start of the line, do not - // show completion results. - else if ((character == ">" || character == ":") && preceding_index < 0) { - did_fail_check = true; - } - // If the character is > but - does not preced it, or if it is : and : - // does not preced it, do not show completion results. - else if (preceding_index >= 0 && - preceding_index < (int)buffer_line.size()) { - char preceding = buffer_line[preceding_index]; - did_fail_check = (preceding != '-' && character == ">") || - (preceding != ':' && character == ":"); + bool ok = true; + int col = param.position.character - 2; + switch ((*param.context.triggerCharacter)[0]) { + case '"': + case '/': + case '<': + ok = CCOpts.IncludeCodePatterns; // start with # + break; + case ':': + ok = col >= 0 && buffer_line[col] == ':'; // :: + break; + case '>': + ok = col >= 0 && buffer_line[col] == '-'; // -> + break; } - - if (did_fail_check) { + if (!ok) { reply(result); return; } } - std::string completion_text; + std::string filter; Position end_pos = param.position; - Position begin_pos = file->FindStableCompletionSource( - param.position, &completion_text, &end_pos); + Position begin_pos = + file->FindStableCompletionSource(param.position, &filter, &end_pos); +#if LLVM_VERSION_MAJOR < 8 ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); - if (preprocess.ok && preprocess.keyword.compare("include") == 0) { CompletionList result; { @@ -506,47 +507,40 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, buffer_line); DecorateIncludePaths(preprocess.match, &result.items); reply(result); - } else { - std::string path = param.textDocument.uri.GetPath(); - CompletionManager::OnComplete callback = - [completion_text, path, begin_pos, end_pos, reply, - buffer_line](CodeCompleteConsumer *OptConsumer) { - if (!OptConsumer) - return; - auto *Consumer = static_cast(OptConsumer); - CompletionList result; - result.items = Consumer->ls_items; - - FilterCandidates(result, completion_text, begin_pos, end_pos, - buffer_line); - reply(result); - if (!Consumer->from_cache) { - cache.WithLock([&]() { - cache.path = path; - cache.position = begin_pos; - cache.result = Consumer->ls_items; - }); - } - }; - - clang::CodeCompleteOptions CCOpts; - CCOpts.IncludeBriefComments = true; - CCOpts.IncludeCodePatterns = preprocess.ok; // if there is a # -#if LLVM_VERSION_MAJOR >= 7 - CCOpts.IncludeFixIts = true; + return; + } #endif - CCOpts.IncludeMacros = true; - if (cache.IsCacheValid(path, begin_pos)) { - CompletionConsumer Consumer(CCOpts, true); - cache.WithLock([&]() { Consumer.ls_items = cache.result; }); - callback(&Consumer); - } else { - clang_complete->completion_request_.PushBack( - std::make_unique( - reply.id, param.textDocument, begin_pos, - std::make_unique(CCOpts, false), CCOpts, - callback)); - } + + CompletionManager::OnComplete callback = + [filter, path, begin_pos, end_pos, reply, + buffer_line](CodeCompleteConsumer *OptConsumer) { + if (!OptConsumer) + return; + auto *Consumer = static_cast(OptConsumer); + CompletionList result; + result.items = Consumer->ls_items; + + FilterCandidates(result, filter, begin_pos, end_pos, buffer_line); + reply(result); + if (!Consumer->from_cache) { + cache.WithLock([&]() { + cache.path = path; + cache.position = begin_pos; + cache.result = Consumer->ls_items; + }); + } + }; + + if (cache.IsCacheValid(path, begin_pos)) { + CompletionConsumer Consumer(CCOpts, true); + cache.WithLock([&]() { Consumer.ls_items = cache.result; }); + callback(&Consumer); + } else { + clang_complete->completion_request_.PushBack( + std::make_unique( + reply.id, param.textDocument, begin_pos, + std::make_unique(CCOpts, false), CCOpts, + callback)); } } } // namespace ccls diff --git a/src/project.cc b/src/project.cc index 911e84d25..8ea716430 100644 --- a/src/project.cc +++ b/src/project.cc @@ -141,6 +141,7 @@ struct ProjectProcessor { } args.push_back(Intern("-working-directory=" + entry.directory)); entry.args = args; +#if LLVM_VERSION_MAJOR < 8 args.push_back("-fsyntax-only"); if (!command_set.insert(hash).second) return; @@ -191,6 +192,7 @@ struct ProjectProcessor { break; } } +#endif } }; From 5736dd094dfb3d40ac22cf825d806bf4525426bf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 11 Nov 2018 01:10:15 -0800 Subject: [PATCH 288/378] Fix some MSVC 2017 errors Thanks to Dso Tsin! --- src/clang_tu.cc | 3 ++- src/lsp.cc | 1 + src/position.cc | 7 ++----- src/position.hh | 8 +++----- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 91fa2e389..5a87153a1 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -45,7 +45,8 @@ static Pos Decomposed2LineAndCol(const SourceManager &SM, std::pair I) { int l = SM.getLineNumber(I.first, I.second) - 1, c = SM.getColumnNumber(I.first, I.second) - 1; - return {(int16_t)std::min(l, INT16_MAX), (int16_t)std::min(c, INT16_MAX)}; + return {(int16_t)std::min(l, INT16_MAX), + (int16_t)std::min(c, INT16_MAX)}; } Range FromCharSourceRange(const SourceManager &SM, const LangOptions &LangOpts, diff --git a/src/lsp.cc b/src/lsp.cc index 9adc2f425..3a95a9d80 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -18,6 +18,7 @@ limitations under the License. #include "log.hh" #include "serializers/json.hh" +#include #include namespace ccls { diff --git a/src/position.cc b/src/position.cc index 2a124c5bd..b82d30975 100644 --- a/src/position.cc +++ b/src/position.cc @@ -17,6 +17,7 @@ limitations under the License. #include "serializer.hh" +#include #include #include #include @@ -57,14 +58,10 @@ Range Range::FromString(const std::string &encoded) { bool Range::Contains(int line, int column) const { if (line > INT16_MAX) return false; - Pos p{int16_t(line), int16_t(std::min(column, INT16_MAX))}; + Pos p{(int16_t)line, (int16_t)std::min(column, INT16_MAX)}; return !(p < start) && p < end; } -Range Range::RemovePrefix(Pos position) const { - return {std::min(std::max(position, start), end), end}; -} - std::string Range::ToString() { char buf[99]; snprintf(buf, sizeof buf, "%d:%d-%d:%d", start.line + 1, start.column + 1, diff --git a/src/position.hh b/src/position.hh index 794c7af2b..e595e1ed3 100644 --- a/src/position.hh +++ b/src/position.hh @@ -52,7 +52,6 @@ struct Range { bool Valid() const { return start.Valid(); } bool Contains(int line, int column) const; - Range RemovePrefix(Pos position) const; std::string ToString(); @@ -76,12 +75,11 @@ void Reflect(Writer &visitor, Range &value); namespace std { template <> struct hash { std::size_t operator()(ccls::Range x) const { - union U { - ccls::Range range = {}; + union { + ccls::Range range; uint64_t u64; - } u; + } u{x}; static_assert(sizeof(ccls::Range) == 8); - u.range = x; return hash()(u.u64); } }; From a24fe5a3863abd1a0583b89634f82d5e13e81b44 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 10 Nov 2018 19:50:35 -0800 Subject: [PATCH 289/378] hierarchicalDocumentSymbol: display member function declarations --- src/messages/textDocument_document.cc | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 8b8599d94..9135ce762 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -174,21 +174,20 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, continue; auto &ds = r.first->second; ds = std::make_unique(); + if (auto range = GetLsRange(wfile, sym.range)) { + ds->selectionRange = *range; + ds->range = ds->selectionRange; + if (sym.extent.Valid()) + if (auto range1 = GetLsRange(wfile, sym.extent)) + ds->range = *range1; + } std::vector def_ptrs; - WithEntity(db, sym, [&, sym = sym](const auto &entity) { + WithEntity(db, sym, [&](const auto &entity) { auto *def = entity.AnyDef(); if (!def) return; ds->name = def->Name(false); ds->detail = def->Name(true); - if (auto ls_range = GetLsRange(wfile, sym.range)) { - ds->selectionRange = *ls_range; - ds->range = ds->selectionRange; - if (sym.extent.Valid()) - if (auto ls_range1 = GetLsRange(wfile, sym.extent)) - ds->range = *ls_range1; - } - for (auto &def : entity.def) if (def.file_id == file_id && !Ignore(&def)) { ds->kind = def.kind; @@ -196,11 +195,14 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, def_ptrs.push_back(&def); } }); - if (def_ptrs.empty() || !(param.all || sym.role & Role::Definition || - ds->kind == SymbolKind::Namespace)) { + if (!(param.all || sym.role & Role::Definition || + ds->kind == SymbolKind::Method || + ds->kind == SymbolKind::Namespace)) { ds.reset(); continue; } + if (def_ptrs.empty()) + continue; if (sym.kind == Kind::Func) funcs.emplace_back(std::move(def_ptrs), ds.get()); else if (sym.kind == Kind::Type) From 63a510ac2132d68d6291df50d99dd3286f3a32d6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 10 Nov 2018 15:05:21 -0800 Subject: [PATCH 290/378] Use SM.isWrittenInMainFile; suppress -Werror in preamble SM.isWrittenInMainFile is to work around preamble bug: spurious err_pp_unterminated_conditional with circular #include --- src/clang_complete.cc | 7 ++++++- src/indexer.cc | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 5ccad32c5..393cbcd40 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -221,7 +221,7 @@ class StoreDiags : public DiagnosticConsumer { if (!L.isValid()) return; const SourceManager &SM = Info.getSourceManager(); StringRef Filename = SM.getFilename(Info.getLocation()); - bool concerned = IsConcerned(SM, Info.getLocation()); + bool concerned = SM.isWrittenInMainFile(L); auto fillDiagBase = [&](DiagBase &d) { llvm::SmallString<64> Message; Info.FormatDiagnostic(Message); @@ -315,6 +315,11 @@ void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; + // -Werror makes warnings issued as errors, which stops parsing + // prematurely because of -ferror-limit=. This also works around the issue + // of -Werror + -Wunused-parameter in interaction with SkipFunctionBodies. + auto &Ws = CI.getDiagnosticOpts().Warnings; + Ws.erase(std::remove(Ws.begin(), Ws.end(), "error"), Ws.end()); CI.getDiagnosticOpts().IgnoreWarnings = false; CI.getFrontendOpts().SkipFunctionBodies = true; CI.getLangOpts()->CommentOpts.ParseAllComments = g_config->index.comments > 1; diff --git a/src/indexer.cc b/src/indexer.cc index 52aefbb07..f980ad628 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -722,7 +722,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!db) return true; param.SeenFile(*FE); - if (!SM.isInMainFile(R.getBegin())) + if (!SM.isWrittenInMainFile(R.getBegin())) lid = GetFileLID(db, SM, *FE); } else { db = param.ConsumeFile(*FE); From 77bec58a6202ef2acc351dc549b559c9bd6cebd7 Mon Sep 17 00:00:00 2001 From: Dso Tsin Date: Tue, 13 Nov 2018 12:33:01 +0800 Subject: [PATCH 291/378] Fix VS2017 build issues and add Appveyor CI script (#118) --- .appveyor.yml | 22 ++++++++++++++++++++++ CMakeLists.txt | 7 ++++--- cmake/FindClang.cmake | 7 ++++--- 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..0fc36d3fe --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,22 @@ +version: "{build}" + +os: Visual Studio 2017 + +platform: + - x64 + +build: + parallel: true # enable MSBuild parallel builds + verbosity: minimal + +install: + - if not exist llvm.tar.xz appveyor DownloadFile "https://ziglang.org/deps/llvm+clang-7.0.0-win64-msvc-release.tar.xz" -FileName llvm.tar.xz + - 7z e -txz llvm.tar.xz + - 7z x llvm.tar + - git submodule update --init --recursive +build_script: + - cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DSYSTEM_CLANG=ON -DCLANG_ROOT=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release + - cmake --build build --target ccls --config Release + +artifacts: + - path: build\Release diff --git a/CMakeLists.txt b/CMakeLists.txt index abe0e04b4..3d608c900 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,16 +50,17 @@ if(MSVC) /EHsc /D_CRT_SECURE_NO_WARNINGS # don't try to use MSVC std replacements /W3 # roughly -Wall - /wd4996 # disable loguru unsafe warnings - /wd4722 # ignores warning C4722 - # (destructor never returns) in loguru + /wd4996 # ignore deprecated declaration /wd4267 # ignores warning C4267 # (conversion from 'size_t' to 'type'), # roughly -Wno-sign-compare /wd4800 /wd4068 # Disable unknown pragma warning + /std:c++17 $<$:/FS> ) + # relink system libs + target_link_libraries(ccls PRIVATE Mincore.lib) else() # Common GCC/Clang(Linux) options target_compile_options(ccls PRIVATE diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index e56e25dd9..194029005 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -143,9 +143,10 @@ if(Clang_FOUND AND NOT TARGET Clang::Clang) set_target_properties(Clang::Clang PROPERTIES IMPORTED_LOCATION ${Clang_LIBRARY} INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") - - find_package(Curses REQUIRED) - find_package(ZLIB REQUIRED) + if(NOT MSVC) + find_package(Curses REQUIRED) + find_package(ZLIB REQUIRED) + endif() set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES};${ZLIB_LIBRARIES}") if(MINGW) set_property(TARGET Clang::Clang APPEND_STRING PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES ";version") From 6767b9bf240a81418481073a76332617a719a4ac Mon Sep 17 00:00:00 2001 From: Nikolaus Wittenstein Date: Tue, 13 Nov 2018 12:12:03 -0500 Subject: [PATCH 292/378] Add Apache LICENSE file (#121) --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 06dff217206751bd287e6e7ae45a0f385fd41411 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 15 Nov 2018 20:53:04 -0800 Subject: [PATCH 293/378] README: add client feature table --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 81d25dc5f..5c3e251d5 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,7 @@ cquery has system include path detection (through running the compiler driver) w # >>> [Getting started](../../wiki/Getting-started) (CLICK HERE) <<< * [Build](../../wiki/Build) -* [Emacs](../../wiki/Emacs) -* [LanguageClient-neovim](../../wiki/LanguageClient-neovim) +* [Client feature table](../../wiki/Client-feature-table) * [FAQ](../../wiki/FAQ) ccls can index itself (~180MiB RSS when ide, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See [wiki/compile_commands.json](../../wiki/compile_commands.json) for examples. From b31a1c6b3ea71bc028ca8ddb28c9fba510b12fef Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 16 Nov 2018 15:23:26 -0800 Subject: [PATCH 294/378] hierarchicalDocumentSymbol: support SymbolKind::Function declaration and uniquify by range Also ensure selectionRange is a subrange of range, otherwise VSCode won't show the item. Use detailed_name for 'detail' --- src/lsp.hh | 3 +++ src/messages/textDocument_document.cc | 25 ++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/lsp.hh b/src/lsp.hh index 27c9727f1..b6a60877a 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -101,6 +101,9 @@ struct Position { bool operator<(const Position &o) const { return line != o.line ? line < o.line : character < o.character; } + bool operator<=(const Position &o) const { + return line != o.line ? line < o.line : character <= o.character; + } std::string ToString() const; }; diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 9135ce762..2ff5d218c 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -137,6 +137,16 @@ template<> bool Ignore(const QueryVar::Def *def) { return !def || def->is_local(); } + +void Uniquify(std::vector> &cs) { + std::sort(cs.begin(), cs.end(), + [](auto &l, auto &r) { return l->range < r->range; }); + cs.erase(std::unique(cs.begin(), cs.end(), + [](auto &l, auto &r) { return l->range == r->range; }), + cs.end()); + for (auto &c : cs) + Uniquify(c->children); +} } // namespace void MessageHandler::textDocument_documentSymbol(Reader &reader, @@ -177,8 +187,13 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, if (auto range = GetLsRange(wfile, sym.range)) { ds->selectionRange = *range; ds->range = ds->selectionRange; + // For a macro expansion, M(name), we may use `M` for extent and `name` + // for spell, do the check as selectionRange must be a subrange of + // range. if (sym.extent.Valid()) - if (auto range1 = GetLsRange(wfile, sym.extent)) + if (auto range1 = GetLsRange(wfile, sym.extent); + range1 && range1->start <= range->start && + range->end <= range1->end) ds->range = *range1; } std::vector def_ptrs; @@ -187,7 +202,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, if (!def) return; ds->name = def->Name(false); - ds->detail = def->Name(true); + ds->detail = def->detailed_name; for (auto &def : entity.def) if (def.file_id == file_id && !Ignore(&def)) { ds->kind = def.kind; @@ -196,6 +211,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, } }); if (!(param.all || sym.role & Role::Definition || + ds->kind == SymbolKind::Function || ds->kind == SymbolKind::Method || ds->kind == SymbolKind::Namespace)) { ds.reset(); @@ -237,8 +253,11 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, } std::vector> result; for (auto &[_, ds] : sym2ds) - if (ds) + if (ds) { + Uniquify(ds->children); result.push_back(std::move(ds)); + } + Uniquify(result); reply(result); } else { std::vector result; From 8c73bbc3c721afe1e0f6f6e27b588579a857e001 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 17 Nov 2018 10:23:12 -0800 Subject: [PATCH 295/378] Use clang::isIdentifierBody and clean up utils/working_files --- src/clang_tu.cc | 2 +- src/include_complete.cc | 13 ++++- src/indexer.cc | 11 ++-- src/pipeline.cc | 2 +- src/project.cc | 2 +- src/serializer.cc | 2 +- src/test.cc | 56 ++++++++++-------- src/utils.cc | 47 +-------------- src/utils.hh | 11 ---- src/working_files.cc | 124 +++++++--------------------------------- src/working_files.hh | 27 ++------- 11 files changed, 76 insertions(+), 221 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 5a87153a1..e6fe3ef92 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -32,7 +32,7 @@ std::string PathFromFileEntry(const FileEntry &file) { std::string ret = NormalizePath(Name); // Resolve /usr/include/c++/7.3.0 symlink. if (!llvm::any_of(g_config->workspaceFolders, [&](const std::string &root) { - return StartsWith(ret, root); + return StringRef(ret).startswith(root); })) { SmallString<256> dest; llvm::sys::fs::real_path(ret, dest); diff --git a/src/include_complete.cc b/src/include_complete.cc index fab2279bd..7f2933361 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -156,7 +156,11 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, } void IncludeComplete::AddFile(const std::string &path) { - if (!EndsWithAny(path, g_config->completion.include.suffixWhitelist)) + bool ok = false; + for (StringRef suffix : g_config->completion.include.suffixWhitelist) + if (StringRef(path).endswith(suffix)) + ok = true; + if (!ok) return; if (match_ && !match_->IsMatch(path)) return; @@ -183,8 +187,11 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, GetFilesInFolder( directory, true /*recursive*/, false /*add_folder_to_path*/, [&](const std::string &path) { - if (!include_cpp && - !EndsWithAny(path, g_config->completion.include.suffixWhitelist)) + bool ok = include_cpp; + for (StringRef suffix : g_config->completion.include.suffixWhitelist) + if (StringRef(path).endswith(suffix)) + ok = true; + if (!ok) return; if (match_ && !match_->IsMatch(directory + path)) return; diff --git a/src/indexer.cc b/src/indexer.cc index f980ad628..203b463ca 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -451,11 +451,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { } while (ret.size() && isspace(ret.back())) ret.pop_back(); - if (EndsWith(ret, "*/")) { + if (StringRef(ret).endswith("*/")) ret.resize(ret.size() - 2); - } else if (EndsWith(ret, "\n/")) { + else if (StringRef(ret).endswith("\n/")) ret.resize(ret.size() - 2); - } while (ret.size() && isspace(ret.back())) ret.pop_back(); return ret; @@ -521,8 +520,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { } auto i = name.find(short_name); if (short_name.size()) - while (i != std::string::npos && ((i && isalnum(name[i - 1])) || - isalnum(name[i + short_name.size()]))) + while (i != std::string::npos && ((i && isIdentifierBody(name[i - 1])) || + isIdentifierBody(name[i + short_name.size()]))) i = name.find(short_name, i + short_name.size()); if (i == std::string::npos) { // e.g. operator type-parameter-1 @@ -541,7 +540,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { paren++; else if (name[i - 1] == '(') paren--; - else if (!(paren > 0 || isalnum(name[i - 1]) || name[i - 1] == '_' || + else if (!(paren > 0 || isIdentifierBody(name[i - 1]) || name[i - 1] == ':')) break; } diff --git a/src/pipeline.cc b/src/pipeline.cc index 5baab1c06..054584ac9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -141,7 +141,7 @@ std::string AppendSerializationFormat(const std::string &base) { std::string GetCachePath(const std::string &source_file) { for (auto &root : g_config->workspaceFolders) - if (StartsWith(source_file, root)) { + if (StringRef(source_file).startswith(root)) { auto len = root.size(); return g_config->cacheDirectory + EscapeFileName(root.substr(0, len - 1)) + '/' + diff --git a/src/project.cc b/src/project.cc index 8ea716430..f899ec75e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -447,7 +447,7 @@ Project::Entry Project::FindEntry(const std::string &path, best_entry = &entry; } } - if (StartsWith(path, root)) + if (StringRef(path).startswith(root)) result.root = root; } if (result.root.empty()) diff --git a/src/serializer.cc b/src/serializer.cc index 3c152ebc2..97af72719 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -213,7 +213,7 @@ void Reflect(Writer &visitor, IndexInclude &value) { REFLECT_MEMBER(line); if (gTestOutputMode) { std::string basename = llvm::sys::path::filename(value.resolved_path); - if (!StartsWith(value.resolved_path, "&")) + if (value.resolved_path[0] != '&') basename = "&" + basename; REFLECT_MEMBER2("resolved_path", basename); } else { diff --git a/src/test.cc b/src/test.cc index 44ebe7e1d..491833398 100644 --- a/src/test.cc +++ b/src/test.cc @@ -25,7 +25,6 @@ limitations under the License. #include #include -using namespace llvm; #include #include @@ -42,6 +41,8 @@ using namespace llvm; #include #endif +using namespace llvm; + extern bool gTestOutputMode; namespace ccls { @@ -90,6 +91,24 @@ void TrimInPlace(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end()); } +std::vector SplitString(const std::string &str, + const std::string &delimiter) { + // http://stackoverflow.com/a/13172514 + std::vector strings; + + std::string::size_type pos = 0; + std::string::size_type prev = 0; + while ((pos = str.find(delimiter, prev)) != std::string::npos) { + strings.push_back(str.substr(prev, pos - prev)); + prev = pos + 1; + } + + // To get the last substring (or only, if delimiter is not found) + strings.push_back(str.substr(prev)); + + return strings; +} + void ParseTestExpectation( const std::string &filename, const std::vector &lines_with_endings, TextReplacer *replacer, @@ -98,10 +117,10 @@ void ParseTestExpectation( // Scan for EXTRA_FLAGS: { bool in_output = false; - for (std::string line : lines_with_endings) { - line = StringRef(line).trim().str(); + for (StringRef line : lines_with_endings) { + line = line.trim(); - if (StartsWith(line, "EXTRA_FLAGS:")) { + if (line.startswith("EXTRA_FLAGS:")) { assert(!in_output && "multiple EXTRA_FLAGS sections"); in_output = true; continue; @@ -111,7 +130,7 @@ void ParseTestExpectation( break; if (in_output) - flags->push_back(line); + flags->push_back(line.str()); } } @@ -121,11 +140,11 @@ void ParseTestExpectation( std::string active_output_contents; bool in_output = false; - for (std::string line_with_ending : lines_with_endings) { - if (StartsWith(line_with_ending, "*/")) + for (StringRef line_with_ending : lines_with_endings) { + if (line_with_ending.startswith("*/")) break; - if (StartsWith(line_with_ending, "OUTPUT:")) { + if (line_with_ending.startswith("OUTPUT:")) { // Terminate the previous output section if we found a new one. if (in_output) { (*output_sections)[active_output_filename] = active_output_contents; @@ -133,9 +152,10 @@ void ParseTestExpectation( // Try to tokenize OUTPUT: based one whitespace. If there is more than // one token assume it is a filename. - std::vector tokens = SplitString(line_with_ending, " "); + SmallVector tokens; + line_with_ending.split(tokens, ' '); if (tokens.size() > 1) { - active_output_filename = StringRef(tokens[1]).trim().str(); + active_output_filename = tokens[1].str(); } else { active_output_filename = filename; } @@ -229,7 +249,7 @@ std::string FindExpectedOutputForFilename( std::string filename, const std::unordered_map &expected) { for (const auto &entry : expected) { - if (EndsWith(entry.first, filename)) + if (StringRef(entry.first).endswith(filename)) return entry.second; } @@ -243,7 +263,7 @@ IndexFile * FindDbForPathEnding(const std::string &path, const std::vector> &dbs) { for (auto &db : dbs) { - if (EndsWith(db->path, path)) + if (StringRef(db->path).endswith(path)) return db.get(); } return nullptr; @@ -276,18 +296,6 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { [&](const std::string &path) { bool is_fail_allowed = false; - if (EndsWithAny(path, {".m", ".mm"})) { -#ifndef __APPLE__ - return; -#endif - - // objective-c tests are often not updated right away. do not bring - // down - // CI if they fail. - if (!enable_update) - is_fail_allowed = true; - } - if (path.find(filter_path) == std::string::npos) return; diff --git a/src/utils.cc b/src/utils.cc index 8e2eb4d62..3100c32d9 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -34,7 +34,7 @@ using namespace llvm; #include namespace ccls { -uint64_t HashUsr(std::string_view s) { +uint64_t HashUsr(llvm::StringRef s) { union { uint64_t ret; uint8_t out[8]; @@ -47,51 +47,6 @@ uint64_t HashUsr(std::string_view s) { return ret; } -uint64_t HashUsr(llvm::StringRef s) { - return HashUsr(std::string_view(s.data(), s.size())); -} - -bool EndsWith(std::string_view s, std::string_view suffix) { - return s.size() >= suffix.size() && - std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); -} - -bool StartsWith(std::string_view s, std::string_view prefix) { - return s.size() >= prefix.size() && - std::equal(prefix.begin(), prefix.end(), s.begin()); -} - -bool EndsWithAny(std::string_view s, const std::vector &ss) { - return std::any_of(ss.begin(), ss.end(), - std::bind(EndsWith, s, std::placeholders::_1)); -} - -bool FindAnyPartial(const std::string &value, - const std::vector &values) { - return std::any_of(std::begin(values), std::end(values), - [&value](const std::string &v) { - return value.find(v) != std::string::npos; - }); -} - -std::vector SplitString(const std::string &str, - const std::string &delimiter) { - // http://stackoverflow.com/a/13172514 - std::vector strings; - - std::string::size_type pos = 0; - std::string::size_type prev = 0; - while ((pos = str.find(delimiter, prev)) != std::string::npos) { - strings.push_back(str.substr(prev, pos - prev)); - prev = pos + 1; - } - - // To get the last substring (or only, if delimiter is not found) - strings.push_back(str.substr(prev)); - - return strings; -} - std::string LowerPathIfInsensitive(const std::string &path) { #if defined(_WIN32) std::string ret = path; diff --git a/src/utils.hh b/src/utils.hh index 1bf9ed372..1c00b2a61 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -27,19 +27,8 @@ class StringRef; } namespace ccls { -uint64_t HashUsr(std::string_view s); uint64_t HashUsr(llvm::StringRef s); -// Returns true if |value| starts/ends with |start| or |ending|. -bool StartsWith(std::string_view value, std::string_view start); -bool EndsWith(std::string_view value, std::string_view ending); -bool EndsWithAny(std::string_view s, const std::vector &ss); -bool FindAnyPartial(const std::string &value, - const std::vector &values); - -std::vector SplitString(const std::string &str, - const std::string &delimiter); - std::string LowerPathIfInsensitive(const std::string &path); // Ensures that |path| ends in a slash. diff --git a/src/working_files.cc b/src/working_files.cc index 6c7ac4632..48004e9c1 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -18,11 +18,16 @@ limitations under the License. #include "log.hh" #include "position.hh" +#include + #include #include #include #include +using namespace clang; +using namespace llvm; + namespace ccls { namespace { @@ -248,7 +253,7 @@ void WorkingFile::ComputeLineMapping() { // For index line i, set index_to_buffer[i] to -1 if line i is duplicated. int i = 0; - for (auto &line : index_lines) { + for (StringRef line : index_lines) { uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { @@ -265,7 +270,7 @@ void WorkingFile::ComputeLineMapping() { // For buffer line i, set buffer_to_index[i] to -1 if line i is duplicated. i = 0; hash_to_unique.clear(); - for (auto &line : buffer_lines) { + for (StringRef line : buffer_lines) { uint64_t h = HashUsr(line); auto it = hash_to_unique.find(h); if (it == hash_to_unique.end()) { @@ -341,80 +346,22 @@ std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int *column, index_lines, is_end); } -std::string -WorkingFile::FindClosestCallNameInBuffer(Position position, - int *active_parameter, - Position *completion_position) const { - *active_parameter = 0; - - int offset = GetOffsetForPosition(position, buffer_content); - - // If vscode auto-inserts closing ')' we will begin on ')' token in foo() - // which will make the below algorithm think it's a nested call. - if (offset > 0 && buffer_content[offset] == ')') - --offset; - - // Scan back out of call context. - int balance = 0; - while (offset > 0) { - char c = buffer_content[offset]; - if (c == ')') - ++balance; - else if (c == '(') - --balance; - - if (balance == 0 && c == ',') - *active_parameter += 1; - - --offset; - - if (balance == -1) - break; - } - - if (offset < 0) - return ""; - - // Scan back entire identifier. - int start_offset = offset; - while (offset > 0) { - char c = buffer_content[offset - 1]; - if (isalnum(c) == false && c != '_') - break; - --offset; - } - - if (completion_position) - *completion_position = GetPositionForOffset(buffer_content, offset); - - return buffer_content.substr(offset, start_offset - offset + 1); -} - Position WorkingFile::FindStableCompletionSource(Position position, std::string *existing_completion, Position *replace_end_pos) const { - int start_offset = GetOffsetForPosition(position, buffer_content); - int offset = start_offset; - - while (offset > 0) { - char c = buffer_content[offset - 1]; - if (!isalnum(c) && c != '_') - break; - --offset; - } + int start = GetOffsetForPosition(position, buffer_content); + int i = start; + while (i > 0 && isIdentifierBody(buffer_content[i - 1])) + --i; *replace_end_pos = position; - for (int i = start_offset; i < buffer_content.size(); i++) { - char c = buffer_content[i]; - if (!isalnum(c) && c != '_') - break; - // We know that replace_end_pos and position are on the same line. + for (int i = start; + i < buffer_content.size() && isIdentifierBody(buffer_content[i]); i++) replace_end_pos->character++; - } - *existing_completion = buffer_content.substr(offset, start_offset - offset); - return GetPositionForOffset(buffer_content, offset); + *existing_completion = buffer_content.substr(i, start - i); + return GetPositionForOffset(buffer_content, i); } WorkingFile *WorkingFiles::GetFileByFilename(const std::string &filename) { @@ -439,19 +386,6 @@ std::string WorkingFiles::GetContent(const std::string &filename) { return ""; } -void WorkingFiles::DoAction(const std::function &action) { - std::lock_guard lock(files_mutex); - action(); -} - -void WorkingFiles::DoActionOnFile( - const std::string &filename, - const std::function &action) { - std::lock_guard lock(files_mutex); - WorkingFile *file = GetFileByFilenameNoLock(filename); - action(file); -} - WorkingFile *WorkingFiles::OnOpen(const TextDocumentItem &open) { std::lock_guard lock(files_mutex); @@ -522,19 +456,6 @@ void WorkingFiles::OnClose(const TextDocumentIdentifier &close) { << " because it was not open"; } -WorkingFiles::Snapshot -WorkingFiles::AsSnapshot(const std::vector &filter_paths) { - std::lock_guard lock(files_mutex); - - Snapshot result; - result.files.reserve(files.size()); - for (const auto &file : files) { - if (filter_paths.empty() || FindAnyPartial(file->filename, filter_paths)) - result.files.push_back({file->filename, file->buffer_content}); - } - return result; -} - // VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent // text documents. // We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). @@ -557,24 +478,19 @@ int GetOffsetForPosition(Position pos, std::string_view content) { std::string_view LexIdentifierAroundPos(Position position, std::string_view content) { - int start = GetOffsetForPosition(position, content); - int end = start + 1; + int start = GetOffsetForPosition(position, content), end = start + 1; char c; // We search for :: before the cursor but not after to get the qualifier. for (; start > 0; start--) { c = content[start - 1]; - if (isalnum(c) || c == '_') - ; - else if (c == ':' && start > 1 && content[start - 2] == ':') + if (c == ':' && start > 1 && content[start - 2] == ':') start--; - else + else if (!isIdentifierBody(c)) break; } - - for (; end < (int)content.size(); end++) - if (c = content[end], !(isalnum(c) || c == '_')) - break; + for (; end < content.size() && isIdentifierBody(content[end]); end++) + ; return content.substr(start, end - start); } diff --git a/src/working_files.hh b/src/working_files.hh index f0df1c6fe..95cdf957d 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -62,19 +62,6 @@ struct WorkingFile { // Also resolves |column| if not NULL. std::optional GetIndexPosFromBufferPos(int line, int *column, bool is_end); - - // TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into - // lex_utils.h/cc - - // Finds the closest 'callable' name prior to position. This is used for - // signature help to filter code completion results. - // - // |completion_position| will be point to a good code completion location to - // for fetching signatures. - std::string - FindClosestCallNameInBuffer(Position position, int *active_parameter, - Position *completion_position = nullptr) const; - // Returns a relatively stable completion position (it jumps back until there // is a non-alphanumeric character). // @@ -111,21 +98,15 @@ struct WorkingFiles { std::string GetContent(const std::string &filename); // Run |action| under the lock. - void DoAction(const std::function &action); - // Run |action| on the file identified by |filename|. This executes under the - // lock. - void DoActionOnFile(const std::string &filename, - const std::function &action); + template void DoAction(Fn &&fn) { + std::lock_guard lock(files_mutex); + fn(); + } WorkingFile *OnOpen(const TextDocumentItem &open); void OnChange(const TextDocumentDidChangeParam &change); void OnClose(const TextDocumentIdentifier &close); - // If |filter_paths| is non-empty, only files which contain any of the given - // strings. For example, {"foo", "bar"} means that every result has either the - // string "foo" or "bar" contained within it. - Snapshot AsSnapshot(const std::vector &filter_paths); - // Use unique_ptrs so we can handout WorkingFile ptrs and not have them // invalidated if we resize files. std::vector> files; From afa654f0d19180bf7c99e153d26d80225f39d0d3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 19 Nov 2018 23:14:49 -0800 Subject: [PATCH 296/378] .ccls: add %objective-c %objective-cpp Also allow multiple directives on a line, e.g. %c %cpp -DFOO --- src/project.cc | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/project.cc b/src/project.cc index f899ec75e..eee0d774d 100644 --- a/src/project.cc +++ b/src/project.cc @@ -102,15 +102,24 @@ struct ProjectProcessor { args.reserve(entry.args.size() + g_config->clang.extraArgs.size() + 1); const LanguageId lang = lookupExtension(entry.filename).first; for (const char *arg : entry.args) { - if (strncmp(arg, "%c ", 3) == 0) { - if (lang == LanguageId::C) - args.push_back(arg + 3); - } else if (strncmp(arg, "%cpp ", 5) == 0) { - if (lang == LanguageId::Cpp) - args.push_back(arg + 5); - } else if (strcmp(arg, "%clang") == 0) { - args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); - } else if (!excludeArgs.count(arg)) { + StringRef A(arg); + if (A[0] == '%') { + bool ok = false; + for (;;) { + if (A.consume_front("%c ")) + ok |= lang == LanguageId::C; + else if (A.consume_front("%cpp ")) + ok |= lang == LanguageId::Cpp; + else if (A.consume_front("%objective-c ")) + ok |= lang == LanguageId::ObjC; + else if (A.consume_front("%objective-cpp ")) + ok |= lang == LanguageId::ObjCpp; + else + break; + } + if (ok) + args.push_back(A.data()); + } else if (!excludeArgs.count(A)) { args.push_back(arg); } } From f6fca760889014469a2cbddc3796ed285db0e248 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 22 Nov 2018 20:07:39 -0800 Subject: [PATCH 297/378] indexer: handle DecltypeType and empty main file; diag: -Wno-unused-function for headers Don't replace name with qualified name in Cls::*name --- src/clang_complete.cc | 3 +++ src/indexer.cc | 31 ++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 393cbcd40..f310180da 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -481,6 +481,9 @@ void *DiagnosticMain(void *manager_) { BuildCompilerInvocation(session->file.args, FS); if (!CI) continue; + // If main file is a header, add -Wno-unused-function + if (lookupExtension(session->file.filename).second) + CI->getDiagnosticOpts().Warnings.push_back("no-unused-function"); CI->getDiagnosticOpts().IgnoreWarnings = false; CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; StoreDiags DC(path); diff --git a/src/indexer.cc b/src/indexer.cc index 203b463ca..db0d56eb8 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -527,11 +527,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { // e.g. operator type-parameter-1 i = 0; def.short_name_offset = 0; - } else if (short_name.size() && (!i || name[i - 1] != ':')) { + } else if (short_name.empty() || (i >= 2 && name[i - 2] == ':')) { + // Don't replace name with qualified name in ns::name Cls::*name + def.short_name_offset = i; + } else { name.replace(i, short_name.size(), qualified); def.short_name_offset = i + qualified.size() - short_name.size(); - } else { - def.short_name_offset = i; } def.short_name_size = short_name.size(); for (int paren = 0; i; i--) { @@ -552,7 +553,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { std::string_view qualified, IndexVar::Def &def) { QualType T; const Expr *init = nullptr; - bool binding = false; + bool deduced = false; if (auto *VD = dyn_cast(D)) { T = VD->getType(); init = VD->getAnyInitializer(); @@ -562,9 +563,21 @@ class IndexDataConsumer : public index::IndexDataConsumer { init = FD->getInClassInitializer(); } else if (auto *BD = dyn_cast(D)) { T = BD->getType(); - binding = true; + deduced = true; } - if (!T.isNull() && (binding || T->getContainedDeducedType())) { + if (!T.isNull()) { + if (T->getContainedDeducedType()) { + deduced = true; + } else if (auto *DT = dyn_cast(T)) { + // decltype(y) x; + while (DT && !DT->getUnderlyingType().isNull()) { + T = DT->getUnderlyingType(); + DT = dyn_cast(T); + } + deduced = true; + } + } + if (!T.isNull() && deduced) { SmallString<256> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP = GetDefaultPolicy(); @@ -671,7 +684,11 @@ class IndexDataConsumer : public index::IndexDataConsumer { public: IndexDataConsumer(IndexParam ¶m) : param(param) {} - void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; } + void initialize(ASTContext &Ctx) override { + this->Ctx = param.Ctx = &Ctx; + SourceManager &SM = Ctx.getSourceManager(); + (void)param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID())); + } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, #if LLVM_VERSION_MAJOR >= 7 From 58e996366d7c5dffcdaa915f8cf3b0714a0cfa44 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 23 Nov 2018 10:08:44 -0800 Subject: [PATCH 298/378] Refactor ReplyOnce; error if InitializeParams.rootUri is null --- src/lsp.hh | 7 ------- src/message_handler.cc | 28 +++++++------------------ src/message_handler.hh | 9 +++----- src/messages/ccls_call.cc | 6 ++---- src/messages/ccls_inheritance.cc | 6 ++---- src/messages/ccls_member.cc | 6 ++---- src/messages/initialize.cc | 12 +++++------ src/messages/textDocument_formatting.cc | 14 +++++-------- 8 files changed, 27 insertions(+), 61 deletions(-) diff --git a/src/lsp.hh b/src/lsp.hh index b6a60877a..2c4c735fd 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -62,15 +62,8 @@ enum class ErrorCode { }; struct ResponseError { - // A number indicating the error type that occurred. ErrorCode code; - - // A string providing a short description of the error. std::string message; - - // A Primitive or Structured value that contains additional - // information about the error. Can be omitted. - // std::optional data; }; constexpr char ccls_xref[] = "ccls.xref"; diff --git a/src/message_handler.cc b/src/message_handler.cc index 969c691b5..c9ff275dd 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -207,21 +207,13 @@ void MessageHandler::Run(InMessage &msg) { try { it->second(reader, reply); } catch (std::invalid_argument &ex) { - ResponseError err; - err.code = ErrorCode::InvalidParams; - err.message = "invalid params of " + msg.method + ": " + ex.what(); - reply.Error(err); + reply.Error(ErrorCode::InvalidParams, + "invalid params of " + msg.method + ": " + ex.what()); } catch (...) { - ResponseError err; - err.code = ErrorCode::InternalError; - err.message = "failed to process " + msg.method; - reply.Error(err); + reply.Error(ErrorCode::InternalError, "failed to process " + msg.method); } } else { - ResponseError err; - err.code = ErrorCode::MethodNotFound; - err.message = "unknown request " + msg.method; - reply.Error(err); + reply.Error(ErrorCode::MethodNotFound, "unknown request " + msg.method); } } else { auto it = method2notification.find(msg.method); @@ -260,14 +252,10 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply, has_entry |= folder.path2entry_index.count(path); } ResponseError err; - if (has_entry) { - err.code = ErrorCode::ServerNotInitialized; - err.message = path + " is being indexed"; - } else { - err.code = ErrorCode::InternalError; - err.message = "unable to find " + path; - } - reply.Error(err); + if (has_entry) + reply.Error(ErrorCode::ServerNotInitialized, path + " is being indexed"); + else + reply.Error(ErrorCode::InternalError, "unable to find " + path); } return ret; diff --git a/src/message_handler.hh b/src/message_handler.hh index bac8b1b9b..ed2ab1366 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -194,17 +194,14 @@ MAKE_REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); MAKE_REFLECT_STRUCT(ShowMessageParam, type, message); MAKE_REFLECT_TYPE_PROXY(LanguageId); -// TODO llvm 8 llvm::unique_function -template -using Callback = std::function; - struct ReplyOnce { RequestId id; - template void operator()(Res &result) const { + template void operator()(Res &&result) const { if (id.Valid()) pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); }); } - template void Error(Err &err) const { + void Error(ErrorCode code, std::string message) const { + ResponseError err{code, std::move(message)}; if (id.Valid()) pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); }); } diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index babf849c1..1b0b9f76f 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -216,9 +216,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { if (param.hierarchy) reply(result); - else { - auto out = FlattenHierarchy(result); - reply(out); - } + else + reply(FlattenHierarchy(result)); } } // namespace ccls diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 558d537b5..d2f65258d 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -161,10 +161,8 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { if (param.hierarchy) reply(result); - else { - auto out = FlattenHierarchy(result); - reply(out); - } + else + reply(FlattenHierarchy(result)); } } // namespace diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index fd7d2c4a4..87fd58cdb 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -309,9 +309,7 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { if (param.hierarchy) reply(result); - else { - auto out = FlattenHierarchy(result); - reply(out); - } + else + reply(FlattenHierarchy(result)); } } // namespace ccls diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 7c93511eb..cfea3b3e8 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -292,10 +292,7 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { // Send initialization before starting indexers, so we don't send a // status update too early. - { - InitializeResult result; - reply(result); - } + reply(InitializeResult{}); // Set project root. EnsureEndsInSlash(project_path); @@ -342,8 +339,10 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { InitializeParam param; Reflect(reader, param); - if (!param.rootUri) + if (!param.rootUri) { + reply.Error(ErrorCode::InvalidRequest, "expected rootUri"); return; + } Initialize(this, param, reply); } @@ -355,8 +354,7 @@ void StandaloneInitialize(MessageHandler &handler, const std::string &root) { } void MessageHandler::shutdown(EmptyParam &, ReplyOnce &reply) { - JsonNull result; - reply(result); + reply(JsonNull{}); } void MessageHandler::exit(EmptyParam &) { diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 211eac78e..271d1a1d1 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -70,15 +70,11 @@ std::vector ReplacementsToEdits(std::string_view code, void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { std::string_view code = wfile->buffer_content; auto ReplsOrErr = FormatCode(code, wfile->filename, range); - if (ReplsOrErr) { - auto result = ReplacementsToEdits(code, *ReplsOrErr); - reply(result); - } else { - ResponseError err; - err.code = ErrorCode::UnknownErrorCode; - err.message = llvm::toString(ReplsOrErr.takeError()); - reply.Error(err); - } + if (ReplsOrErr) + reply(ReplacementsToEdits(code, *ReplsOrErr)); + else + reply.Error(ErrorCode::UnknownErrorCode, + llvm::toString(ReplsOrErr.takeError())); } } // namespace From 3bcb5f23a40d5ae377f8d481db4e22a533a92cfa Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 23 Nov 2018 11:53:21 -0800 Subject: [PATCH 299/378] serializer: make visitor/vis value/v consistent --- src/messages/textDocument_hover.cc | 6 +- src/serializer.cc | 274 ++++++++++++++--------------- src/serializer.hh | 172 +++++++++--------- 3 files changed, 224 insertions(+), 228 deletions(-) diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 3fdce20a0..c2666a1f9 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -27,16 +27,16 @@ struct Hover { std::optional range; }; -void Reflect(Writer &visitor, MarkedString &value) { +void Reflect(Writer &vis, MarkedString &v) { // If there is a language, emit a `{language:string, value:string}` object. If // not, emit a string. - if (value.language) { + if (v.language) { REFLECT_MEMBER_START(); REFLECT_MEMBER(language); REFLECT_MEMBER(value); REFLECT_MEMBER_END(); } else { - Reflect(visitor, value.value); + Reflect(vis, v.value); } } MAKE_REFLECT_STRUCT(Hover, contents, range); diff --git a/src/serializer.cc b/src/serializer.cc index 97af72719..11c751979 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -41,96 +41,94 @@ Writer::~Writer() {} BinaryWriter::~BinaryWriter() {} JsonWriter::~JsonWriter() {} -void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); } -void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); } +void Reflect(Reader &vis, uint8_t &v) { v = vis.GetUInt8(); } +void Reflect(Writer &vis, uint8_t &v) { vis.UInt8(v); } -void Reflect(Reader &visitor, short &value) { - if (!visitor.IsInt()) +void Reflect(Reader &vis, short &v) { + if (!vis.IsInt()) throw std::invalid_argument("short"); - value = (short)visitor.GetInt(); + v = (short)vis.GetInt(); } -void Reflect(Writer &visitor, short &value) { visitor.Int(value); } +void Reflect(Writer &vis, short &v) { vis.Int(v); } -void Reflect(Reader &visitor, unsigned short &value) { - if (!visitor.IsInt()) +void Reflect(Reader &vis, unsigned short &v) { + if (!vis.IsInt()) throw std::invalid_argument("unsigned short"); - value = (unsigned short)visitor.GetInt(); + v = (unsigned short)vis.GetInt(); } -void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); } +void Reflect(Writer &vis, unsigned short &v) { vis.Int(v); } -void Reflect(Reader &visitor, int &value) { - if (!visitor.IsInt()) +void Reflect(Reader &vis, int &v) { + if (!vis.IsInt()) throw std::invalid_argument("int"); - value = visitor.GetInt(); + v = vis.GetInt(); } -void Reflect(Writer &visitor, int &value) { visitor.Int(value); } +void Reflect(Writer &vis, int &v) { vis.Int(v); } -void Reflect(Reader &visitor, unsigned &value) { - if (!visitor.IsUInt64()) +void Reflect(Reader &vis, unsigned &v) { + if (!vis.IsUInt64()) throw std::invalid_argument("unsigned"); - value = visitor.GetUInt32(); + v = vis.GetUInt32(); } -void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); } +void Reflect(Writer &vis, unsigned &v) { vis.UInt32(v); } -void Reflect(Reader &visitor, long &value) { - if (!visitor.IsInt64()) +void Reflect(Reader &vis, long &v) { + if (!vis.IsInt64()) throw std::invalid_argument("long"); - value = long(visitor.GetInt64()); + v = long(vis.GetInt64()); } -void Reflect(Writer &visitor, long &value) { visitor.Int64(value); } +void Reflect(Writer &vis, long &v) { vis.Int64(v); } -void Reflect(Reader &visitor, unsigned long &value) { - if (!visitor.IsUInt64()) +void Reflect(Reader &vis, unsigned long &v) { + if (!vis.IsUInt64()) throw std::invalid_argument("unsigned long"); - value = (unsigned long)visitor.GetUInt64(); + v = (unsigned long)vis.GetUInt64(); } -void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); } +void Reflect(Writer &vis, unsigned long &v) { vis.UInt64(v); } -void Reflect(Reader &visitor, long long &value) { - if (!visitor.IsInt64()) +void Reflect(Reader &vis, long long &v) { + if (!vis.IsInt64()) throw std::invalid_argument("long long"); - value = visitor.GetInt64(); + v = vis.GetInt64(); } -void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); } +void Reflect(Writer &vis, long long &v) { vis.Int64(v); } -void Reflect(Reader &visitor, unsigned long long &value) { - if (!visitor.IsUInt64()) +void Reflect(Reader &vis, unsigned long long &v) { + if (!vis.IsUInt64()) throw std::invalid_argument("unsigned long long"); - value = visitor.GetUInt64(); -} -void Reflect(Writer &visitor, unsigned long long &value) { - visitor.UInt64(value); + v = vis.GetUInt64(); } +void Reflect(Writer &vis, unsigned long long &v) { vis.UInt64(v); } -void Reflect(Reader &visitor, double &value) { - if (!visitor.IsDouble()) +void Reflect(Reader &vis, double &v) { + if (!vis.IsDouble()) throw std::invalid_argument("double"); - value = visitor.GetDouble(); + v = vis.GetDouble(); } -void Reflect(Writer &visitor, double &value) { visitor.Double(value); } +void Reflect(Writer &vis, double &v) { vis.Double(v); } -void Reflect(Reader &visitor, bool &value) { - if (!visitor.IsBool()) +void Reflect(Reader &vis, bool &v) { + if (!vis.IsBool()) throw std::invalid_argument("bool"); - value = visitor.GetBool(); + v = vis.GetBool(); } -void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); } +void Reflect(Writer &vis, bool &v) { vis.Bool(v); } -void Reflect(Reader &visitor, std::string &value) { - if (!visitor.IsString()) +void Reflect(Reader &vis, std::string &v) { + if (!vis.IsString()) throw std::invalid_argument("std::string"); - value = visitor.GetString(); + v = vis.GetString(); } -void Reflect(Writer &visitor, std::string &value) { - visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); +void Reflect(Writer &vis, std::string &v) { + vis.String(v.c_str(), (rapidjson::SizeType)v.size()); } void Reflect(Reader &, std::string_view &) { assert(0); } -void Reflect(Writer &visitor, std::string_view &data) { +void Reflect(Writer &vis, std::string_view &data) { if (data.empty()) - visitor.String(""); + vis.String(""); else - visitor.String(&data[0], (rapidjson::SizeType)data.size()); + vis.String(&data[0], (rapidjson::SizeType)data.size()); } void Reflect(Reader &vis, const char *&v) { @@ -139,17 +137,17 @@ void Reflect(Reader &vis, const char *&v) { } void Reflect(Writer &vis, const char *&v) { vis.String(v); } -void Reflect(Reader &visitor, JsonNull &value) { - assert(visitor.Format() == SerializeFormat::Json); - visitor.GetNull(); +void Reflect(Reader &vis, JsonNull &v) { + assert(vis.Format() == SerializeFormat::Json); + vis.GetNull(); } -void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); } +void Reflect(Writer &vis, JsonNull &v) { vis.Null(); } // std::unordered_map template -void Reflect(Reader &visitor, std::unordered_map &map) { - visitor.IterArray([&](Reader &entry) { +void Reflect(Reader &vis, std::unordered_map &map) { + vis.IterArray([&](Reader &entry) { V val; Reflect(entry, val); auto usr = val.usr; @@ -157,14 +155,14 @@ void Reflect(Reader &visitor, std::unordered_map &map) { }); } template -void Reflect(Writer &visitor, std::unordered_map &map) { +void Reflect(Writer &vis, std::unordered_map &map) { std::vector> xs(map.begin(), map.end()); std::sort(xs.begin(), xs.end(), [](const auto &a, const auto &b) { return a.first < b.first; }); - visitor.StartArray(xs.size()); + vis.StartArray(xs.size()); for (auto &it : xs) - Reflect(visitor, it.second); - visitor.EndArray(); + Reflect(vis, it.second); + vis.EndArray(); } // Used by IndexFile::dependencies. @@ -202,18 +200,18 @@ void Reflect(Writer &vis, DenseMap &v) { } // TODO: Move this to indexer.cc -void Reflect(Reader &visitor, IndexInclude &value) { +void Reflect(Reader &vis, IndexInclude &v) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); REFLECT_MEMBER(resolved_path); REFLECT_MEMBER_END(); } -void Reflect(Writer &visitor, IndexInclude &value) { +void Reflect(Writer &vis, IndexInclude &v) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); if (gTestOutputMode) { - std::string basename = llvm::sys::path::filename(value.resolved_path); - if (value.resolved_path[0] != '&') + std::string basename = llvm::sys::path::filename(v.resolved_path); + if (v.resolved_path[0] != '&') basename = "&" + basename; REFLECT_MEMBER2("resolved_path", basename); } else { @@ -222,114 +220,112 @@ void Reflect(Writer &visitor, IndexInclude &value) { REFLECT_MEMBER_END(); } -template -void ReflectHoverAndComments(Reader &visitor, Def &def) { - ReflectMember(visitor, "hover", def.hover); - ReflectMember(visitor, "comments", def.comments); +template void ReflectHoverAndComments(Reader &vis, Def &def) { + ReflectMember(vis, "hover", def.hover); + ReflectMember(vis, "comments", def.comments); } -template -void ReflectHoverAndComments(Writer &visitor, Def &def) { +template void ReflectHoverAndComments(Writer &vis, Def &def) { // Don't emit empty hover and comments in JSON test mode. if (!gTestOutputMode || def.hover[0]) - ReflectMember(visitor, "hover", def.hover); + ReflectMember(vis, "hover", def.hover); if (!gTestOutputMode || def.comments[0]) - ReflectMember(visitor, "comments", def.comments); + ReflectMember(vis, "comments", def.comments); } -template void ReflectShortName(Reader &visitor, Def &def) { +template void ReflectShortName(Reader &vis, Def &def) { if (gTestOutputMode) { std::string short_name; - ReflectMember(visitor, "short_name", short_name); + ReflectMember(vis, "short_name", short_name); def.short_name_offset = std::string_view(def.detailed_name).find(short_name); assert(def.short_name_offset != std::string::npos); def.short_name_size = short_name.size(); } else { - ReflectMember(visitor, "short_name_offset", def.short_name_offset); - ReflectMember(visitor, "short_name_size", def.short_name_size); + ReflectMember(vis, "short_name_offset", def.short_name_offset); + ReflectMember(vis, "short_name_size", def.short_name_size); } } -template void ReflectShortName(Writer &visitor, Def &def) { +template void ReflectShortName(Writer &vis, Def &def) { if (gTestOutputMode) { std::string_view short_name(def.detailed_name + def.short_name_offset, def.short_name_size); - ReflectMember(visitor, "short_name", short_name); + ReflectMember(vis, "short_name", short_name); } else { - ReflectMember(visitor, "short_name_offset", def.short_name_offset); - ReflectMember(visitor, "short_name_size", def.short_name_size); + ReflectMember(vis, "short_name_offset", def.short_name_offset); + ReflectMember(vis, "short_name_size", def.short_name_size); } } -template void Reflect(TVisitor &visitor, IndexFunc &value) { +template void Reflect(TVisitor &vis, IndexFunc &v) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("usr", value.usr); - REFLECT_MEMBER2("detailed_name", value.def.detailed_name); - REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); - ReflectShortName(visitor, value.def); - REFLECT_MEMBER2("spell", value.def.spell); - ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("bases", value.def.bases); - REFLECT_MEMBER2("vars", value.def.vars); - REFLECT_MEMBER2("callees", value.def.callees); - REFLECT_MEMBER2("kind", value.def.kind); - REFLECT_MEMBER2("parent_kind", value.def.parent_kind); - REFLECT_MEMBER2("storage", value.def.storage); - - REFLECT_MEMBER2("declarations", value.declarations); - REFLECT_MEMBER2("derived", value.derived); - REFLECT_MEMBER2("uses", value.uses); + REFLECT_MEMBER2("usr", v.usr); + REFLECT_MEMBER2("detailed_name", v.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); + ReflectShortName(vis, v.def); + REFLECT_MEMBER2("spell", v.def.spell); + ReflectHoverAndComments(vis, v.def); + REFLECT_MEMBER2("bases", v.def.bases); + REFLECT_MEMBER2("vars", v.def.vars); + REFLECT_MEMBER2("callees", v.def.callees); + REFLECT_MEMBER2("kind", v.def.kind); + REFLECT_MEMBER2("parent_kind", v.def.parent_kind); + REFLECT_MEMBER2("storage", v.def.storage); + + REFLECT_MEMBER2("declarations", v.declarations); + REFLECT_MEMBER2("derived", v.derived); + REFLECT_MEMBER2("uses", v.uses); REFLECT_MEMBER_END(); } -template void Reflect(TVisitor &visitor, IndexType &value) { +template void Reflect(TVisitor &vis, IndexType &v) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("usr", value.usr); - REFLECT_MEMBER2("detailed_name", value.def.detailed_name); - REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); - ReflectShortName(visitor, value.def); - ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("spell", value.def.spell); - REFLECT_MEMBER2("bases", value.def.bases); - REFLECT_MEMBER2("funcs", value.def.funcs); - REFLECT_MEMBER2("types", value.def.types); - REFLECT_MEMBER2("vars", value.def.vars); - REFLECT_MEMBER2("alias_of", value.def.alias_of); - REFLECT_MEMBER2("kind", value.def.kind); - REFLECT_MEMBER2("parent_kind", value.def.parent_kind); - - REFLECT_MEMBER2("declarations", value.declarations); - REFLECT_MEMBER2("derived", value.derived); - REFLECT_MEMBER2("instances", value.instances); - REFLECT_MEMBER2("uses", value.uses); + REFLECT_MEMBER2("usr", v.usr); + REFLECT_MEMBER2("detailed_name", v.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); + ReflectShortName(vis, v.def); + ReflectHoverAndComments(vis, v.def); + REFLECT_MEMBER2("spell", v.def.spell); + REFLECT_MEMBER2("bases", v.def.bases); + REFLECT_MEMBER2("funcs", v.def.funcs); + REFLECT_MEMBER2("types", v.def.types); + REFLECT_MEMBER2("vars", v.def.vars); + REFLECT_MEMBER2("alias_of", v.def.alias_of); + REFLECT_MEMBER2("kind", v.def.kind); + REFLECT_MEMBER2("parent_kind", v.def.parent_kind); + + REFLECT_MEMBER2("declarations", v.declarations); + REFLECT_MEMBER2("derived", v.derived); + REFLECT_MEMBER2("instances", v.instances); + REFLECT_MEMBER2("uses", v.uses); REFLECT_MEMBER_END(); } -template void Reflect(TVisitor &visitor, IndexVar &value) { +template void Reflect(TVisitor &vis, IndexVar &v) { REFLECT_MEMBER_START(); - REFLECT_MEMBER2("usr", value.usr); - REFLECT_MEMBER2("detailed_name", value.def.detailed_name); - REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); - ReflectShortName(visitor, value.def); - ReflectHoverAndComments(visitor, value.def); - REFLECT_MEMBER2("spell", value.def.spell); - REFLECT_MEMBER2("type", value.def.type); - REFLECT_MEMBER2("kind", value.def.kind); - REFLECT_MEMBER2("parent_kind", value.def.parent_kind); - REFLECT_MEMBER2("storage", value.def.storage); - - REFLECT_MEMBER2("declarations", value.declarations); - REFLECT_MEMBER2("uses", value.uses); + REFLECT_MEMBER2("usr", v.usr); + REFLECT_MEMBER2("detailed_name", v.def.detailed_name); + REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); + ReflectShortName(vis, v.def); + ReflectHoverAndComments(vis, v.def); + REFLECT_MEMBER2("spell", v.def.spell); + REFLECT_MEMBER2("type", v.def.type); + REFLECT_MEMBER2("kind", v.def.kind); + REFLECT_MEMBER2("parent_kind", v.def.parent_kind); + REFLECT_MEMBER2("storage", v.def.storage); + + REFLECT_MEMBER2("declarations", v.declarations); + REFLECT_MEMBER2("uses", v.uses); REFLECT_MEMBER_END(); } // IndexFile -bool ReflectMemberStart(Writer &visitor, IndexFile &value) { - visitor.StartObject(); +bool ReflectMemberStart(Writer &vis, IndexFile &v) { + vis.StartObject(); return true; } -template void Reflect(TVisitor &visitor, IndexFile &value) { +template void Reflect(TVisitor &vis, IndexFile &v) { REFLECT_MEMBER_START(); if (!gTestOutputMode) { REFLECT_MEMBER(mtime); @@ -352,13 +348,13 @@ void Reflect(Reader &vis, SerializeFormat &v) { : SerializeFormat::Binary; } -void Reflect(Writer &visitor, SerializeFormat &value) { - switch (value) { +void Reflect(Writer &vis, SerializeFormat &v) { + switch (v) { case SerializeFormat::Binary: - visitor.String("binary"); + vis.String("binary"); break; case SerializeFormat::Json: - visitor.String("json"); + vis.String("json"); break; } } diff --git a/src/serializer.hh b/src/serializer.hh index 0cf25b092..b57dbfae4 100644 --- a/src/serializer.hh +++ b/src/serializer.hh @@ -94,34 +94,34 @@ public: struct IndexFile; -#define REFLECT_MEMBER_START() ReflectMemberStart(visitor) -#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor); -#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) -#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) +#define REFLECT_MEMBER_START() ReflectMemberStart(vis) +#define REFLECT_MEMBER_END() ReflectMemberEnd(vis); +#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name) +#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v) #define MAKE_REFLECT_TYPE_PROXY(type_name) \ MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) #define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &visitor, type &value) { \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &vis, type &v) { \ as_type value0; \ - ::ccls::Reflect(visitor, value0); \ - value = static_cast(value0); \ + ::ccls::Reflect(vis, value0); \ + v = static_cast(value0); \ } \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &visitor, type &value) { \ - auto value0 = static_cast(value); \ - ::ccls::Reflect(visitor, value0); \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &vis, type &v) { \ + auto value0 = static_cast(v); \ + ::ccls::Reflect(vis, value0); \ } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ - template void Reflect(TVisitor &visitor, type &value) { \ + template void Reflect(TVisitor &vis, type &v) { \ REFLECT_MEMBER_START(); \ REFLECT_MEMBER_END(); \ } #define MAKE_REFLECT_STRUCT(type, ...) \ - template void Reflect(TVisitor &visitor, type &value) { \ + template void Reflect(TVisitor &vis, type &v) { \ REFLECT_MEMBER_START(); \ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ REFLECT_MEMBER_END(); \ @@ -133,66 +133,66 @@ struct IndexFile; #define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) // clang-format on -#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name); +#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name); // Reflects the struct so it is serialized as an array instead of an object. // This currently only supports writers. #define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \ - inline void Reflect(Writer &visitor, type &value) { \ - visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ + inline void Reflect(Writer &vis, type &v) { \ + vis.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \ - visitor.EndArray(); \ + vis.EndArray(); \ } //// Elementary types -void Reflect(Reader &visitor, uint8_t &value); -void Reflect(Writer &visitor, uint8_t &value); +void Reflect(Reader &vis, uint8_t &v); +void Reflect(Writer &vis, uint8_t &v); -void Reflect(Reader &visitor, short &value); -void Reflect(Writer &visitor, short &value); +void Reflect(Reader &vis, short &v); +void Reflect(Writer &vis, short &v); -void Reflect(Reader &visitor, unsigned short &value); -void Reflect(Writer &visitor, unsigned short &value); +void Reflect(Reader &vis, unsigned short &v); +void Reflect(Writer &vis, unsigned short &v); -void Reflect(Reader &visitor, int &value); -void Reflect(Writer &visitor, int &value); +void Reflect(Reader &vis, int &v); +void Reflect(Writer &vis, int &v); -void Reflect(Reader &visitor, unsigned &value); -void Reflect(Writer &visitor, unsigned &value); +void Reflect(Reader &vis, unsigned &v); +void Reflect(Writer &vis, unsigned &v); -void Reflect(Reader &visitor, long &value); -void Reflect(Writer &visitor, long &value); +void Reflect(Reader &vis, long &v); +void Reflect(Writer &vis, long &v); -void Reflect(Reader &visitor, unsigned long &value); -void Reflect(Writer &visitor, unsigned long &value); +void Reflect(Reader &vis, unsigned long &v); +void Reflect(Writer &vis, unsigned long &v); -void Reflect(Reader &visitor, long long &value); -void Reflect(Writer &visitor, long long &value); +void Reflect(Reader &vis, long long &v); +void Reflect(Writer &vis, long long &v); -void Reflect(Reader &visitor, unsigned long long &value); -void Reflect(Writer &visitor, unsigned long long &value); +void Reflect(Reader &vis, unsigned long long &v); +void Reflect(Writer &vis, unsigned long long &v); -void Reflect(Reader &visitor, double &value); -void Reflect(Writer &visitor, double &value); +void Reflect(Reader &vis, double &v); +void Reflect(Writer &vis, double &v); -void Reflect(Reader &visitor, bool &value); -void Reflect(Writer &visitor, bool &value); +void Reflect(Reader &vis, bool &v); +void Reflect(Writer &vis, bool &v); -void Reflect(Reader &visitor, std::string &value); -void Reflect(Writer &visitor, std::string &value); +void Reflect(Reader &vis, std::string &v); +void Reflect(Writer &vis, std::string &v); -void Reflect(Reader &visitor, std::string_view &view); -void Reflect(Writer &visitor, std::string_view &view); +void Reflect(Reader &vis, std::string_view &v); +void Reflect(Writer &vis, std::string_view &v); void Reflect(Reader &vis, const char *&v); void Reflect(Writer &vis, const char *&v); -void Reflect(Reader &visitor, JsonNull &value); -void Reflect(Writer &visitor, JsonNull &value); +void Reflect(Reader &vis, JsonNull &v); +void Reflect(Writer &vis, JsonNull &v); -void Reflect(Reader &visitor, SerializeFormat &value); -void Reflect(Writer &visitor, SerializeFormat &value); +void Reflect(Reader &vis, SerializeFormat &v); +void Reflect(Writer &vis, SerializeFormat &v); //// Type constructors @@ -200,60 +200,60 @@ void Reflect(Writer &visitor, SerializeFormat &value); // properties (in `key: value` context). Reflect std::optional is used for a // different purpose, whether an object is nullable (possibly in `value` // context). -template void Reflect(Reader &visitor, std::optional &value) { - if (visitor.IsNull()) { - visitor.GetNull(); +template void Reflect(Reader &vis, std::optional &v) { + if (vis.IsNull()) { + vis.GetNull(); return; } - T real_value; - Reflect(visitor, real_value); - value = std::move(real_value); + T val; + Reflect(vis, val); + v = std::move(val); } -template void Reflect(Writer &visitor, std::optional &value) { - if (value) { - if (visitor.Format() != SerializeFormat::Json) - visitor.UInt8(1); - Reflect(visitor, *value); +template void Reflect(Writer &vis, std::optional &v) { + if (v) { + if (vis.Format() != SerializeFormat::Json) + vis.UInt8(1); + Reflect(vis, *v); } else - visitor.Null(); + vis.Null(); } // The same as std::optional -template void Reflect(Reader &visitor, Maybe &value) { - if (visitor.IsNull()) { - visitor.GetNull(); +template void Reflect(Reader &vis, Maybe &v) { + if (vis.IsNull()) { + vis.GetNull(); return; } - T real_value; - Reflect(visitor, real_value); - value = std::move(real_value); + T val; + Reflect(vis, val); + v = std::move(val); } -template void Reflect(Writer &visitor, Maybe &value) { - if (value) { - if (visitor.Format() != SerializeFormat::Json) - visitor.UInt8(1); - Reflect(visitor, *value); +template void Reflect(Writer &vis, Maybe &v) { + if (v) { + if (vis.Format() != SerializeFormat::Json) + vis.UInt8(1); + Reflect(vis, *v); } else - visitor.Null(); + vis.Null(); } template -void ReflectMember(Writer &visitor, const char *name, std::optional &value) { +void ReflectMember(Writer &vis, const char *name, std::optional &v) { // For TypeScript std::optional property key?: value in the spec, // We omit both key and value if value is std::nullopt (null) for JsonWriter // to reduce output. But keep it for other serialization formats. - if (value || visitor.Format() != SerializeFormat::Json) { - visitor.Key(name); - Reflect(visitor, value); + if (v || vis.Format() != SerializeFormat::Json) { + vis.Key(name); + Reflect(vis, v); } } // The same as std::optional template -void ReflectMember(Writer &visitor, const char *name, Maybe &value) { - if (value.Valid() || visitor.Format() != SerializeFormat::Json) { - visitor.Key(name); - Reflect(visitor, value); +void ReflectMember(Writer &vis, const char *name, Maybe &v) { + if (v.Valid() || vis.Format() != SerializeFormat::Json) { + vis.Key(name); + Reflect(vis, v); } } @@ -271,18 +271,18 @@ void Reflect(Writer &vis, std::pair &v) { } // std::vector -template void Reflect(Reader &visitor, std::vector &values) { - visitor.IterArray([&](Reader &entry) { +template void Reflect(Reader &vis, std::vector &vs) { + vis.IterArray([&](Reader &entry) { T entry_value; Reflect(entry, entry_value); - values.push_back(std::move(entry_value)); + vs.push_back(std::move(entry_value)); }); } -template void Reflect(Writer &visitor, std::vector &values) { - visitor.StartArray(values.size()); - for (auto &value : values) - Reflect(visitor, value); - visitor.EndArray(); +template void Reflect(Writer &vis, std::vector &vs) { + vis.StartArray(vs.size()); + for (auto &v : vs) + Reflect(vis, v); + vis.EndArray(); } // ReflectMember From 7a363d225970661f8e2a66fe63810d7c47f9319b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 23 Nov 2018 11:53:51 -0800 Subject: [PATCH 300/378] completion: delete insertText; don't set filterText if it is the same as label It decreases Content-Length: from 32K to 25K for the following case: #include int main() { std::| } Also * make results deterministic when completion text is empty * sort by newText, label, filterText --- src/message_handler.hh | 5 +- src/messages/textDocument_completion.cc | 86 ++++++++++++++----------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/message_handler.hh b/src/message_handler.hh index ed2ab1366..e5e078443 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -119,10 +119,9 @@ struct CompletionItem { std::string label; CompletionItemKind kind = CompletionItemKind::Text; std::string detail; - std::optional documentation; + std::string documentation; std::string sortText; - std::optional filterText; - std::string insertText; + std::string filterText; InsertTextFormat insertTextFormat = InsertTextFormat::PlainText; TextEdit textEdit; std::vector additionalTextEdits; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 5748b8bd2..bb6562981 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -34,9 +34,23 @@ using namespace llvm; MAKE_REFLECT_TYPE_PROXY(InsertTextFormat); MAKE_REFLECT_TYPE_PROXY(CompletionItemKind); -MAKE_REFLECT_STRUCT(CompletionItem, label, kind, detail, documentation, - sortText, filterText, insertText, insertTextFormat, - textEdit, additionalTextEdits); + +void Reflect(Writer &vis, CompletionItem &v) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(label); + REFLECT_MEMBER(kind); + REFLECT_MEMBER(detail); + if (v.documentation.size()) + REFLECT_MEMBER(documentation); + REFLECT_MEMBER(sortText); + if (v.filterText.size()) + REFLECT_MEMBER(filterText); + REFLECT_MEMBER(insertTextFormat); + REFLECT_MEMBER(textEdit); + if (v.additionalTextEdits.size()) + REFLECT_MEMBER(additionalTextEdits); + REFLECT_MEMBER_END(); +} namespace { struct CompletionList { @@ -67,7 +81,6 @@ void DecorateIncludePaths(const std::smatch &match, item.textEdit.newText = prefix + quote0 + item.textEdit.newText + quote1 + suffix; item.label = prefix + quote0 + item.label + quote1 + suffix; - item.filterText = std::nullopt; } } @@ -124,8 +137,8 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, std::string sort(4, ' '); for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; - if (has_open_paren && item.filterText) - item.textEdit.newText = *item.filterText; + if (has_open_paren) + item.textEdit.newText = item.filterText; // https://github.com/Microsoft/language-server-protocol/issues/543 // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; @@ -133,48 +146,44 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, Position start = edits[0].range.start, end = edits[0].range.end; item.textEdit.range.start = start; item.textEdit.newText = edits[0].newText + item.textEdit.newText; - if (start.line == begin_pos.line && item.filterText) { + if (start.line == begin_pos.line) { item.filterText = buffer_line.substr(start.character, end.character - start.character) + - *item.filterText; + item.filterText; } edits.erase(edits.begin()); } + if (item.filterText == item.label) + item.filterText.clear(); for (auto i = sort.size(); i && ++sort[i - 1] == 'A';) sort[--i] = ' '; item.sortText = sort; - // Compatibility - item.insertText = item.textEdit.newText; } }; - // No complete text; don't run any filtering logic except to trim the items. - if (!g_config->completion.filterAndSort || complete_text.empty()) { + if (!g_config->completion.filterAndSort) { finalize(); return; } - // Make sure all items have |filterText| set, code that follow needs it. - for (auto &item : items) { - if (!item.filterText) - item.filterText = item.label; - } - - // Fuzzy match and remove awful candidates. - bool sensitive = g_config->completion.caseSensitivity; - FuzzyMatcher fuzzy(complete_text, sensitive); - for (auto &item : items) { - item.score_ = - ReverseSubseqMatch(complete_text, *item.filterText, sensitive) >= 0 - ? fuzzy.Match(*item.filterText) - : FuzzyMatcher::kMinScore; + if (complete_text.size()) { + // Fuzzy match and remove awful candidates. + bool sensitive = g_config->completion.caseSensitivity; + FuzzyMatcher fuzzy(complete_text, sensitive); + for (CompletionItem &item : items) { + const std::string &filter = + item.filterText.size() ? item.filterText : item.label; + item.score_ = ReverseSubseqMatch(complete_text, filter, sensitive) >= 0 + ? fuzzy.Match(filter) + : FuzzyMatcher::kMinScore; + } + items.erase(std::remove_if(items.begin(), items.end(), + [](const CompletionItem &item) { + return item.score_ <= FuzzyMatcher::kMinScore; + }), + items.end()); } - items.erase(std::remove_if(items.begin(), items.end(), - [](const CompletionItem &item) { - return item.score_ <= FuzzyMatcher::kMinScore; - }), - items.end()); std::sort(items.begin(), items.end(), [](const CompletionItem &lhs, const CompletionItem &rhs) { int t = int(lhs.additionalTextEdits.size() - @@ -185,9 +194,13 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, return lhs.score_ > rhs.score_; if (lhs.priority_ != rhs.priority_) return lhs.priority_ < rhs.priority_; - if (lhs.filterText->size() != rhs.filterText->size()) - return lhs.filterText->size() < rhs.filterText->size(); - return *lhs.filterText < *rhs.filterText; + t = lhs.textEdit.newText.compare(rhs.textEdit.newText); + if (t) + return t < 0; + t = lhs.label.compare(rhs.label); + if (t) + return t < 0; + return lhs.filterText < rhs.filterText; }); // Trim result. @@ -293,8 +306,7 @@ void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS, case CodeCompletionString::CK_TypedText: text = Chunk.Text; for (auto i = first; i < out.size(); i++) - if (Kind == CodeCompletionString::CK_TypedText && !out[i].filterText) - out[i].filterText = text; + out[i].filterText = text; break; case CodeCompletionString::CK_Placeholder: text = Chunk.Text; @@ -414,7 +426,7 @@ class CompletionConsumer : public CodeCompleteConsumer { ls_items[j].priority_ = CCS->getPriority(); if (!g_config->completion.detailedLabel) { ls_items[j].detail = ls_items[j].label; - ls_items[j].label = ls_items[j].filterText.value_or(""); + ls_items[j].label = ls_items[j].filterText; } } #if LLVM_VERSION_MAJOR >= 7 From eacbc1e1e73357bfd9aa6b4a8691585fbaff7458 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 24 Nov 2018 09:49:58 -0800 Subject: [PATCH 301/378] Make DocumentLink::range narrower Thanks to Riatre #135 --- src/messages/textDocument_document.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 2ff5d218c..487345520 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -90,13 +90,22 @@ MAKE_REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFileByFilename(file->def->path) : nullptr; + if (!wf) { + reply.Error(ErrorCode::InternalError, "not opened"); return; + } std::vector result; for (const IndexInclude &include : file->def->includes) - result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}}, - DocumentUri::FromPath(include.resolved_path)}); + if (std::optional bline = + wf->GetBufferPosFromIndexPos(include.line, nullptr, false)) { + const std::string &line = wf->buffer_lines[*bline]; + auto start = line.find_first_of("\"<"), end = line.find_last_of("\">"); + if (start < end) + result.push_back({lsRange{{*bline, (int)start + 1}, {*bline, (int)end}}, + DocumentUri::FromPath(include.resolved_path)}); + } reply(result); } // namespace ccls From 9ffbf3c52e0e928efab20cdc0b4f2397d6ab8da5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 25 Nov 2018 14:55:33 -0800 Subject: [PATCH 302/378] codeAction: use codeActionProvider: CodeActionOptions and respect CodeActionParams::range --- src/lsp.hh | 6 ++++++ src/messages/initialize.cc | 17 ++++++++++------- src/messages/textDocument_code.cc | 15 +++++++++------ src/messages/textDocument_document.cc | 3 +-- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/lsp.hh b/src/lsp.hh index 2c4c735fd..9677aea58 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -109,6 +109,12 @@ struct lsRange { bool operator<(const lsRange &o) const { return !(start == o.start) ? start < o.start : end < o.end; } + bool Includes(const lsRange &o) const { + return start <= o.start && o.end <= end; + } + bool Intersects(const lsRange &o) const { + return start < o.end && o.start < end; + } }; struct Location { diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index cfea3b3e8..4582e4ac6 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -63,11 +63,11 @@ struct ServerCap { // for // '::' and '>' for '->'. See // https://github.com/Microsoft/language-server-protocol/issues/138. - std::vector triggerCharacters = {".", ":", ">", "#", - "<", "\"", "/"}; + std::vector triggerCharacters = {".", ":", ">", "#", + "<", "\"", "/"}; } completionProvider; struct SignatureHelpOptions { - std::vector triggerCharacters = {"(", ","}; + std::vector triggerCharacters = {"(", ","}; } signatureHelpProvider; bool definitionProvider = true; bool typeDefinitionProvider = true; @@ -76,7 +76,9 @@ struct ServerCap { bool documentHighlightProvider = true; bool documentSymbolProvider = true; bool workspaceSymbolProvider = true; - bool codeActionProvider = true; + struct CodeActionOptions { + std::vector codeActionKinds = {"quickfix"}; + } codeActionProvider; struct CodeLensOptions { bool resolveProvider = false; } codeLensProvider; @@ -84,7 +86,7 @@ struct ServerCap { bool documentRangeFormattingProvider = true; struct DocumentOnTypeFormattingOptions { std::string firstTriggerCharacter = "}"; - std::vector moreTriggerCharacter; + std::vector moreTriggerCharacter; } documentOnTypeFormattingProvider; bool renameProvider = true; struct DocumentLinkOptions { @@ -93,7 +95,7 @@ struct ServerCap { bool foldingRangeProvider = true; // The server provides execute command support. struct ExecuteCommandOptions { - std::vector commands{std::string(ccls_xref)}; + std::vector commands = {ccls_xref}; } executeCommandProvider; struct Workspace { struct WorkspaceFolders { @@ -102,9 +104,10 @@ struct ServerCap { } workspaceFolders; } workspace; }; +MAKE_REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds); +MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); MAKE_REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider, triggerCharacters); -MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); MAKE_REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider); MAKE_REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index 3f645c26a..4adcf0cbe 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -33,21 +33,24 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); } void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { - WorkingFile *wfile = + WorkingFile *wf = wfiles->GetFileByFilename(param.textDocument.uri.GetPath()); - if (!wfile) { + if (!wf) return; - } std::vector result; std::vector diagnostics; - wfiles->DoAction([&]() { diagnostics = wfile->diagnostics_; }); + wfiles->DoAction([&]() { diagnostics = wf->diagnostics_; }); for (Diagnostic &diag : diagnostics) - if (diag.fixits_.size()) { + if (diag.fixits_.size() && + (param.range.Intersects(diag.range) || + llvm::any_of(diag.fixits_, [&](const TextEdit &edit) { + return param.range.Intersects(edit.range); + }))) { CodeAction &cmd = result.emplace_back(); cmd.title = "FixIt: " + diag.message; auto &edit = cmd.edit.documentChanges.emplace_back(); edit.textDocument.uri = param.textDocument.uri; - edit.textDocument.version = wfile->version; + edit.textDocument.version = wf->version; edit.edits = diag.fixits_; } reply(result); diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 487345520..a02005a75 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -201,8 +201,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, // range. if (sym.extent.Valid()) if (auto range1 = GetLsRange(wfile, sym.extent); - range1 && range1->start <= range->start && - range->end <= range1->end) + range1 && range1->Includes(*range)) ds->range = *range1; } std::vector def_ptrs; From 0606b95754898841fdb5dc753482c3aba1688ca9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 25 Nov 2018 16:05:00 -0800 Subject: [PATCH 303/378] constexpr std::string_view -> const std::string_view This works around gcc 7.2/clang rC347417 which have a bad interaction with libstdc++'s implementation of P0426 constexpr std::string_view also emits a string_view object in .rodata that cannot be optimized out by clang (which means larger object file size) So use good old const. --- src/pipeline.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipeline.cc b/src/pipeline.cc index 054584ac9..347ecab77 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -424,8 +424,8 @@ void LaunchStdin() { std::thread([]() { set_thread_name("stdin"); std::string str; + const std::string_view kContentLength("Content-Length: "); while (true) { - constexpr std::string_view kContentLength("Content-Length: "); int len = 0; str.clear(); while (true) { From e6510f7428cbb98458ceaa5d0e0b10f10b9cc797 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 26 Nov 2018 21:00:30 -0800 Subject: [PATCH 304/378] Make EmptyParam empty & rewrite LruCache --- src/clang_complete.cc | 12 ++-- src/clang_complete.hh | 37 ++++++++++- src/lru_cache.hh | 148 ----------------------------------------- src/message_handler.cc | 2 +- src/message_handler.hh | 4 +- src/pipeline.cc | 1 - 6 files changed, 44 insertions(+), 160 deletions(-) delete mode 100644 src/lru_cache.hh diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f310180da..f4fde92c8 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -618,14 +618,14 @@ void CompletionManager::NotifySave(const std::string &filename) { void CompletionManager::OnClose(const std::string &filename) { std::lock_guard lock(sessions_lock_); - preloads.TryTake(filename); - sessions.TryTake(filename); + preloads.Take(filename); + sessions.Take(filename); } bool CompletionManager::EnsureCompletionOrCreatePreloadSession( const std::string &path) { std::lock_guard lock(sessions_lock_); - if (preloads.TryGet(path) || sessions.TryGet(path)) + if (preloads.Get(path) || sessions.Get(path)) return false; // No CompletionSession, create new one. @@ -644,11 +644,11 @@ std::shared_ptr CompletionManager::TryGetSession(const std::string &path, bool preload, bool *is_open) { std::lock_guard lock(sessions_lock_); - std::shared_ptr session = preloads.TryGet(path); + std::shared_ptr session = preloads.Get(path); if (session) { if (!preload) { - preloads.TryTake(path); + preloads.Take(path); sessions.Insert(path, session); if (is_open) *is_open = true; @@ -656,7 +656,7 @@ CompletionManager::TryGetSession(const std::string &path, bool preload, return session; } - session = sessions.TryGet(path); + session = sessions.Get(path); if (!session && !preload) { session = std::make_shared( project_->FindEntry(path, false), wfiles_, PCH); diff --git a/src/clang_complete.hh b/src/clang_complete.hh index e158aa0db..d067818c8 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -16,7 +16,6 @@ limitations under the License. #pragma once #include "clang_tu.hh" -#include "lru_cache.hh" #include "lsp.hh" #include "project.hh" #include "threaded_queue.hh" @@ -26,10 +25,12 @@ limitations under the License. #include #include +#include #include #include #include #include +#include namespace ccls { struct PreambleData; @@ -52,6 +53,40 @@ TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L, const clang::FixItHint &FixIt); +template struct LruCache { + LruCache(int capacity) : capacity(capacity) {} + + std::shared_ptr Get(const K &key) { + for (auto it = items.begin(); it != items.end(); ++it) + if (it->first == key) { + auto x = std::move(*it); + std::move_backward(items.begin(), it, it + 1); + items[0] = std::move(x); + return items[0].second; + } + return nullptr; + } + std::shared_ptr Take(const K &key) { + for (auto it = items.begin(); it != items.end(); ++it) + if (it->first == key) { + auto x = std::move(it->second); + items.erase(it); + return x; + } + return nullptr; + } + void Insert(const K &key, std::shared_ptr value) { + if ((int)items.size() >= capacity) + items.pop_back(); + items.emplace(items.begin(), key, std::move(value)); + } + void Clear() { items.clear(); } + +private: + std::vector>> items; + int capacity; +}; + struct CompletionSession : public std::enable_shared_from_this { std::mutex mutex; diff --git a/src/lru_cache.hh b/src/lru_cache.hh deleted file mode 100644 index 5e0253a29..000000000 --- a/src/lru_cache.hh +++ /dev/null @@ -1,148 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include -#include -#include -#include -#include - -// Cache that evicts old entries which have not been used recently. Implemented -// using array/linear search so this works well for small array sizes. -template struct LruCache { - explicit LruCache(int max_entries); - - // Fetches an entry for |key|. If it does not exist, |allocator| will be - // invoked to create one. - template - std::shared_ptr Get(const TKey &key, TAllocator allocator); - // Fetches the entry for |filename| and updates it's usage so it is less - // likely to be evicted. - std::shared_ptr TryGet(const TKey &key); - // TryGetEntry, except the entry is removed from the cache. - std::shared_ptr TryTake(const TKey &key); - // Inserts an entry. Evicts the oldest unused entry if there is no space. - void Insert(const TKey &key, const std::shared_ptr &value); - - // Call |func| on existing entries. If |func| returns false iteration - // temrinates early. - template void IterateValues(TFunc func); - - // Empties the cache - void Clear(void); - -private: - // There is a global score counter, when we access an element we increase - // its score to the current global value, so it has the highest overall - // score. This means that the oldest/least recently accessed value has the - // lowest score. - // - // There is a bit of special logic to handle score overlow. - struct Entry { - uint32_t score = 0; - TKey key; - std::shared_ptr value; - bool operator<(const Entry &other) const { return score < other.score; } - }; - - void IncrementScore(); - - std::vector entries_; - int max_entries_ = 1; - uint32_t next_score_ = 0; -}; - -template -LruCache::LruCache(int max_entries) : max_entries_(max_entries) { - assert(max_entries > 0); -} - -template -template -std::shared_ptr LruCache::Get(const TKey &key, - TAllocator allocator) { - std::shared_ptr result = TryGet(key); - if (!result) - Insert(key, result = allocator()); - return result; -} - -template -std::shared_ptr LruCache::TryGet(const TKey &key) { - // Assign new score. - for (Entry &entry : entries_) { - if (entry.key == key) { - entry.score = next_score_; - IncrementScore(); - return entry.value; - } - } - - return nullptr; -} - -template -std::shared_ptr LruCache::TryTake(const TKey &key) { - for (size_t i = 0; i < entries_.size(); ++i) { - if (entries_[i].key == key) { - std::shared_ptr copy = entries_[i].value; - entries_.erase(entries_.begin() + i); - return copy; - } - } - - return nullptr; -} - -template -void LruCache::Insert(const TKey &key, - const std::shared_ptr &value) { - if ((int)entries_.size() >= max_entries_) - entries_.erase(std::min_element(entries_.begin(), entries_.end())); - - Entry entry; - entry.score = next_score_; - IncrementScore(); - entry.key = key; - entry.value = value; - entries_.push_back(entry); -} - -template -template -void LruCache::IterateValues(TFunc func) { - for (Entry &entry : entries_) { - if (!func(entry.value)) - break; - } -} - -template -void LruCache::IncrementScore() { - // Overflow. - if (++next_score_ == 0) { - std::sort(entries_.begin(), entries_.end()); - for (Entry &entry : entries_) - entry.score = next_score_++; - } -} - -template -void LruCache::Clear(void) { - entries_.clear(); - next_score_ = 0; -} diff --git a/src/message_handler.cc b/src/message_handler.cc index c9ff275dd..ee67ee6c2 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -32,7 +32,7 @@ MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); -MAKE_REFLECT_STRUCT(EmptyParam, placeholder); +void Reflect(Reader &, EmptyParam &) {} MAKE_REFLECT_STRUCT(TextDocumentParam, textDocument); MAKE_REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument); MAKE_REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text); diff --git a/src/message_handler.hh b/src/message_handler.hh index e5e078443..8eca93754 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -43,9 +43,7 @@ struct CodeActionParam { std::vector diagnostics; } context; }; -struct EmptyParam { - bool placeholder; -}; +struct EmptyParam {}; struct DidOpenTextDocumentParam { TextDocumentItem textDocument; }; diff --git a/src/pipeline.cc b/src/pipeline.cc index 347ecab77..c91f338dc 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -465,7 +465,6 @@ void LaunchStdin() { std::string method; ReflectMember(reader, "id", id); ReflectMember(reader, "method", method); - auto param = std::make_unique(); on_request->PushBack( {id, std::move(method), std::move(message), std::move(document)}); From 5a723b489a5c7003802dca22f4a6c09b8400dddb Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 26 Nov 2018 22:22:27 -0800 Subject: [PATCH 305/378] Refactor Matcher to use pimpl and merge match.hh into utils.hh --- CMakeLists.txt | 1 - src/clang_complete.cc | 3 +- src/include_complete.cc | 7 ++-- src/indexer.cc | 3 +- src/match.cc | 77 ------------------------------------- src/match.hh | 45 ---------------------- src/message_handler.cc | 3 +- src/messages/ccls_reload.cc | 1 - src/pipeline.cc | 5 +-- src/project.cc | 5 +-- src/utils.cc | 59 ++++++++++++++++++++++++++++ src/utils.hh | 21 ++++++++++ 12 files changed, 90 insertions(+), 140 deletions(-) delete mode 100644 src/match.cc delete mode 100644 src/match.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d608c900..b794d3982 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,7 +190,6 @@ target_sources(ccls PRIVATE src/indexer.cc src/log.cc src/lsp.cc - src/match.cc src/message_handler.cc src/pipeline.cc src/platform_posix.cc diff --git a/src/clang_complete.cc b/src/clang_complete.cc index f4fde92c8..3132a5233 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -18,7 +18,6 @@ limitations under the License. #include "clang_tu.hh" #include "filesystem.hh" #include "log.hh" -#include "match.hh" #include "platform.hh" #include @@ -585,7 +584,7 @@ void CompletionManager::DiagnosticsUpdate(const std::string &path, int debounce) { static GroupMatch match(g_config->diagnostics.whitelist, g_config->diagnostics.blacklist); - if (!match.IsMatch(path)) + if (!match.Matches(path)) return; int64_t now = chrono::duration_cast( chrono::high_resolution_clock::now().time_since_epoch()) diff --git a/src/include_complete.cc b/src/include_complete.cc index 7f2933361..b7834d61d 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -16,7 +16,6 @@ limitations under the License. #include "include_complete.hh" #include "filesystem.hh" -#include "match.hh" #include "platform.hh" #include "project.hh" @@ -162,7 +161,7 @@ void IncludeComplete::AddFile(const std::string &path) { ok = true; if (!ok) return; - if (match_ && !match_->IsMatch(path)) + if (match_ && !match_->Matches(path)) return; std::string trimmed_path = path; @@ -179,7 +178,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets) { directory = NormalizePath(directory); EnsureEndsInSlash(directory); - if (match_ && !match_->IsMatch(directory)) + if (match_ && !match_->Matches(directory)) return; bool include_cpp = directory.find("include/c++") != std::string::npos; @@ -193,7 +192,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, ok = true; if (!ok) return; - if (match_ && !match_->IsMatch(directory + path)) + if (match_ && !match_->Matches(directory + path)) return; CompletionCandidate candidate; diff --git a/src/indexer.cc b/src/indexer.cc index db0d56eb8..b833589f6 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -18,7 +18,6 @@ limitations under the License. #include "clang_complete.hh" #include "clang_tu.hh" #include "log.hh" -#include "match.hh" #include "pipeline.hh" #include "platform.hh" #include "serializer.hh" @@ -97,7 +96,7 @@ struct IndexParam { bool UseMultiVersion(const FileEntry &FE) { auto it = UID2multi.try_emplace(FE.getUniqueID()); if (it.second) - it.first->second = multiVersionMatcher->IsMatch(PathFromFileEntry(FE)); + it.first->second = multiVersionMatcher->Matches(PathFromFileEntry(FE)); return it.first->second; } }; diff --git a/src/match.cc b/src/match.cc deleted file mode 100644 index dc8515515..000000000 --- a/src/match.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "match.hh" - -#include "message_handler.hh" -#include "pipeline.hh" - -namespace ccls { -std::optional Matcher::Create(const std::string &search) { - try { - Matcher m; - m.regex_string = search; - m.regex = std::regex(search, std::regex_constants::ECMAScript | - std::regex_constants::icase | - std::regex_constants::optimize - // std::regex_constants::nosubs - ); - return m; - } catch (const std::exception &e) { - ShowMessageParam params; - params.type = MessageType::Error; - params.message = - "failed to parse EMCAScript regex " + search + " : " + e.what(); - pipeline::Notify(window_showMessage, params); - return std::nullopt; - } -} - -bool Matcher::IsMatch(const std::string &value) const { - // std::smatch match; - // return std::regex_match(value, match, regex); - return std::regex_search(value, regex, std::regex_constants::match_any); -} - -GroupMatch::GroupMatch(const std::vector &whitelist, - const std::vector &blacklist) { - for (const std::string &entry : whitelist) { - std::optional m = Matcher::Create(entry); - if (m) - this->whitelist.push_back(*m); - } - for (const std::string &entry : blacklist) { - std::optional m = Matcher::Create(entry); - if (m) - this->blacklist.push_back(*m); - } -} - -bool GroupMatch::IsMatch(const std::string &value, - std::string *match_failure_reason) const { - for (const Matcher &m : whitelist) - if (m.IsMatch(value)) - return true; - - for (const Matcher &m : blacklist) - if (m.IsMatch(value)) { - if (match_failure_reason) - *match_failure_reason = "blacklist \"" + m.regex_string + "\""; - return false; - } - - return true; -} -} // namespace ccls diff --git a/src/match.hh b/src/match.hh deleted file mode 100644 index f5ebb976f..000000000 --- a/src/match.hh +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include - -#include -#include -#include - -namespace ccls { -struct Matcher { - static std::optional Create(const std::string &search); - - bool IsMatch(const std::string &value) const; - - std::string regex_string; - std::regex regex; -}; - -// Check multiple |Matcher| instances at the same time. -struct GroupMatch { - GroupMatch(const std::vector &whitelist, - const std::vector &blacklist); - - bool IsMatch(const std::string &value, - std::string *match_failure_reason = nullptr) const; - - std::vector whitelist; - std::vector blacklist; -}; -} // namespace ccls diff --git a/src/message_handler.cc b/src/message_handler.cc index ee67ee6c2..1acb97beb 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -16,7 +16,6 @@ limitations under the License. #include "message_handler.hh" #include "log.hh" -#include "match.hh" #include "pipeline.hh" #include "project.hh" #include "query_utils.hh" @@ -275,7 +274,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { g_config->highlight.blacklist); assert(file.def); if (wfile->buffer_content.size() > g_config->highlight.largeFileSize || - !match.IsMatch(file.def->path)) + !match.Matches(file.def->path)) return; // Group symbols together. diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 0ec1bb855..d48d23c9e 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -14,7 +14,6 @@ limitations under the License. ==============================================================================*/ #include "clang_complete.hh" -#include "match.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" diff --git a/src/pipeline.cc b/src/pipeline.cc index c91f338dc..fceb524db 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -20,7 +20,6 @@ limitations under the License. #include "include_complete.hh" #include "log.hh" #include "lsp.hh" -#include "match.hh" #include "message_handler.hh" #include "pipeline.hh" #include "platform.hh" @@ -199,7 +198,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, return false; } - if (!matcher.IsMatch(request.path)) { + if (!matcher.Matches(request.path)) { LOG_IF_S(INFO, loud) << "skip " << request.path; return false; } @@ -321,7 +320,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, for (std::unique_ptr &curr : indexes) { std::string path = curr->path; - if (!matcher.IsMatch(path)) { + if (!matcher.Matches(path)) { LOG_IF_S(INFO, loud) << "skip index for " << path; continue; } diff --git a/src/project.cc b/src/project.cc index eee0d774d..3f1df4078 100644 --- a/src/project.cc +++ b/src/project.cc @@ -18,7 +18,6 @@ limitations under the License. #include "clang_tu.hh" // llvm::vfs #include "filesystem.hh" #include "log.hh" -#include "match.hh" #include "pipeline.hh" #include "platform.hh" #include "serializers/json.hh" @@ -497,8 +496,8 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { int i = 0; for (const Project::Entry &entry : folder.entries) { std::string reason; - if (match.IsMatch(entry.filename, &reason) && - match_i.IsMatch(entry.filename, &reason)) { + if (match.Matches(entry.filename, &reason) && + match_i.Matches(entry.filename, &reason)) { bool interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; pipeline::Index( diff --git a/src/utils.cc b/src/utils.cc index 3100c32d9..48e9c0d06 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -16,6 +16,8 @@ limitations under the License. #include "utils.hh" #include "log.hh" +#include "message_handler.hh" +#include "pipeline.hh" #include "platform.hh" #include @@ -30,10 +32,67 @@ using namespace llvm; #include #include #include +#include #include #include namespace ccls { +struct Matcher::Impl { + std::regex regex; +}; + +Matcher::Matcher(const std::string &pattern) + : impl(std::make_unique()), pattern(pattern) { + impl->regex = std::regex(pattern, std::regex_constants::ECMAScript | + std::regex_constants::icase | + std::regex_constants::optimize); +} + +Matcher::~Matcher() {} + +bool Matcher::Matches(const std::string &text) const { + return std::regex_search(text, impl->regex, std::regex_constants::match_any); +} + +GroupMatch::GroupMatch(const std::vector &whitelist, + const std::vector &blacklist) { + auto err = [](const std::string &pattern, const char *what) { + ShowMessageParam params; + params.type = MessageType::Error; + params.message = + "failed to parse EMCAScript regex " + pattern + " : " + what; + pipeline::Notify(window_showMessage, params); + }; + for (const std::string &pattern : whitelist) { + try { + this->whitelist.emplace_back(pattern); + } catch (const std::exception &e) { + err(pattern, e.what()); + } + } + for (const std::string &pattern : blacklist) { + try { + this->blacklist.emplace_back(pattern); + } catch (const std::exception &e) { + err(pattern, e.what()); + } + } +} + +bool GroupMatch::Matches(const std::string &text, + std::string *blacklist_pattern) const { + for (const Matcher &m : whitelist) + if (m.Matches(text)) + return true; + for (const Matcher &m : blacklist) + if (m.Matches(text)) { + if (blacklist_pattern) + *blacklist_pattern = m.pattern; + return false; + } + return true; +} + uint64_t HashUsr(llvm::StringRef s) { union { uint64_t ret; diff --git a/src/utils.hh b/src/utils.hh index 1c00b2a61..d6d079664 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -19,6 +19,7 @@ limitations under the License. #include #include +#include #include #include @@ -27,6 +28,26 @@ class StringRef; } namespace ccls { +struct Matcher { + struct Impl; + std::unique_ptr impl; + std::string pattern; + + Matcher(const std::string &pattern); // throw + Matcher(Matcher&&) = default; + ~Matcher(); + bool Matches(const std::string &text) const; +}; + +struct GroupMatch { + std::vector whitelist, blacklist; + + GroupMatch(const std::vector &whitelist, + const std::vector &blacklist); + bool Matches(const std::string &text, + std::string *blacklist_pattern = nullptr) const; +}; + uint64_t HashUsr(llvm::StringRef s); std::string LowerPathIfInsensitive(const std::string &path); From 5a5165faa88cfaf9126276aaceb1b9526b3955cc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 26 Nov 2018 22:29:28 -0800 Subject: [PATCH 306/378] Merge query.hh and query_util.hh --- CMakeLists.txt | 1 - src/message_handler.cc | 2 +- src/messages/ccls_call.cc | 2 +- src/messages/ccls_info.cc | 2 +- src/messages/ccls_inheritance.cc | 2 +- src/messages/ccls_member.cc | 2 +- src/messages/ccls_navigate.cc | 2 +- src/messages/ccls_vars.cc | 2 +- src/messages/textDocument_code.cc | 2 +- src/messages/textDocument_definition.cc | 2 +- src/messages/textDocument_document.cc | 2 +- src/messages/textDocument_foldingRange.cc | 2 +- src/messages/textDocument_hover.cc | 2 +- src/messages/textDocument_references.cc | 2 +- src/messages/textDocument_rename.cc | 2 +- src/messages/workspace.cc | 2 +- src/pipeline.cc | 2 +- src/query.cc | 322 ++++++++++++++++++++- src/query.hh | 84 ++++++ src/query_utils.cc | 337 ---------------------- src/query_utils.hh | 106 ------- 21 files changed, 418 insertions(+), 464 deletions(-) delete mode 100644 src/query_utils.cc delete mode 100644 src/query_utils.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index b794d3982..fa1168169 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,6 @@ target_sources(ccls PRIVATE src/platform_win.cc src/position.cc src/project.cc - src/query_utils.cc src/query.cc src/serializer.cc src/test.cc diff --git a/src/message_handler.cc b/src/message_handler.cc index 1acb97beb..2f51e3268 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -18,7 +18,7 @@ limitations under the License. #include "log.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.hh" +#include "query.hh" #include "serializers/json.hh" #include diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 1b0b9f76f..f3a059f0b 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -16,7 +16,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" #include diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 664ff3d78..9560f2d95 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -16,7 +16,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.hh" +#include "query.hh" namespace ccls { MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index d2f65258d..fa453379c 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -16,7 +16,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" #include diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index 87fd58cdb..da7db980c 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -17,7 +17,7 @@ limitations under the License. #include "hierarchy.hh" #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" #include #include diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 03f895f05..78b6fa749 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.hh" +#include "query.hh" namespace ccls { namespace { diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index b8917e612..ec13840ca 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" namespace ccls { namespace { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index 4adcf0cbe..9f59fcc30 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" #include "serializers/json.hh" #include diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index cd52afaf8..0c7b853e3 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.hh" +#include "query.hh" #include #include diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index a02005a75..d8a07f0ff 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -15,7 +15,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" -#include "query_utils.hh" +#include "query.hh" #include diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index 24af7dd8a..62a62fe3b 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -16,7 +16,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.hh" +#include "query.hh" #include "working_files.hh" namespace ccls { diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index c2666a1f9..182104de4 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.hh" +#include "query.hh" namespace ccls { namespace { diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index d37e28b32..b3604068f 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.hh" +#include "query.hh" #include diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 944c90e1c..2274e872f 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ #include "message_handler.hh" -#include "query_utils.hh" +#include "query.hh" namespace ccls { namespace { diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 084433933..05d6488b4 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -19,7 +19,7 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" -#include "query_utils.hh" +#include "query.hh" #include #include diff --git a/src/pipeline.cc b/src/pipeline.cc index fceb524db..2c7b54f82 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -24,7 +24,7 @@ limitations under the License. #include "pipeline.hh" #include "platform.hh" #include "project.hh" -#include "query_utils.hh" +#include "query.hh" #include "serializers/json.hh" #include diff --git a/src/query.cc b/src/query.cc index 00b32cecc..0f767b159 100644 --- a/src/query.cc +++ b/src/query.cc @@ -16,11 +16,13 @@ limitations under the License. #include "query.hh" #include "indexer.hh" +#include "pipeline.hh" #include "serializer.hh" #include "serializers/json.hh" -#include -#include +#include +#include +#include #include #include #include @@ -52,7 +54,7 @@ void RemoveRange(std::vector &from, const std::vector &to_remove) { } } -QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile &indexed) { +QueryFile::DefUpdate BuildFileDefUpdate(IndexFile &&indexed) { QueryFile::Def def; def.path = std::move(indexed.path); def.args = std::move(indexed.args); @@ -87,7 +89,6 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { else previous = ∅ r.lid2path = std::move(current->lid2path); - r.files_def_update = BuildFileDefUpdate(std::move(*current)); r.funcs_hint = current->usr2func.size() - previous->usr2func.size(); for (auto &it : previous->usr2func) { @@ -143,6 +144,7 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { r.vars_uses[var.usr].second = std::move(var.uses); } + r.files_def_update = BuildFileDefUpdate(std::move(*current)); return r; } @@ -486,4 +488,316 @@ std::vector DB::GetFileSet(const std::vector &folders) { } return file_set; } + +namespace { +// Computes roughly how long |range| is. +int ComputeRangeSize(const Range &range) { + if (range.start.line != range.end.line) + return INT_MAX; + return range.end.column - range.start.column; +} + +template +std::vector +GetDeclarations(llvm::DenseMap &entity_usr, + std::vector &entities, const std::vector &usrs) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + Q &entity = entities[entity_usr[{usr}]]; + bool has_def = false; + for (auto &def : entity.def) + if (def.spell) { + ret.push_back(*def.spell); + has_def = true; + break; + } + if (!has_def && entity.declarations.size()) + ret.push_back(entity.declarations[0]); + } + return ret; +} +} + +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { + Maybe ret; + EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); + return ret; +} + +std::vector GetFuncDeclarations(DB *db, const std::vector &usrs) { + return GetDeclarations(db->func_usr, db->funcs, usrs); +} +std::vector GetTypeDeclarations(DB *db, const std::vector &usrs) { + return GetDeclarations(db->type_usr, db->types, usrs); +} +std::vector GetVarDeclarations(DB *db, const std::vector &usrs, + unsigned kind) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + QueryVar &var = db->Var(usr); + bool has_def = false; + for (auto &def : var.def) + if (def.spell) { + has_def = true; + // See messages/ccls_vars.cc + if (def.kind == SymbolKind::Field) { + if (!(kind & 1)) + break; + } else if (def.kind == SymbolKind::Variable) { + if (!(kind & 2)) + break; + } else if (def.kind == SymbolKind::Parameter) { + if (!(kind & 4)) + break; + } + ret.push_back(*def.spell); + break; + } + if (!has_def && var.declarations.size()) + ret.push_back(var.declarations[0]); + } + return ret; +} + +std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym) { + static std::vector empty; + switch (sym.kind) { + case Kind::Func: + return db->GetFunc(sym).declarations; + case Kind::Type: + return db->GetType(sym).declarations; + case Kind::Var: + return db->GetVar(sym).declarations; + default: + break; + } + return empty; +} + +std::vector GetUsesForAllBases(DB *db, QueryFunc &root) { + std::vector ret; + std::vector stack{&root}; + std::unordered_set seen; + seen.insert(root.usr); + while (!stack.empty()) { + QueryFunc &func = *stack.back(); + stack.pop_back(); + if (auto *def = func.AnyDef()) { + EachDefinedFunc(db, def->bases, [&](QueryFunc &func1) { + if (!seen.count(func1.usr)) { + seen.insert(func1.usr); + stack.push_back(&func1); + ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); + } + }); + } + } + + return ret; +} + +std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { + std::vector ret; + std::vector stack{&root}; + std::unordered_set seen; + seen.insert(root.usr); + while (!stack.empty()) { + QueryFunc &func = *stack.back(); + stack.pop_back(); + EachDefinedFunc(db, func.derived, [&](QueryFunc &func1) { + if (!seen.count(func1.usr)) { + seen.insert(func1.usr); + stack.push_back(&func1); + ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); + } + }); + } + + return ret; +} + +std::optional GetLsRange(WorkingFile *wfile, + const Range &location) { + if (!wfile || wfile->index_lines.empty()) + return lsRange{Position{location.start.line, location.start.column}, + Position{location.end.line, location.end.column}}; + + int start_column = location.start.column, end_column = location.end.column; + std::optional start = wfile->GetBufferPosFromIndexPos( + location.start.line, &start_column, false); + std::optional end = wfile->GetBufferPosFromIndexPos( + location.end.line, &end_column, true); + if (!start || !end) + return std::nullopt; + + // If remapping end fails (end can never be < start), just guess that the + // final location didn't move. This only screws up the highlighted code + // region if we guess wrong, so not a big deal. + // + // Remapping fails often in C++ since there are a lot of "};" at the end of + // class/struct definitions. + if (*end < *start) + *end = *start + (location.end.line - location.start.line); + if (*start == *end && start_column > end_column) + end_column = start_column; + + return lsRange{Position{*start, start_column}, Position{*end, end_column}}; +} + +DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { + QueryFile &file = db->files[file_id]; + if (file.def) { + *path = file.def->path; + return DocumentUri::FromPath(*path); + } else { + *path = ""; + return DocumentUri::FromPath(""); + } +} + +DocumentUri GetLsDocumentUri(DB *db, int file_id) { + QueryFile &file = db->files[file_id]; + if (file.def) { + return DocumentUri::FromPath(file.def->path); + } else { + return DocumentUri::FromPath(""); + } +} + +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) { + std::string path; + DocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); + std::optional range = + GetLsRange(wfiles->GetFileByFilename(path), use.range); + if (!range) + return std::nullopt; + return Location{uri, *range}; +} + +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, + SymbolRef sym, int file_id) { + return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id}); +} + +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, + const std::vector &uses) { + std::vector ret; + for (Use use : uses) + if (auto loc = GetLsLocation(db, wfiles, use)) + ret.push_back(*loc); + std::sort(ret.begin(), ret.end()); + ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); + if (ret.size() > g_config->xref.maxNum) + ret.resize(g_config->xref.maxNum); + return ret; +} + +SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { + SymbolKind ret; + if (sym.kind == Kind::File) + ret = SymbolKind::File; + else { + ret = SymbolKind::Unknown; + WithEntity(db, sym, [&](const auto &entity) { + for (auto &def : entity.def) { + ret = def.kind; + break; + } + }); + } + return ret; +} + +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, + bool detailed) { + switch (sym.kind) { + case Kind::Invalid: + break; + case Kind::File: { + QueryFile &file = db->GetFile(sym); + if (!file.def) + break; + + SymbolInformation info; + info.name = file.def->path; + info.kind = SymbolKind::File; + return info; + } + default: { + SymbolInformation info; + EachEntityDef(db, sym, [&](const auto &def) { + if (detailed) + info.name = def.detailed_name; + else + info.name = def.Name(true); + info.kind = def.kind; + return false; + }); + return info; + } + } + + return std::nullopt; +} + +std::vector FindSymbolsAtLocation(WorkingFile *wfile, + QueryFile *file, Position &ls_pos, + bool smallest) { + std::vector symbols; + // If multiVersion > 0, index may not exist and thus index_lines is empty. + if (wfile && wfile->index_lines.size()) { + if (auto line = wfile->GetIndexPosFromBufferPos( + ls_pos.line, &ls_pos.character, false)) { + ls_pos.line = *line; + } else { + ls_pos.line = -1; + return {}; + } + } + + for (auto [sym, refcnt] : file->symbol2refcnt) + if (refcnt > 0 && sym.range.Contains(ls_pos.line, ls_pos.character)) + symbols.push_back(sym); + + // Order shorter ranges first, since they are more detailed/precise. This is + // important for macros which generate code so that we can resolving the + // macro argument takes priority over the entire macro body. + // + // Order Kind::Var before Kind::Type. Macro calls are treated as Var + // currently. If a macro expands to tokens led by a Kind::Type, the macro and + // the Type have the same range. We want to find the macro definition instead + // of the Type definition. + // + // Then order functions before other types, which makes goto definition work + // better on constructors. + std::sort( + symbols.begin(), symbols.end(), + [](const SymbolRef &a, const SymbolRef &b) { + int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); + if (t) + return t < 0; + // MacroExpansion + if ((t = (a.role & Role::Dynamic) - (b.role & Role::Dynamic))) + return t > 0; + if ((t = (a.role & Role::Definition) - (b.role & Role::Definition))) + return t > 0; + // operator> orders Var/Func before Type. + t = static_cast(a.kind) - static_cast(b.kind); + if (t) + return t > 0; + return a.usr < b.usr; + }); + if (symbols.size() && smallest) { + SymbolRef sym = symbols[0]; + for (size_t i = 1; i < symbols.size(); i++) + if (!(sym.range == symbols[i].range && sym.kind == symbols[i].kind)) { + symbols.resize(i); + break; + } + } + + return symbols; +} } // namespace ccls diff --git a/src/query.hh b/src/query.hh index 33cb5a663..60f234335 100644 --- a/src/query.hh +++ b/src/query.hh @@ -17,6 +17,7 @@ limitations under the License. #include "indexer.hh" #include "serializer.hh" +#include "working_files.hh" #include #include @@ -196,4 +197,87 @@ struct DB { QueryType &GetType(SymbolIdx ref) { return Type(ref.usr); } QueryVar &GetVar(SymbolIdx ref) { return Var(ref.usr); } }; + +Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); + +// Get defining declaration (if exists) or an arbitrary declaration (otherwise) +// for each id. +std::vector GetFuncDeclarations(DB *, const std::vector &); +std::vector GetTypeDeclarations(DB *, const std::vector &); +std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); + +// Get non-defining declarations. +std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym); + +std::vector GetUsesForAllBases(DB *db, QueryFunc &root); +std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); +std::optional GetLsRange(WorkingFile *working_file, + const Range &location); +DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); +DocumentUri GetLsDocumentUri(DB *db, int file_id); + +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); +std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, + SymbolRef sym, int file_id); +std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, + const std::vector &uses); +// Returns a symbol. The symbol will *NOT* have a location assigned. +std::optional GetSymbolInfo(DB *db, SymbolIdx sym, + bool detailed); + +std::vector FindSymbolsAtLocation(WorkingFile *working_file, + QueryFile *file, + Position &ls_pos, + bool smallest = false); + +template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { + switch (sym.kind) { + case Kind::Invalid: + case Kind::File: + break; + case Kind::Func: + fn(db->GetFunc(sym)); + break; + case Kind::Type: + fn(db->GetType(sym)); + break; + case Kind::Var: + fn(db->GetVar(sym)); + break; + } +} + +template void EachEntityDef(DB *db, SymbolIdx sym, Fn &&fn) { + WithEntity(db, sym, [&](const auto &entity) { + for (auto &def : entity.def) + if (!fn(def)) + break; + }); +} + +template +void EachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) { + WithEntity(db, sym, [&](const auto &entity) { + for (Use use : entity.uses) + fn(use); + if (include_decl) { + for (auto &def : entity.def) + if (def.spell) + fn(*def.spell); + for (Use use : entity.declarations) + fn(use); + } + }); +} + +SymbolKind GetSymbolKind(DB *db, SymbolIdx sym); + +template +void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { + for (Usr usr : usrs) { + auto &obj = db->Func(usr); + if (!obj.def.empty()) + fn(obj); + } +} } // namespace ccls diff --git a/src/query_utils.cc b/src/query_utils.cc deleted file mode 100644 index 34411f21b..000000000 --- a/src/query_utils.cc +++ /dev/null @@ -1,337 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "query_utils.hh" - -#include "pipeline.hh" - -#include -#include - -namespace ccls { -namespace { - -// Computes roughly how long |range| is. -int ComputeRangeSize(const Range &range) { - if (range.start.line != range.end.line) - return INT_MAX; - return range.end.column - range.start.column; -} - -template -std::vector -GetDeclarations(llvm::DenseMap &entity_usr, - std::vector &entities, const std::vector &usrs) { - std::vector ret; - ret.reserve(usrs.size()); - for (Usr usr : usrs) { - Q &entity = entities[entity_usr[{usr}]]; - bool has_def = false; - for (auto &def : entity.def) - if (def.spell) { - ret.push_back(*def.spell); - has_def = true; - break; - } - if (!has_def && entity.declarations.size()) - ret.push_back(entity.declarations[0]); - } - return ret; -} - -} // namespace - -Maybe GetDefinitionSpell(DB *db, SymbolIdx sym) { - Maybe ret; - EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); - return ret; -} - -std::vector GetFuncDeclarations(DB *db, const std::vector &usrs) { - return GetDeclarations(db->func_usr, db->funcs, usrs); -} -std::vector GetTypeDeclarations(DB *db, const std::vector &usrs) { - return GetDeclarations(db->type_usr, db->types, usrs); -} -std::vector GetVarDeclarations(DB *db, const std::vector &usrs, - unsigned kind) { - std::vector ret; - ret.reserve(usrs.size()); - for (Usr usr : usrs) { - QueryVar &var = db->Var(usr); - bool has_def = false; - for (auto &def : var.def) - if (def.spell) { - has_def = true; - // See messages/ccls_vars.cc - if (def.kind == SymbolKind::Field) { - if (!(kind & 1)) - break; - } else if (def.kind == SymbolKind::Variable) { - if (!(kind & 2)) - break; - } else if (def.kind == SymbolKind::Parameter) { - if (!(kind & 4)) - break; - } - ret.push_back(*def.spell); - break; - } - if (!has_def && var.declarations.size()) - ret.push_back(var.declarations[0]); - } - return ret; -} - -std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym) { - static std::vector empty; - switch (sym.kind) { - case Kind::Func: - return db->GetFunc(sym).declarations; - case Kind::Type: - return db->GetType(sym).declarations; - case Kind::Var: - return db->GetVar(sym).declarations; - default: - break; - } - return empty; -} - -std::vector GetUsesForAllBases(DB *db, QueryFunc &root) { - std::vector ret; - std::vector stack{&root}; - std::unordered_set seen; - seen.insert(root.usr); - while (!stack.empty()) { - QueryFunc &func = *stack.back(); - stack.pop_back(); - if (auto *def = func.AnyDef()) { - EachDefinedFunc(db, def->bases, [&](QueryFunc &func1) { - if (!seen.count(func1.usr)) { - seen.insert(func1.usr); - stack.push_back(&func1); - ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); - } - }); - } - } - - return ret; -} - -std::vector GetUsesForAllDerived(DB *db, QueryFunc &root) { - std::vector ret; - std::vector stack{&root}; - std::unordered_set seen; - seen.insert(root.usr); - while (!stack.empty()) { - QueryFunc &func = *stack.back(); - stack.pop_back(); - EachDefinedFunc(db, func.derived, [&](QueryFunc &func1) { - if (!seen.count(func1.usr)) { - seen.insert(func1.usr); - stack.push_back(&func1); - ret.insert(ret.end(), func1.uses.begin(), func1.uses.end()); - } - }); - } - - return ret; -} - -std::optional GetLsRange(WorkingFile *wfile, - const Range &location) { - if (!wfile || wfile->index_lines.empty()) - return lsRange{Position{location.start.line, location.start.column}, - Position{location.end.line, location.end.column}}; - - int start_column = location.start.column, end_column = location.end.column; - std::optional start = wfile->GetBufferPosFromIndexPos( - location.start.line, &start_column, false); - std::optional end = wfile->GetBufferPosFromIndexPos( - location.end.line, &end_column, true); - if (!start || !end) - return std::nullopt; - - // If remapping end fails (end can never be < start), just guess that the - // final location didn't move. This only screws up the highlighted code - // region if we guess wrong, so not a big deal. - // - // Remapping fails often in C++ since there are a lot of "};" at the end of - // class/struct definitions. - if (*end < *start) - *end = *start + (location.end.line - location.start.line); - if (*start == *end && start_column > end_column) - end_column = start_column; - - return lsRange{Position{*start, start_column}, Position{*end, end_column}}; -} - -DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) { - QueryFile &file = db->files[file_id]; - if (file.def) { - *path = file.def->path; - return DocumentUri::FromPath(*path); - } else { - *path = ""; - return DocumentUri::FromPath(""); - } -} - -DocumentUri GetLsDocumentUri(DB *db, int file_id) { - QueryFile &file = db->files[file_id]; - if (file.def) { - return DocumentUri::FromPath(file.def->path); - } else { - return DocumentUri::FromPath(""); - } -} - -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) { - std::string path; - DocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); - std::optional range = - GetLsRange(wfiles->GetFileByFilename(path), use.range); - if (!range) - return std::nullopt; - return Location{uri, *range}; -} - -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, - SymbolRef sym, int file_id) { - return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id}); -} - -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, - const std::vector &uses) { - std::vector ret; - for (Use use : uses) - if (auto loc = GetLsLocation(db, wfiles, use)) - ret.push_back(*loc); - std::sort(ret.begin(), ret.end()); - ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); - if (ret.size() > g_config->xref.maxNum) - ret.resize(g_config->xref.maxNum); - return ret; -} - -SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { - SymbolKind ret; - if (sym.kind == Kind::File) - ret = SymbolKind::File; - else { - ret = SymbolKind::Unknown; - WithEntity(db, sym, [&](const auto &entity) { - for (auto &def : entity.def) { - ret = def.kind; - break; - } - }); - } - return ret; -} - -std::optional GetSymbolInfo(DB *db, SymbolIdx sym, - bool detailed) { - switch (sym.kind) { - case Kind::Invalid: - break; - case Kind::File: { - QueryFile &file = db->GetFile(sym); - if (!file.def) - break; - - SymbolInformation info; - info.name = file.def->path; - info.kind = SymbolKind::File; - return info; - } - default: { - SymbolInformation info; - EachEntityDef(db, sym, [&](const auto &def) { - if (detailed) - info.name = def.detailed_name; - else - info.name = def.Name(true); - info.kind = def.kind; - return false; - }); - return info; - } - } - - return std::nullopt; -} - -std::vector FindSymbolsAtLocation(WorkingFile *wfile, - QueryFile *file, Position &ls_pos, - bool smallest) { - std::vector symbols; - // If multiVersion > 0, index may not exist and thus index_lines is empty. - if (wfile && wfile->index_lines.size()) { - if (auto line = wfile->GetIndexPosFromBufferPos( - ls_pos.line, &ls_pos.character, false)) { - ls_pos.line = *line; - } else { - ls_pos.line = -1; - return {}; - } - } - - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && sym.range.Contains(ls_pos.line, ls_pos.character)) - symbols.push_back(sym); - - // Order shorter ranges first, since they are more detailed/precise. This is - // important for macros which generate code so that we can resolving the - // macro argument takes priority over the entire macro body. - // - // Order Kind::Var before Kind::Type. Macro calls are treated as Var - // currently. If a macro expands to tokens led by a Kind::Type, the macro and - // the Type have the same range. We want to find the macro definition instead - // of the Type definition. - // - // Then order functions before other types, which makes goto definition work - // better on constructors. - std::sort( - symbols.begin(), symbols.end(), - [](const SymbolRef &a, const SymbolRef &b) { - int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); - if (t) - return t < 0; - // MacroExpansion - if ((t = (a.role & Role::Dynamic) - (b.role & Role::Dynamic))) - return t > 0; - if ((t = (a.role & Role::Definition) - (b.role & Role::Definition))) - return t > 0; - // operator> orders Var/Func before Type. - t = static_cast(a.kind) - static_cast(b.kind); - if (t) - return t > 0; - return a.usr < b.usr; - }); - if (symbols.size() && smallest) { - SymbolRef sym = symbols[0]; - for (size_t i = 1; i < symbols.size(); i++) - if (!(sym.range == symbols[i].range && sym.kind == symbols[i].kind)) { - symbols.resize(i); - break; - } - } - - return symbols; -} -} // namespace ccls diff --git a/src/query_utils.hh b/src/query_utils.hh deleted file mode 100644 index 1bf69f622..000000000 --- a/src/query_utils.hh +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "query.hh" -#include "working_files.hh" - -#include - -namespace ccls { -Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); - -// Get defining declaration (if exists) or an arbitrary declaration (otherwise) -// for each id. -std::vector GetFuncDeclarations(DB *, const std::vector &); -std::vector GetTypeDeclarations(DB *, const std::vector &); -std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); - -// Get non-defining declarations. -std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym); - -std::vector GetUsesForAllBases(DB *db, QueryFunc &root); -std::vector GetUsesForAllDerived(DB *db, QueryFunc &root); -std::optional GetLsRange(WorkingFile *working_file, - const Range &location); -DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); -DocumentUri GetLsDocumentUri(DB *db, int file_id); - -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); -std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, - SymbolRef sym, int file_id); -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, - const std::vector &uses); -// Returns a symbol. The symbol will *NOT* have a location assigned. -std::optional GetSymbolInfo(DB *db, SymbolIdx sym, - bool detailed); - -std::vector FindSymbolsAtLocation(WorkingFile *working_file, - QueryFile *file, - Position &ls_pos, - bool smallest = false); - -template void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) { - switch (sym.kind) { - case Kind::Invalid: - case Kind::File: - break; - case Kind::Func: - fn(db->GetFunc(sym)); - break; - case Kind::Type: - fn(db->GetType(sym)); - break; - case Kind::Var: - fn(db->GetVar(sym)); - break; - } -} - -template void EachEntityDef(DB *db, SymbolIdx sym, Fn &&fn) { - WithEntity(db, sym, [&](const auto &entity) { - for (auto &def : entity.def) - if (!fn(def)) - break; - }); -} - -template -void EachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) { - WithEntity(db, sym, [&](const auto &entity) { - for (Use use : entity.uses) - fn(use); - if (include_decl) { - for (auto &def : entity.def) - if (def.spell) - fn(*def.spell); - for (Use use : entity.declarations) - fn(use); - } - }); -} - -SymbolKind GetSymbolKind(DB *db, SymbolIdx sym); - -template -void EachDefinedFunc(DB *db, const std::vector &usrs, Fn &&fn) { - for (Usr usr : usrs) { - auto &obj = db->Func(usr); - if (!obj.def.empty()) - fn(obj); - } -} -} // namespace ccls From 72ee893d2661e569d084f7380fe30e7d0ab9d17c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 26 Nov 2018 23:07:28 -0800 Subject: [PATCH 307/378] Merge maybe.hh into utils.hh --- src/indexer.hh | 1 - src/maybe.hh | 60 ----------------------------------------------- src/position.hh | 1 - src/serializer.hh | 2 +- src/utils.hh | 39 ++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 63 deletions(-) delete mode 100644 src/maybe.hh diff --git a/src/indexer.hh b/src/indexer.hh index 55bc1ffb0..b0ea2de19 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -16,7 +16,6 @@ limitations under the License. #pragma once #include "lsp.hh" -#include "maybe.hh" #include "position.hh" #include "serializer.hh" #include "utils.hh" diff --git a/src/maybe.hh b/src/maybe.hh deleted file mode 100644 index e62f27924..000000000 --- a/src/maybe.hh +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include - -#include - -namespace ccls { -// Like std::optional, but the stored data is responsible for containing the -// empty state. T should define a function `bool T::Valid()`. -template class Maybe { - T storage; - -public: - constexpr Maybe() = default; - Maybe(const Maybe &) = default; - Maybe(std::nullopt_t) {} - Maybe(const T &x) : storage(x) {} - Maybe(T &&x) : storage(std::forward(x)) {} - - Maybe &operator=(const Maybe &) = default; - Maybe &operator=(const T &x) { - storage = x; - return *this; - } - - const T *operator->() const { return &storage; } - T *operator->() { return &storage; } - const T &operator*() const { return storage; } - T &operator*() { return storage; } - - bool Valid() const { return storage.Valid(); } - explicit operator bool() const { return Valid(); } - operator std::optional() const { - if (Valid()) - return storage; - return std::nullopt; - } - - void operator=(std::optional &&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); } -}; -} // namespace ccls diff --git a/src/position.hh b/src/position.hh index e595e1ed3..11075e90a 100644 --- a/src/position.hh +++ b/src/position.hh @@ -15,7 +15,6 @@ limitations under the License. #pragma once -#include "maybe.hh" #include "utils.hh" #include diff --git a/src/serializer.hh b/src/serializer.hh index b57dbfae4..dc469d309 100644 --- a/src/serializer.hh +++ b/src/serializer.hh @@ -15,7 +15,7 @@ limitations under the License. #pragma once -#include "maybe.hh" +#include "utils.hh" #include diff --git a/src/utils.hh b/src/utils.hh index d6d079664..fcda9d8e7 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -21,6 +21,7 @@ limitations under the License. #include #include #include +#include #include namespace llvm { @@ -99,4 +100,42 @@ inline void hash_combine(std::size_t &seed, const T &v, Rest... rest) { } std::string GetDefaultResourceDirectory(); + +// Like std::optional, but the stored data is responsible for containing the +// empty state. T should define a function `bool T::Valid()`. +template class Maybe { + T storage; + +public: + constexpr Maybe() = default; + Maybe(const Maybe &) = default; + Maybe(std::nullopt_t) {} + Maybe(const T &x) : storage(x) {} + Maybe(T &&x) : storage(std::forward(x)) {} + + Maybe &operator=(const Maybe &) = default; + Maybe &operator=(const T &x) { + storage = x; + return *this; + } + + const T *operator->() const { return &storage; } + T *operator->() { return &storage; } + const T &operator*() const { return storage; } + T &operator*() { return storage; } + + bool Valid() const { return storage.Valid(); } + explicit operator bool() const { return Valid(); } + operator std::optional() const { + if (Valid()) + return storage; + return std::nullopt; + } + + void operator=(std::optional &&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); } +}; } // namespace ccls From a37782dc0ccff51805538a6fe0810d121fc2c809 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 27 Nov 2018 09:19:22 -0800 Subject: [PATCH 308/378] Fix ComputeGuessScore and delete dead code Thanks to CXuesong --- src/project.cc | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/project.cc b/src/project.cc index 3f1df4078..cc23c238e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -268,7 +268,7 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { e.filename = file; e.args = GetCompilerArgumentForFile(file); if (e.args.empty()) - e.args.push_back("%clang"); // Add a Dummy. + e.args.push_back("%clang"); e.args.push_back(Intern(e.filename)); proc.Process(e); result.push_back(e); @@ -376,7 +376,7 @@ LoadEntriesFromDirectory(ProjectConfig *project, // argument guessing. int ComputeGuessScore(std::string_view a, std::string_view b) { // Increase score based on common prefix and suffix. Prefixes are prioritized. - if (a.size() < b.size()) + if (a.size() > b.size()) std::swap(a, b); size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); @@ -419,19 +419,6 @@ void Project::Load(const std::string &root) { } } -void Project::SetArgsForFile(const std::vector &args, - const std::string &path) { - std::lock_guard lock(mutex_); - for (auto &[root, folder] : root2folder) { - auto it = folder.path2entry_index.find(path); - if (it != folder.path2entry_index.end()) { - // The entry already exists in the project, just set the flags. - folder.entries[it->second].args = args; - return; - } - } -} - Project::Entry Project::FindEntry(const std::string &path, bool can_be_inferred) { std::lock_guard lock(mutex_); From e5b4a404df94efe512442b32b47e0ffe7394f106 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Nov 2018 10:11:14 -0800 Subject: [PATCH 309/378] completion: use Text for Macro{Instantiation,Definition} --- src/messages/textDocument_completion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index bb6562981..7dd4f9db1 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -264,7 +264,7 @@ CompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { case CXCursor_MacroInstantiation: case CXCursor_MacroDefinition: - return CompletionItemKind::Interface; + return CompletionItemKind::Text; case CXCursor_Namespace: case CXCursor_NamespaceAlias: From ab48663ca0e7b82989fb18775d6d92cb9c6df639 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Nov 2018 22:44:52 -0800 Subject: [PATCH 310/378] Refactor WorkingFiles and CompletionManager * WorkingFiles::files : vector -> unordered_map * Add timestamp to WorkingFile * Rename "comp-preload" thread to "preamble" * Rename CompletionManager to SemaManager as it is used by "diag" "comp" "preamble" * Rename clang_complete.* to sema_manager.* * Merge SemaManager::{preloads,sessions} * Add initialization option session.maxNum * In DiagnosticMain, if an included file was modified, cancel the DiagTask and create a PreambleTask instead. The task sets `from_diag` so as to trigger immediate DiagTask after the preamble is built. --- CMakeLists.txt | 2 +- src/config.hh | 7 +- src/indexer.cc | 9 +- src/indexer.hh | 4 +- src/message_handler.hh | 4 +- src/messages/ccls_call.cc | 7 +- src/messages/ccls_inheritance.cc | 5 +- src/messages/ccls_member.cc | 7 +- src/messages/ccls_navigate.cc | 13 +- src/messages/ccls_reload.cc | 4 +- src/messages/ccls_vars.cc | 7 +- src/messages/initialize.cc | 6 +- src/messages/textDocument_code.cc | 12 +- src/messages/textDocument_completion.cc | 14 +- src/messages/textDocument_definition.cc | 10 +- src/messages/textDocument_did.cc | 24 +- src/messages/textDocument_document.cc | 19 +- src/messages/textDocument_foldingRange.cc | 2 +- src/messages/textDocument_formatting.cc | 28 +- src/messages/textDocument_hover.cc | 9 +- src/messages/textDocument_references.cc | 10 +- src/messages/textDocument_rename.cc | 11 +- src/messages/textDocument_signatureHelp.cc | 15 +- src/messages/workspace.cc | 17 +- src/pipeline.cc | 30 +- src/pipeline.hh | 4 +- src/project.cc | 3 +- src/query.cc | 3 +- src/{clang_complete.cc => sema_manager.cc} | 311 +++++++++++---------- src/{clang_complete.hh => sema_manager.hh} | 106 +++---- src/test.cc | 8 +- src/working_files.cc | 79 +++--- src/working_files.hh | 39 +-- 33 files changed, 388 insertions(+), 441 deletions(-) rename src/{clang_complete.cc => sema_manager.cc} (70%) rename src/{clang_complete.hh => sema_manager.hh} (58%) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa1168169..01f49968b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,6 @@ file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h target_sources(ccls PRIVATE third_party/siphash.cc) target_sources(ccls PRIVATE - src/clang_complete.cc src/clang_tu.cc src/config.cc src/filesystem.cc @@ -197,6 +196,7 @@ target_sources(ccls PRIVATE src/position.cc src/project.cc src/query.cc + src/sema_manager.cc src/serializer.cc src/test.cc src/utils.cc diff --git a/src/config.hh b/src/config.hh index 26574d150..1185697fd 100644 --- a/src/config.hh +++ b/src/config.hh @@ -240,6 +240,10 @@ struct Config { std::vector whitelist; } index; + struct Session { + int maxNum = 10; + } session; + struct WorkspaceSymbol { int caseSensitivity = 1; // Maximum workspace search results. @@ -273,12 +277,13 @@ MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, initialWhitelist, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, threads, trackDependency, whitelist); +MAKE_REFLECT_STRUCT(Config::Session, maxNum); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat, clang, client, codeLens, completion, diagnostics, highlight, - index, workspaceSymbol, xref); + index, session, workspaceSymbol, xref); extern Config *g_config; diff --git a/src/indexer.cc b/src/indexer.cc index b833589f6..ea9f3ca44 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -15,11 +15,11 @@ limitations under the License. #include "indexer.hh" -#include "clang_complete.hh" #include "clang_tu.hh" #include "log.hh" #include "pipeline.hh" #include "platform.hh" +#include "sema_manager.hh" #include "serializer.hh" #include @@ -1232,10 +1232,11 @@ void Init() { } std::vector> -Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, +Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, - const std::vector> &remapped, bool &ok) { + const std::vector> &remapped, + bool &ok) { ok = true; auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = llvm::vfs::getRealFileSystem(); @@ -1266,7 +1267,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, bool done_remap = false; #if 0 std::shared_ptr session = - completion->TryGetSession(file, false, false); + manager->TryGetSession(file, false, false); if (session) if (auto preamble = session->GetPreamble()) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(buf)); diff --git a/src/indexer.hh b/src/indexer.hh index b0ea2de19..8e55f6669 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -324,14 +324,14 @@ struct IndexFile { std::string ToString(); }; -struct CompletionManager; +struct SemaManager; struct WorkingFiles; struct VFS; namespace idx { void Init(); std::vector> -Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs, +Index(SemaManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, const std::vector> &remapped, diff --git a/src/message_handler.hh b/src/message_handler.hh index 8eca93754..14e64eafd 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -24,7 +24,7 @@ limitations under the License. #include namespace ccls { -struct CompletionManager; +struct SemaManager; struct VFS; struct IncludeComplete; struct Project; @@ -205,7 +205,7 @@ struct ReplyOnce { }; struct MessageHandler { - CompletionManager *clang_complete = nullptr; + SemaManager *manager = nullptr; DB *db = nullptr; IncludeComplete *include_complete = nullptr; Project *project = nullptr; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index f3a059f0b..68acc942c 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -201,11 +201,10 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { param.levels); } else { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { if (sym.kind == Kind::Func) { result = BuildInitial(this, sym.usr, param.callee, param.callType, param.qualified, param.levels); diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index fa453379c..5352a43a2 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -149,9 +149,8 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = m->wfiles->GetFileByFilename(file->def->path); - - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) + WorkingFile *wf = m->wfiles->GetFile(file->def->path); + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) if (sym.kind == Kind::Func || sym.kind == Kind::Type) { result = BuildInitial(m, sym, param.derived, param.qualified, param.levels); diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index da7db980c..b204584da 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -282,11 +282,10 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { result.reset(); } else { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(wfile, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { switch (sym.kind) { case Kind::Func: case Kind::Type: diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 78b6fa749..991823f63 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -43,14 +43,13 @@ void MessageHandler::ccls_navigate(Reader &reader, Param param; Reflect(reader, param); QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); Position ls_pos = param.position; - if (wfile && wfile->index_lines.size()) - if (auto line = wfile->GetIndexPosFromBufferPos(ls_pos.line, - &ls_pos.character, false)) + if (wf->index_lines.size()) + if (auto line = + wf->GetIndexPosFromBufferPos(ls_pos.line, &ls_pos.character, false)) ls_pos.line = *line; Pos pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; @@ -97,7 +96,7 @@ void MessageHandler::ccls_navigate(Reader &reader, } std::vector result; if (res) - if (auto ls_range = GetLsRange(wfile, *res)) { + if (auto ls_range = GetLsRange(wf, *res)) { Location &ls_loc = result.emplace_back(); ls_loc.uri = param.textDocument.uri; ls_loc.range = *ls_range; diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index d48d23c9e..0ca2d446f 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -13,10 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" +#include "sema_manager.hh" #include "working_files.hh" #include @@ -40,7 +40,7 @@ void MessageHandler::ccls_reload(Reader &reader) { vfs->Clear(); db->clear(); project->Index(wfiles, RequestId()); - clang_complete->FlushAllSessions(); + manager->Clear(); return; } } diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index ec13840ca..560a07e29 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -32,13 +32,12 @@ void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); std::vector result; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { Usr usr = sym.usr; switch (sym.kind) { default: diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 4582e4ac6..0f8f6ca82 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" +#include "sema_manager.hh" #include "filesystem.hh" #include "include_complete.hh" #include "log.hh" @@ -241,7 +241,7 @@ void *Indexer(void *arg_) { delete arg; std::string name = "indexer" + std::to_string(idx); set_thread_name(name.c_str()); - pipeline::Indexer_Main(h->clang_complete, h->vfs, h->project, h->wfiles); + pipeline::Indexer_Main(h->manager, h->vfs, h->project, h->wfiles); return nullptr; } } // namespace @@ -337,6 +337,8 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { LOG_S(INFO) << "dispatch initial index requests"; m->project->Index(m->wfiles, reply.id); + + m->manager->sessions.SetCapacity(g_config->session.maxNum); } void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index 9f59fcc30..aa45e134c 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -33,13 +33,12 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); } void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { - WorkingFile *wf = - wfiles->GetFileByFilename(param.textDocument.uri.GetPath()); + WorkingFile *wf = wfiles->GetFile(param.textDocument.uri.GetPath()); if (!wf) return; std::vector result; std::vector diagnostics; - wfiles->DoAction([&]() { diagnostics = wf->diagnostics_; }); + wfiles->WithLock([&]() { diagnostics = wf->diagnostics; }); for (Diagnostic &diag : diagnostics) if (diag.fixits_.size() && (param.range.Intersects(diag.range) || @@ -97,9 +96,8 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, std::string path = param.textDocument.uri.GetPath(); QueryFile *file = FindFile(reply, path); - WorkingFile *wfile = - file ? wfiles->GetFileByFilename(file->def->path) : nullptr; - if (!wfile) { + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) { return; } @@ -107,7 +105,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, bool force_display = false) { if (!num && !force_display) return; - std::optional ls_range = GetLsRange(wfile, range); + std::optional ls_range = GetLsRange(wf, range); if (!ls_range) return; CodeLens &code_lens = result.emplace_back(); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 7dd4f9db1..a371c7535 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -13,12 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" #include "fuzzy_match.hh" #include "include_complete.hh" #include "log.hh" #include "message_handler.hh" #include "pipeline.hh" +#include "sema_manager.hh" #include "working_files.hh" #include @@ -451,7 +451,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, static CompleteConsumerCache> cache; CompletionList result; std::string path = param.textDocument.uri.GetPath(); - WorkingFile *file = wfiles->GetFileByFilename(path); + WorkingFile *file = wfiles->GetFile(path); if (!file) { return; } @@ -523,7 +523,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, } #endif - CompletionManager::OnComplete callback = + SemaManager::OnComplete callback = [filter, path, begin_pos, end_pos, reply, buffer_line](CodeCompleteConsumer *OptConsumer) { if (!OptConsumer) @@ -548,11 +548,9 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, cache.WithLock([&]() { Consumer.ls_items = cache.result; }); callback(&Consumer); } else { - clang_complete->completion_request_.PushBack( - std::make_unique( - reply.id, param.textDocument, begin_pos, - std::make_unique(CCOpts, false), CCOpts, - callback)); + manager->comp_tasks.PushBack(std::make_unique( + reply.id, param.textDocument.uri.GetPath(), begin_pos, + std::make_unique(CCOpts, false), CCOpts, callback)); } } } // namespace ccls diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 0c7b853e3..93fbd5144 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -49,15 +49,15 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; std::vector result; Maybe on_def; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); Position &ls_pos = param.position; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos, true)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, ls_pos, true)) { // Special cases which are handled: // - symbol has declaration but no definition (ie, pure virtual) // - goto declaration while in definition of recursive type @@ -108,7 +108,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, // Find the best match of the identifier at point. if (!range) { Position position = param.position; - const std::string &buffer = wfile->buffer_content; + const std::string &buffer = wf->buffer_content; std::string_view query = LexIdentifierAroundPos(position, buffer); std::string_view short_query = query; { @@ -172,7 +172,7 @@ void MessageHandler::textDocument_typeDefinition( QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path); + WorkingFile *working_file = wfiles->GetFile(file->def->path); std::vector result; auto Add = [&](const QueryType &type) { diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 0a8bbff1c..3677bba86 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -13,11 +13,11 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" #include "include_complete.hh" #include "message_handler.hh" #include "pipeline.hh" #include "project.hh" +#include "sema_manager.hh" #include "working_files.hh" namespace ccls { @@ -26,31 +26,31 @@ void MessageHandler::textDocument_didChange(TextDocumentDidChangeParam ¶m) { wfiles->OnChange(param); if (g_config->index.onChange) pipeline::Index(path, {}, IndexMode::OnChange); - clang_complete->NotifyView(path); + manager->OnView(path); if (g_config->diagnostics.onChange >= 0) - clang_complete->DiagnosticsUpdate(path, g_config->diagnostics.onChange); + manager->ScheduleDiag(path, g_config->diagnostics.onChange); } void MessageHandler::textDocument_didClose(TextDocumentParam ¶m) { std::string path = param.textDocument.uri.GetPath(); - wfiles->OnClose(param.textDocument); - clang_complete->OnClose(path); + wfiles->OnClose(path); + manager->OnClose(path); } void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { std::string path = param.textDocument.uri.GetPath(); - WorkingFile *working_file = wfiles->OnOpen(param.textDocument); + WorkingFile *wf = wfiles->OnOpen(param.textDocument); if (std::optional cached_file_contents = pipeline::LoadIndexedContent(path)) - working_file->SetIndexContent(*cached_file_contents); + wf->SetIndexContent(*cached_file_contents); ReplyOnce reply; QueryFile *file = FindFile(reply, path); if (file) { - EmitSkippedRanges(working_file, *file); - EmitSemanticHighlight(db, working_file, *file); + EmitSkippedRanges(wf, *file); + EmitSemanticHighlight(db, wf, *file); } - include_complete->AddFile(working_file->filename); + include_complete->AddFile(wf->filename); // Submit new index request if it is not a header file or there is no // pending index request. @@ -59,12 +59,12 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { !pipeline::pending_index_requests) pipeline::Index(path, {}, IndexMode::Normal); - clang_complete->NotifyView(path); + manager->OnView(path); } void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) { const std::string &path = param.textDocument.uri.GetPath(); pipeline::Index(path, {}, IndexMode::Normal); - clang_complete->NotifySave(path); + manager->OnSave(path); } } // namespace ccls diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index d8a07f0ff..5ad1b26ba 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -45,14 +45,13 @@ void MessageHandler::textDocument_documentHighlight( TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); std::vector result; - std::vector syms = - FindSymbolsAtLocation(wfile, file, param.position, true); + FindSymbolsAtLocation(wf, file, param.position, true); for (auto [sym, refcnt] : file->symbol2refcnt) { if (refcnt <= 0) continue; @@ -90,7 +89,7 @@ MAKE_REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFileByFilename(file->def->path) : nullptr; + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; if (!wf) { reply.Error(ErrorCode::InternalError, "not opened"); return; @@ -165,10 +164,8 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, int file_id; QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); - if (!file) - return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!wfile) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; if (param.startLine >= 0) { @@ -193,14 +190,14 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, continue; auto &ds = r.first->second; ds = std::make_unique(); - if (auto range = GetLsRange(wfile, sym.range)) { + if (auto range = GetLsRange(wf, sym.range)) { ds->selectionRange = *range; ds->range = ds->selectionRange; // For a macro expansion, M(name), we may use `M` for extent and `name` // for spell, do the check as selectionRange must be a subrange of // range. if (sym.extent.Valid()) - if (auto range1 = GetLsRange(wfile, sym.extent); + if (auto range1 = GetLsRange(wf, sym.extent); range1 && range1->Includes(*range)) ds->range = *range1; } diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index 62a62fe3b..bf1c1ffcc 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -34,7 +34,7 @@ void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); if (!file) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); + WorkingFile *wfile = wfiles->GetFile(file->def->path); if (!wfile) return; std::vector result; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 271d1a1d1..4d86898e3 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -81,41 +81,35 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!wfile) - return; - Format(reply, wfile, {0, (unsigned)wfile->buffer_content.size()}); + Format(reply, wf, {0, (unsigned)wf->buffer_content.size()}); } void MessageHandler::textDocument_onTypeFormatting( DocumentOnTypeFormattingParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) - return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!wfile) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - std::string_view code = wfile->buffer_content; + std::string_view code = wf->buffer_content; int pos = GetOffsetForPosition(param.position, code); auto lbrace = code.find_last_of('{', pos); if (lbrace == std::string::npos) lbrace = pos; - Format(reply, wfile, {(unsigned)lbrace, unsigned(pos - lbrace)}); + Format(reply, wf, {(unsigned)lbrace, unsigned(pos - lbrace)}); } void MessageHandler::textDocument_rangeFormatting( DocumentRangeFormattingParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!wfile) - return; - std::string_view code = wfile->buffer_content; + std::string_view code = wf->buffer_content; int begin = GetOffsetForPosition(param.range.start, code), end = GetOffsetForPosition(param.range.end, code); - Format(reply, wfile, {(unsigned)begin, unsigned(end - begin)}); + Format(reply, wf, {(unsigned)begin, unsigned(end - begin)}); } } // namespace ccls diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 182104de4..89ecd9b35 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -94,15 +94,14 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, ReplyOnce &reply) { QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); Hover result; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { std::optional ls_range = - GetLsRange(wfiles->GetFileByFilename(file->def->path), sym.range); + GetLsRange(wfiles->GetFile(file->def->path), sym.range); if (!ls_range) continue; diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index b3604068f..db026eb0c 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -45,10 +45,8 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { ReferenceParam param; Reflect(reader, param); QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) - return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); - if (!wfile) + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; for (auto &folder : param.folders) EnsureEndsInSlash(folder); @@ -58,7 +56,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { std::unordered_set seen_uses; int line = param.position.line; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { // Found symbol. Return references. std::unordered_set seen; seen.insert(sym.usr); @@ -107,7 +105,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { // = 0, // use the current filename. std::string path; - if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1) + if (line == 0 || line >= (int)wf->buffer_lines.size() - 1) path = file->def->path; for (const IndexInclude &include : file->def->includes) if (include.line == param.position.line) { diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 2274e872f..e6ea5b96c 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -38,7 +38,7 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, const std::string &path = file.def->path; path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path); - WorkingFile *working_file = wfiles->GetFileByFilename(path); + WorkingFile *working_file = wfiles->GetFile(path); if (working_file) path_to_edit[file_id].textDocument.version = working_file->version; } @@ -56,14 +56,13 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, } // namespace void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { - int file_id; - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); - if (!file) + QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) return; - WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path); WorkspaceEdit result; - for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { result = BuildWorkspaceEdit(db, wfiles, sym, param.newName); break; } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index b3fa946fa..21238898f 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -13,9 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" #include "message_handler.hh" #include "pipeline.hh" +#include "sema_manager.hh" #include @@ -156,14 +156,14 @@ void MessageHandler::textDocument_signatureHelp( std::string path = param.textDocument.uri.GetPath(); Position begin_pos = param.position; - if (WorkingFile *file = wfiles->GetFileByFilename(path)) { + if (WorkingFile *file = wfiles->GetFile(path)) { std::string completion_text; Position end_pos = param.position; begin_pos = file->FindStableCompletionSource(param.position, &completion_text, &end_pos); } - CompletionManager::OnComplete callback = + SemaManager::OnComplete callback = [reply, path, begin_pos](CodeCompleteConsumer *OptConsumer) { if (!OptConsumer) return; @@ -187,11 +187,10 @@ void MessageHandler::textDocument_signatureHelp( cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); callback(&Consumer); } else { - clang_complete->completion_request_.PushBack( - std::make_unique( - reply.id, param.textDocument, param.position, - std::make_unique(CCOpts, false), CCOpts, - callback)); + manager->comp_tasks.PushBack(std::make_unique( + reply.id, param.textDocument.uri.GetPath(), param.position, + std::make_unique(CCOpts, false), CCOpts, + callback)); } } } // namespace ccls diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 05d6488b4..d4b4da582 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" +#include "sema_manager.hh" #include "fuzzy_match.hh" #include "log.hh" #include "message_handler.hh" @@ -37,29 +37,28 @@ void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { project->Load(folder); project->Index(wfiles, RequestId()); - clang_complete->FlushAllSessions(); + manager->Clear(); }; void MessageHandler::workspace_didChangeWatchedFiles( DidChangeWatchedFilesParam ¶m) { for (auto &event : param.changes) { std::string path = event.uri.GetPath(); - IndexMode mode = wfiles->GetFileByFilename(path) - ? IndexMode::Normal - : IndexMode::NonInteractive; + IndexMode mode = + wfiles->GetFile(path) ? IndexMode::Normal : IndexMode::NonInteractive; switch (event.type) { case FileChangeType::Created: case FileChangeType::Changed: { pipeline::Index(path, {}, mode); if (mode == IndexMode::Normal) - clang_complete->NotifySave(path); + manager->OnSave(path); else - clang_complete->OnClose(path); + manager->OnClose(path); break; } case FileChangeType::Deleted: pipeline::Index(path, {}, mode); - clang_complete->OnClose(path); + manager->OnClose(path); break; } } @@ -91,7 +90,7 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( project->Index(wfiles, RequestId()); - clang_complete->FlushAllSessions(); + manager->Clear(); } namespace { diff --git a/src/pipeline.cc b/src/pipeline.cc index 2c7b54f82..c7f8aa7ce 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -15,7 +15,6 @@ limitations under the License. #include "pipeline.hh" -#include "clang_complete.hh" #include "config.hh" #include "include_complete.hh" #include "log.hh" @@ -25,6 +24,7 @@ limitations under the License. #include "platform.hh" #include "project.hh" #include "query.hh" +#include "sema_manager.hh" #include "serializers/json.hh" #include @@ -179,7 +179,7 @@ std::mutex &GetFileMutex(const std::string &path) { return mutexes[std::hash()(path) % N_MUTEXES]; } -bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, +bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) @@ -376,11 +376,11 @@ void Init() { for_stdout = new ThreadedQueue(stdout_waiter); } -void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, +void Indexer_Main(SemaManager *manager, VFS *vfs, Project *project, WorkingFiles *wfiles) { GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); while (true) - if (!Indexer_Parse(completion, wfiles, project, vfs, matcher)) + if (!Indexer_Parse(manager, wfiles, project, vfs, matcher)) indexer_waiter->Wait(index_request); } @@ -388,13 +388,13 @@ void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { if (update->refresh) { LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; - std::lock_guard lock(wfiles->files_mutex); - for (auto &f : wfiles->files) { - std::string filename = LowerPathIfInsensitive(f->filename); - if (db->name2file_id.find(filename) == db->name2file_id.end()) + std::lock_guard lock(wfiles->mutex); + for (auto &[f, wf] : wfiles->files) { + std::string path = LowerPathIfInsensitive(f); + if (db->name2file_id.find(path) == db->name2file_id.end()) continue; - QueryFile &file = db->files[db->name2file_id[filename]]; - EmitSemanticHighlight(db, f.get(), file); + QueryFile &file = db->files[db->name2file_id[path]]; + EmitSemanticHighlight(db, wf.get(), file); } return; } @@ -407,7 +407,7 @@ void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { auto &def_u = *update->files_def_update; - if (WorkingFile *wfile = wfiles->GetFileByFilename(def_u.first.path)) { + if (WorkingFile *wfile = wfiles->GetFile(def_u.first.path)) { // FIXME With index.onChange: true, use buffer_content only for // request.path wfile->SetIndexContent(g_config->index.onChange ? wfile->buffer_content @@ -495,7 +495,7 @@ void MainLoop() { WorkingFiles wfiles; VFS vfs; - CompletionManager clang_complete( + SemaManager manager( &project, &wfiles, [&](std::string path, std::vector diagnostics) { PublishDiagnosticParam params; @@ -521,7 +521,7 @@ void MainLoop() { handler.project = &project; handler.vfs = &vfs; handler.wfiles = &wfiles; - handler.clang_complete = &clang_complete; + handler.manager = &manager; handler.include_complete = &include_complete; bool has_indexed = false; @@ -557,12 +557,16 @@ void Standalone(const std::string &root) { Project project; WorkingFiles wfiles; VFS vfs; + SemaManager manager( + nullptr, nullptr, [&](std::string, std::vector) {}, + [](RequestId id) {}); IncludeComplete complete(&project); MessageHandler handler; handler.project = &project; handler.wfiles = &wfiles; handler.vfs = &vfs; + handler.manager = &manager; handler.include_complete = &complete; StandaloneInitialize(handler, root); diff --git a/src/pipeline.hh b/src/pipeline.hh index 93b51d1d3..c75a371f0 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -10,7 +10,7 @@ #include namespace ccls { -struct CompletionManager; +struct SemaManager; struct GroupMatch; struct Project; struct WorkingFiles; @@ -41,7 +41,7 @@ extern int64_t tick; void Init(); void LaunchStdin(); void LaunchStdout(); -void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, +void Indexer_Main(SemaManager *manager, VFS *vfs, Project *project, WorkingFiles *wfiles); void MainLoop(); void Standalone(const std::string &root); diff --git a/src/project.cc b/src/project.cc index cc23c238e..c2c23a6cb 100644 --- a/src/project.cc +++ b/src/project.cc @@ -485,8 +485,7 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { std::string reason; if (match.Matches(entry.filename, &reason) && match_i.Matches(entry.filename, &reason)) { - bool interactive = - wfiles->GetFileByFilename(entry.filename) != nullptr; + bool interactive = wfiles->GetFile(entry.filename) != nullptr; pipeline::Index( entry.filename, entry.args, interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); diff --git a/src/query.cc b/src/query.cc index 0f767b159..036cba602 100644 --- a/src/query.cc +++ b/src/query.cc @@ -669,8 +669,7 @@ DocumentUri GetLsDocumentUri(DB *db, int file_id) { std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) { std::string path; DocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); - std::optional range = - GetLsRange(wfiles->GetFileByFilename(path), use.range); + std::optional range = GetLsRange(wfiles->GetFile(path), use.range); if (!range) return std::nullopt; return Location{uri, *range}; diff --git a/src/clang_complete.cc b/src/sema_manager.cc similarity index 70% rename from src/clang_complete.cc rename to src/sema_manager.cc index 3132a5233..f5dee4119 100644 --- a/src/clang_complete.cc +++ b/src/sema_manager.cc @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "clang_complete.hh" +#include "sema_manager.hh" #include "clang_tu.hh" #include "filesystem.hh" @@ -81,6 +81,8 @@ TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L, return edit; } +using IncludeStructure = std::vector>; + struct PreambleStatCache { llvm::StringMap> Cache; @@ -132,11 +134,13 @@ struct PreambleStatCache { }; struct PreambleData { - PreambleData(clang::PrecompiledPreamble P, std::vector diags, + PreambleData(clang::PrecompiledPreamble P, IncludeStructure includes, + std::vector diags, std::unique_ptr stat_cache) - : Preamble(std::move(P)), diags(std::move(diags)), - stat_cache(std::move(stat_cache)) {} + : Preamble(std::move(P)), includes(std::move(includes)), + diags(std::move(diags)), stat_cache(std::move(stat_cache)) {} clang::PrecompiledPreamble Preamble; + IncludeStructure includes; std::vector diags; std::unique_ptr stat_cache; }; @@ -173,7 +177,40 @@ CharSourceRange DiagnosticRange(const clang::Diagnostic &D, const LangOptions &L return R; } +class StoreInclude : public PPCallbacks { + const SourceManager &SM; + IncludeStructure &out; + DenseSet Seen; +public: + StoreInclude(const SourceManager &SM, IncludeStructure &out) + : SM(SM), out(out) {} + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const clang::Module *Imported +#if LLVM_VERSION_MAJOR >= 7 + , SrcMgr::CharacteristicKind FileKind +#endif + ) override { + (void)SM; + if (File && Seen.insert(File).second) + out.emplace_back(PathFromFileEntry(*File), File->getModificationTime()); + } +}; + +class CclsPreambleCallbacks : public PreambleCallbacks { +public: + void BeforeExecute(CompilerInstance &CI) override { + SM = &CI.getSourceManager(); + } + std::unique_ptr createPPCallbacks() override { + return std::make_unique(*SM, includes); + } + SourceManager *SM = nullptr; + IncludeStructure includes; +}; class StoreDiags : public DiagnosticConsumer { const LangOptions *LangOpts; @@ -262,7 +299,7 @@ class StoreDiags : public DiagnosticConsumer { }; std::unique_ptr BuildCompilerInstance( - CompletionSession &session, std::unique_ptr CI, + Session &session, std::unique_ptr CI, IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, const PreambleData *preamble, const std::string &path, std::unique_ptr &Buf) { @@ -303,16 +340,17 @@ bool Parse(CompilerInstance &Clang) { return true; } -void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, +void BuildPreamble(Session &session, CompilerInvocation &CI, IntrusiveRefCntPtr FS, - const std::string &main, + const SemaManager::PreambleTask &task, std::unique_ptr stat_cache) { std::shared_ptr OldP = session.GetPreamble(); - std::string content = session.wfiles->GetContent(main); + std::string content = session.wfiles->GetContent(task.path); std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(content); auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), Buf.get(), 0); - if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) + if (!task.from_diag && OldP && + OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; // -Werror makes warnings issued as errors, which stops parsing // prematurely because of -ferror-limit=. This also works around the issue @@ -323,70 +361,88 @@ void BuildPreamble(CompletionSession &session, CompilerInvocation &CI, CI.getFrontendOpts().SkipFunctionBodies = true; CI.getLangOpts()->CommentOpts.ParseAllComments = g_config->index.comments > 1; - StoreDiags DC(main); + StoreDiags DC(task.path); IntrusiveRefCntPtr DE = CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &DC, false); - PreambleCallbacks PP; + if (OldP) { + std::lock_guard lock(session.wfiles->mutex); + for (auto &include : OldP->includes) + if (WorkingFile *wf = session.wfiles->GetFileUnlocked(include.first)) + CI.getPreprocessorOpts().addRemappedFile( + include.first, + llvm::MemoryBuffer::getMemBufferCopy(wf->buffer_content).release()); + } + + CclsPreambleCallbacks PC; if (auto NewPreamble = PrecompiledPreamble::Build( - CI, Buf.get(), Bounds, *DE, FS, session.PCH, true, PP)) { + CI, Buf.get(), Bounds, *DE, FS, session.PCH, true, PC)) { + assert(!CI.getPreprocessorOpts().RetainRemappedFileBuffers); + if (OldP) { + auto &old_includes = OldP->includes; + auto it = old_includes.begin(); + std::sort(PC.includes.begin(), PC.includes.end()); + for (auto &include : PC.includes) + if (include.second == 0) { + while (it != old_includes.end() && it->first < include.first) + ++it; + if (it == old_includes.end()) + break; + include.second = it->second; + } + } + std::lock_guard lock(session.mutex); session.preamble = std::make_shared( - std::move(*NewPreamble), DC.Take(), std::move(stat_cache)); + std::move(*NewPreamble), std::move(PC.includes), DC.Take(), + std::move(stat_cache)); } } -void *CompletionPreloadMain(void *manager_) { - auto *manager = static_cast(manager_); - set_thread_name("comp-preload"); +void *PreambleMain(void *manager_) { + auto *manager = static_cast(manager_); + set_thread_name("preamble"); while (true) { - auto request = manager->preload_requests_.Dequeue(); + SemaManager::PreambleTask task = manager->preamble_tasks.Dequeue(); - bool is_open = false; - std::shared_ptr session = - manager->TryGetSession(request.path, true, &is_open); - if (!session) - continue; + bool created = false; + std::shared_ptr session = + manager->EnsureSession(task.path, &created); - const auto &args = session->file.args; auto stat_cache = std::make_unique(); IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); if (std::unique_ptr CI = - BuildCompilerInvocation(args, FS)) - BuildPreamble(*session, *CI, FS, request.path, std::move(stat_cache)); - - int debounce = - is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; - if (debounce >= 0) { - TextDocumentIdentifier document; - document.uri = DocumentUri::FromPath(request.path); - manager->DiagnosticsUpdate(request.path, debounce); + BuildCompilerInvocation(session->file.args, FS)) + BuildPreamble(*session, *CI, FS, task, std::move(stat_cache)); + + if (task.from_diag) { + manager->ScheduleDiag(task.path, 0); + } else { + int debounce = + created ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave; + if (debounce >= 0) + manager->ScheduleDiag(task.path, debounce); } } return nullptr; } void *CompletionMain(void *manager_) { - auto *manager = static_cast(manager_); + auto *manager = static_cast(manager_); set_thread_name("comp"); while (true) { - // Fetching the completion request blocks until we have a request. - std::unique_ptr request = - manager->completion_request_.Dequeue(); + std::unique_ptr task = manager->comp_tasks.Dequeue(); // Drop older requests if we're not buffering. while (g_config->completion.dropOldRequests && - !manager->completion_request_.IsEmpty()) { - manager->on_dropped_(request->id); - request->Consumer.reset(); - request->on_complete(nullptr); - request = manager->completion_request_.Dequeue(); + !manager->comp_tasks.IsEmpty()) { + manager->on_dropped_(task->id); + task->Consumer.reset(); + task->on_complete(nullptr); + task = manager->comp_tasks.Dequeue(); } - std::string path = request->document.uri.GetPath(); - - std::shared_ptr session = - manager->TryGetSession(path, false); + std::shared_ptr session = manager->EnsureSession(task->path); std::shared_ptr preamble = session->GetPreamble(); IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; @@ -395,34 +451,34 @@ void *CompletionMain(void *manager_) { if (!CI) continue; auto &FOpts = CI->getFrontendOpts(); - FOpts.CodeCompleteOpts = request->CCOpts; - FOpts.CodeCompletionAt.FileName = path; - FOpts.CodeCompletionAt.Line = request->position.line + 1; - FOpts.CodeCompletionAt.Column = request->position.character + 1; + FOpts.CodeCompleteOpts = task->CCOpts; + FOpts.CodeCompletionAt.FileName = task->path; + FOpts.CodeCompletionAt.Line = task->position.line + 1; + FOpts.CodeCompletionAt.Column = task->position.character + 1; FOpts.SkipFunctionBodies = true; CI->getLangOpts()->CommentOpts.ParseAllComments = true; DiagnosticConsumer DC; - std::string content = manager->wfiles_->GetContent(path); + std::string content = manager->wfiles->GetContent(task->path); auto Buf = llvm::MemoryBuffer::getMemBuffer(content); bool in_preamble = - GetOffsetForPosition( - {request->position.line, request->position.character}, content) < + GetOffsetForPosition({task->position.line, task->position.character}, + content) < ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0).Size; if (in_preamble) preamble.reset(); auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, - preamble.get(), path, Buf); + preamble.get(), task->path, Buf); if (!Clang) continue; Clang->getPreprocessorOpts().SingleFileParseMode = in_preamble; - Clang->setCodeCompletionConsumer(request->Consumer.release()); + Clang->setCodeCompletionConsumer(task->Consumer.release()); if (!Parse(*Clang)) continue; Buf.release(); - request->on_complete(&Clang->getCodeCompletionConsumer()); + task->on_complete(&Clang->getCodeCompletionConsumer()); } return nullptr; } @@ -456,25 +512,38 @@ void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { } void *DiagnosticMain(void *manager_) { - auto *manager = static_cast(manager_); + auto *manager = static_cast(manager_); set_thread_name("diag"); while (true) { - CompletionManager::DiagnosticRequest request = - manager->diagnostic_request_.Dequeue(); - const std::string &path = request.path; - int64_t wait = request.wait_until - + SemaManager::DiagTask task = manager->diag_tasks.Dequeue(); + int64_t wait = task.wait_until - chrono::duration_cast( chrono::high_resolution_clock::now().time_since_epoch()) .count(); if (wait > 0) - std::this_thread::sleep_for(chrono::duration( - std::min(wait, request.debounce))); + std::this_thread::sleep_for( + chrono::duration(std::min(wait, task.debounce))); - std::shared_ptr session = - manager->TryGetSession(path, false); + std::shared_ptr session = manager->EnsureSession(task.path); std::shared_ptr preamble = session->GetPreamble(); IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; + if (preamble) { + bool rebuild = false; + { + std::lock_guard lock(manager->wfiles->mutex); + for (auto &include : preamble->includes) + if (WorkingFile *wf = manager->wfiles->GetFileUnlocked(include.first); + wf && include.second < wf->timestamp) { + include.second = wf->timestamp; + rebuild = true; + } + } + if (rebuild) { + manager->preamble_tasks.PushBack({task.path, true}, true); + continue; + } + } std::unique_ptr CI = BuildCompilerInvocation(session->file.args, FS); @@ -485,11 +554,11 @@ void *DiagnosticMain(void *manager_) { CI->getDiagnosticOpts().Warnings.push_back("no-unused-function"); CI->getDiagnosticOpts().IgnoreWarnings = false; CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking; - StoreDiags DC(path); - std::string content = manager->wfiles_->GetContent(path); + StoreDiags DC(task.path); + std::string content = manager->wfiles->GetContent(task.path); auto Buf = llvm::MemoryBuffer::getMemBuffer(content); auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, - preamble.get(), path, Buf); + preamble.get(), task.path, Buf); if (!Clang) continue; if (!Parse(*Clang)) @@ -552,36 +621,32 @@ void *DiagnosticMain(void *manager_) { } { - std::lock_guard lock(session->wfiles->files_mutex); - if (WorkingFile *wfile = session->wfiles->GetFileByFilenameNoLock(path)) - wfile->diagnostics_ = ls_diags; + std::lock_guard lock(manager->wfiles->mutex); + if (WorkingFile *wf = manager->wfiles->GetFileUnlocked(task.path)) + wf->diagnostics = ls_diags; } - manager->on_diagnostic_(path, ls_diags); + manager->on_diagnostic_(task.path, ls_diags); } return nullptr; } } // namespace -std::shared_ptr CompletionSession::GetPreamble() { +std::shared_ptr Session::GetPreamble() { std::lock_guard lock(mutex); return preamble; } -CompletionManager::CompletionManager(Project *project, WorkingFiles *wfiles, - OnDiagnostic on_diagnostic, - OnDropped on_dropped) - : project_(project), wfiles_(wfiles), on_diagnostic_(on_diagnostic), - on_dropped_(on_dropped), preloads(kMaxPreloadedSessions), - sessions(kMaxCompletionSessions), - PCH(std::make_shared()) { +SemaManager::SemaManager(Project *project, WorkingFiles *wfiles, + OnDiagnostic on_diagnostic, OnDropped on_dropped) + : project_(project), wfiles(wfiles), on_diagnostic_(on_diagnostic), + on_dropped_(on_dropped), PCH(std::make_shared()) { + SpawnThread(ccls::PreambleMain, this); SpawnThread(ccls::CompletionMain, this); - SpawnThread(ccls::CompletionPreloadMain, this); SpawnThread(ccls::DiagnosticMain, this); } -void CompletionManager::DiagnosticsUpdate(const std::string &path, - int debounce) { +void SemaManager::ScheduleDiag(const std::string &path, int debounce) { static GroupMatch match(g_config->diagnostics.whitelist, g_config->diagnostics.blacklist); if (!match.Matches(path)) @@ -601,78 +666,42 @@ void CompletionManager::DiagnosticsUpdate(const std::string &path, } } if (flag) - diagnostic_request_.PushBack({path, now + debounce, debounce}, false); + diag_tasks.PushBack({path, now + debounce, debounce}, false); } -void CompletionManager::NotifyView(const std::string &path) { - // Only reparse the file if we create a new CompletionSession. - if (EnsureCompletionOrCreatePreloadSession(path)) - preload_requests_.PushBack(PreloadRequest{path}, true); +void SemaManager::OnView(const std::string &path) { + std::lock_guard lock(mutex); + if (!sessions.Get(path)) + preamble_tasks.PushBack(PreambleTask{path}, true); } -void CompletionManager::NotifySave(const std::string &filename) { - EnsureCompletionOrCreatePreloadSession(filename); - preload_requests_.PushBack(PreloadRequest{filename}, true); +void SemaManager::OnSave(const std::string &path) { + preamble_tasks.PushBack(PreambleTask{path}, true); } -void CompletionManager::OnClose(const std::string &filename) { - std::lock_guard lock(sessions_lock_); - preloads.Take(filename); - sessions.Take(filename); -} - -bool CompletionManager::EnsureCompletionOrCreatePreloadSession( - const std::string &path) { - std::lock_guard lock(sessions_lock_); - if (preloads.Get(path) || sessions.Get(path)) - return false; - - // No CompletionSession, create new one. - auto session = std::make_shared( - project_->FindEntry(path, false), wfiles_, PCH); - if (session->file.filename != path) { - session->inferred = true; - session->file.filename = path; - } - preloads.Insert(path, session); - LOG_S(INFO) << "create preload session for " << path; - return true; +void SemaManager::OnClose(const std::string &path) { + std::lock_guard lock(mutex); + sessions.Take(path); } -std::shared_ptr -CompletionManager::TryGetSession(const std::string &path, bool preload, - bool *is_open) { - std::lock_guard lock(sessions_lock_); - std::shared_ptr session = preloads.Get(path); - - if (session) { - if (!preload) { - preloads.Take(path); - sessions.Insert(path, session); - if (is_open) - *is_open = true; - } - return session; - } - - session = sessions.Get(path); - if (!session && !preload) { - session = std::make_shared( - project_->FindEntry(path, false), wfiles_, PCH); - sessions.Insert(path, session); +std::shared_ptr +SemaManager::EnsureSession(const std::string &path, bool *created) { + std::lock_guard lock(mutex); + std::shared_ptr session = sessions.Get(path); + if (!session) { + session = std::make_shared( + project_->FindEntry(path, false), wfiles, PCH); LOG_S(INFO) << "create session for " << path; - if (is_open) - *is_open = true; + sessions.Insert(path, session); + if (created) + *created = true; } - return session; } -void CompletionManager::FlushAllSessions() { - LOG_S(INFO) << "flush all clang complete sessions"; - std::lock_guard lock(sessions_lock_); - - preloads.Clear(); +void SemaManager::Clear() { + LOG_S(INFO) << "clear all sessions"; + std::lock_guard lock(mutex); sessions.Clear(); } } // namespace ccls diff --git a/src/clang_complete.hh b/src/sema_manager.hh similarity index 58% rename from src/clang_complete.hh rename to src/sema_manager.hh index d067818c8..632b2eaa0 100644 --- a/src/clang_complete.hh +++ b/src/sema_manager.hh @@ -54,8 +54,6 @@ TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::FixItHint &FixIt); template struct LruCache { - LruCache(int capacity) : capacity(capacity) {} - std::shared_ptr Get(const K &key) { for (auto it = items.begin(); it != items.end(); ++it) if (it->first == key) { @@ -81,14 +79,14 @@ template struct LruCache { items.emplace(items.begin(), key, std::move(value)); } void Clear() { items.clear(); } + void SetCapacity(int cap) { capacity = cap; } private: std::vector>> items; - int capacity; + int capacity = 1; }; -struct CompletionSession - : public std::enable_shared_from_this { +struct Session { std::mutex mutex; std::shared_ptr preamble; @@ -101,14 +99,14 @@ struct CompletionSession llvm::vfs::getRealFileSystem(); std::shared_ptr PCH; - CompletionSession(const Project::Entry &file, WorkingFiles *wfiles, + Session(const Project::Entry &file, WorkingFiles *wfiles, std::shared_ptr PCH) : file(file), wfiles(wfiles), PCH(PCH) {} std::shared_ptr GetPreamble(); }; -struct CompletionManager { +struct SemaManager { using OnDiagnostic = std::function diagnostics)>; // If OptConsumer is nullptr, the request has been cancelled. @@ -116,91 +114,57 @@ struct CompletionManager { std::function; using OnDropped = std::function; - struct PreloadRequest { + struct PreambleTask { std::string path; + bool from_diag = false; }; - struct CompletionRequest { - CompletionRequest(const RequestId &id, - const TextDocumentIdentifier &document, - const Position &position, - std::unique_ptr Consumer, - clang::CodeCompleteOptions CCOpts, - const OnComplete &on_complete) - : id(id), document(document), position(position), - Consumer(std::move(Consumer)), CCOpts(CCOpts), - on_complete(on_complete) {} + struct CompTask { + CompTask(const RequestId &id, const std::string &path, + const Position &position, + std::unique_ptr Consumer, + clang::CodeCompleteOptions CCOpts, const OnComplete &on_complete) + : id(id), path(path), position(position), Consumer(std::move(Consumer)), + CCOpts(CCOpts), on_complete(on_complete) {} RequestId id; - TextDocumentIdentifier document; + std::string path; Position position; std::unique_ptr Consumer; clang::CodeCompleteOptions CCOpts; OnComplete on_complete; }; - struct DiagnosticRequest { + struct DiagTask { std::string path; int64_t wait_until; int64_t debounce; }; - CompletionManager(Project *project, WorkingFiles *wfiles, + SemaManager(Project *project, WorkingFiles *wfiles, OnDiagnostic on_diagnostic, OnDropped on_dropped); - // Request a diagnostics update. - void DiagnosticsUpdate(const std::string &path, int debounce); - - // Notify the completion manager that |filename| has been viewed and we - // should begin preloading completion data. - void NotifyView(const std::string &path); - // Notify the completion manager that |filename| has been saved. This - // triggers a reparse. - void NotifySave(const std::string &path); - // Notify the completion manager that |filename| has been closed. Any existing - // completion session will be dropped. + void ScheduleDiag(const std::string &path, int debounce); + void OnView(const std::string &path); + void OnSave(const std::string &path); void OnClose(const std::string &path); - - // Ensures there is a completion or preloaded session. Returns true if a new - // session was created. - bool EnsureCompletionOrCreatePreloadSession(const std::string &path); - // Tries to find an edit session for |filename|. This will move the session - // from view to edit. - std::shared_ptr - TryGetSession(const std::string &path, bool preload, bool *is_open = nullptr); - - // Flushes all saved sessions - void FlushAllSessions(void); - - // TODO: make these configurable. - const int kMaxPreloadedSessions = 10; - const int kMaxCompletionSessions = 5; + std::shared_ptr EnsureSession(const std::string &path, + bool *created = nullptr); + void Clear(void); // Global state. Project *project_; - WorkingFiles *wfiles_; + WorkingFiles *wfiles; OnDiagnostic on_diagnostic_; OnDropped on_dropped_; - using LruSessionCache = LruCache; - - // CompletionSession instances which are preloaded, ie, files which the user - // has viewed but not requested code completion for. - LruSessionCache preloads; - // CompletionSession instances which the user has actually performed - // completion on. This is more rare so these instances tend to stay alive - // much longer than the ones in |preloaded_sessions_|. - LruSessionCache sessions; - // Mutex which protects |view_sessions_| and |edit_sessions_|. - std::mutex sessions_lock_; + std::mutex mutex; + LruCache sessions; std::mutex diag_mutex; std::unordered_map next_diag; - // Request a code completion at the given location. - ThreadedQueue> completion_request_; - ThreadedQueue diagnostic_request_; - // Parse requests. The path may already be parsed, in which case it should be - // reparsed. - ThreadedQueue preload_requests_; + ThreadedQueue> comp_tasks; + ThreadedQueue diag_tasks; + ThreadedQueue preamble_tasks; std::shared_ptr PCH; }; @@ -210,16 +174,14 @@ struct CompletionManager { // that happens. template struct CompleteConsumerCache { - // NOTE: Make sure to access these variables under |WithLock|. - std::optional path; - std::optional position; - T result; - std::mutex mutex; + std::string path; + Position position; + T result; - void WithLock(std::function action) { + template void WithLock(Fn &&fn) { std::lock_guard lock(mutex); - action(); + fn(); } bool IsCacheValid(const std::string path, Position position) { std::lock_guard lock(mutex); diff --git a/src/test.cc b/src/test.cc index 491833398..7faf948c8 100644 --- a/src/test.cc +++ b/src/test.cc @@ -15,7 +15,7 @@ limitations under the License. #include "test.hh" -#include "clang_complete.hh" +#include "sema_manager.hh" #include "filesystem.hh" #include "indexer.hh" #include "pipeline.hh" @@ -288,9 +288,9 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by conRequestIdex index(1, 1); - CompletionManager completion(nullptr, nullptr, - [&](std::string, std::vector) {}, - [](RequestId id) {}); + SemaManager completion( + nullptr, nullptr, [&](std::string, std::vector) {}, + [](RequestId id) {}); GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string &path) { diff --git a/src/working_files.cc b/src/working_files.cc index 48004e9c1..0165ee96a 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -21,9 +21,11 @@ limitations under the License. #include #include +#include #include #include #include +namespace chrono = std::chrono; using namespace clang; using namespace llvm; @@ -364,57 +366,53 @@ WorkingFile::FindStableCompletionSource(Position position, return GetPositionForOffset(buffer_content, i); } -WorkingFile *WorkingFiles::GetFileByFilename(const std::string &filename) { - std::lock_guard lock(files_mutex); - return GetFileByFilenameNoLock(filename); +WorkingFile *WorkingFiles::GetFile(const std::string &path) { + std::lock_guard lock(mutex); + return GetFileUnlocked(path); } -WorkingFile * -WorkingFiles::GetFileByFilenameNoLock(const std::string &filename) { - for (auto &file : files) { - if (file->filename == filename) - return file.get(); - } - return nullptr; +WorkingFile *WorkingFiles::GetFileUnlocked(const std::string &path) { + auto it = files.find(path); + return it != files.end() ? it->second.get() : nullptr; } -std::string WorkingFiles::GetContent(const std::string &filename) { - std::lock_guard lock(files_mutex); - for (auto &file : files) - if (file->filename == filename) - return file->buffer_content; - return ""; +std::string WorkingFiles::GetContent(const std::string &path) { + std::lock_guard lock(mutex); + auto it = files.find(path); + return it != files.end() ? it->second->buffer_content : ""; } WorkingFile *WorkingFiles::OnOpen(const TextDocumentItem &open) { - std::lock_guard lock(files_mutex); + std::lock_guard lock(mutex); - std::string filename = open.uri.GetPath(); + std::string path = open.uri.GetPath(); std::string content = open.text; - // The file may already be open. - if (WorkingFile *file = GetFileByFilenameNoLock(filename)) { - file->version = open.version; - file->buffer_content = content; - file->OnBufferContentUpdated(); - return file; + auto &wf = files[path]; + if (wf) { + wf->version = open.version; + wf->buffer_content = content; + wf->OnBufferContentUpdated(); + } else { + wf = std::make_unique(path, content); } - - files.push_back(std::make_unique(filename, content)); - return files[files.size() - 1].get(); + return wf.get(); } void WorkingFiles::OnChange(const TextDocumentDidChangeParam &change) { - std::lock_guard lock(files_mutex); + std::lock_guard lock(mutex); - std::string filename = change.textDocument.uri.GetPath(); - WorkingFile *file = GetFileByFilenameNoLock(filename); + std::string path = change.textDocument.uri.GetPath(); + WorkingFile *file = GetFileUnlocked(path); if (!file) { - LOG_S(WARNING) << "Could not change " << filename - << " because it was not open"; + LOG_S(WARNING) << "Could not change " << path << " because it was not open"; return; } + file->timestamp = chrono::duration_cast( + chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + // version: number | null if (change.textDocument.version) file->version = *change.textDocument.version; @@ -440,20 +438,9 @@ void WorkingFiles::OnChange(const TextDocumentDidChangeParam &change) { } } -void WorkingFiles::OnClose(const TextDocumentIdentifier &close) { - std::lock_guard lock(files_mutex); - - std::string filename = close.uri.GetPath(); - - for (int i = 0; i < files.size(); ++i) { - if (files[i]->filename == filename) { - files.erase(files.begin() + i); - return; - } - } - - LOG_S(WARNING) << "Could not close " << filename - << " because it was not open"; +void WorkingFiles::OnClose(const std::string &path) { + std::lock_guard lock(mutex); + files.erase(path); } // VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent diff --git a/src/working_files.hh b/src/working_files.hh index 95cdf957d..76128254c 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -21,9 +21,11 @@ limitations under the License. #include #include #include +#include namespace ccls { struct WorkingFile { + int64_t timestamp = 0; int version = 0; std::string filename; @@ -41,9 +43,7 @@ struct WorkingFile { std::vector index_to_buffer; std::vector buffer_to_index; // A set of diagnostics that have been reported for this file. - // NOTE: _ is appended because it must be accessed under the WorkingFiles - // lock! - std::vector diagnostics_; + std::vector diagnostics; WorkingFile(const std::string &filename, const std::string &buffer_content); @@ -79,38 +79,21 @@ private: }; struct WorkingFiles { - struct Snapshot { - struct File { - std::string filename; - std::string content; - }; + WorkingFile *GetFile(const std::string &path); + WorkingFile *GetFileUnlocked(const std::string &path); + std::string GetContent(const std::string &path); - std::vector files; - }; - - // - // :: IMPORTANT :: All methods in this class are guarded by a single lock. - // - - // Find the file with the given filename. - WorkingFile *GetFileByFilename(const std::string &filename); - WorkingFile *GetFileByFilenameNoLock(const std::string &filename); - std::string GetContent(const std::string &filename); - - // Run |action| under the lock. - template void DoAction(Fn &&fn) { - std::lock_guard lock(files_mutex); + template void WithLock(Fn &&fn) { + std::lock_guard lock(mutex); fn(); } WorkingFile *OnOpen(const TextDocumentItem &open); void OnChange(const TextDocumentDidChangeParam &change); - void OnClose(const TextDocumentIdentifier &close); + void OnClose(const std::string &close); - // Use unique_ptrs so we can handout WorkingFile ptrs and not have them - // invalidated if we resize files. - std::vector> files; - std::mutex files_mutex; // Protects |files|. + std::mutex mutex; + std::unordered_map> files; }; int GetOffsetForPosition(Position pos, std::string_view content); From 872d7c5de90a09260e06d7d2b24d3a2a6cd62b93 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 1 Dec 2018 16:55:51 -0800 Subject: [PATCH 311/378] Add ReplyOnce::NotReady and error if didOpen is not seen Use IgnoringDiagConsumer to override default TextDiagnosticPrinter --- src/clang_tu.cc | 3 ++- src/message_handler.cc | 31 ++++++++--------------- src/message_handler.hh | 4 +-- src/messages/ccls_call.cc | 2 +- src/messages/ccls_info.cc | 2 +- src/messages/ccls_inheritance.cc | 2 +- src/messages/ccls_member.cc | 6 +++-- src/messages/ccls_navigate.cc | 6 +++-- src/messages/ccls_vars.cc | 6 +++-- src/messages/textDocument_code.cc | 11 ++++---- src/messages/textDocument_completion.cc | 4 ++- src/messages/textDocument_definition.cc | 17 ++++++++----- src/messages/textDocument_did.cc | 3 +-- src/messages/textDocument_document.cc | 16 +++++++----- src/messages/textDocument_foldingRange.cc | 12 ++++----- src/messages/textDocument_formatting.cc | 18 ++++++++----- src/messages/textDocument_hover.cc | 8 +++--- src/messages/textDocument_references.cc | 7 +++-- src/messages/textDocument_rename.cc | 12 +++++---- 19 files changed, 95 insertions(+), 75 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index e6fe3ef92..4092372bf 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -98,7 +98,8 @@ BuildCompilerInvocation(std::vector args, std::string save = "-resource-dir=" + g_config->clang.resourceDir; args.push_back(save.c_str()); IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); + CompilerInstance::createDiagnostics(new DiagnosticOptions, + new IgnoringDiagConsumer, true)); std::unique_ptr CI = createInvocationFromCommandLine(args, Diags, VFS); if (CI) { diff --git a/src/message_handler.cc b/src/message_handler.cc index 2f51e3268..e7f25d2cc 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -107,6 +107,13 @@ struct ScanLineEvent { }; } // namespace +void ReplyOnce::NotReady(bool file) { + if (file) + Error(ErrorCode::InvalidRequest, "not opened"); + else + Error(ErrorCode::InternalError, "not indexed"); +} + void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Reader &)) { method2notification[method] = [this, handler](Reader &reader) { (this->*handler)(reader); @@ -220,14 +227,14 @@ void MessageHandler::Run(InMessage &msg) { try { it->second(reader); } catch (...) { - LOG_S(ERROR) << "failed to process " << msg.method; + ShowMessageParam param{MessageType::Error, + std::string("failed to process ") + msg.method}; + pipeline::Notify(window_showMessage, param); } } } -QueryFile *MessageHandler::FindFile(ReplyOnce &reply, - const std::string &path, - int *out_file_id) { +QueryFile *MessageHandler::FindFile(const std::string &path, int *out_file_id) { QueryFile *ret = nullptr; auto it = db->name2file_id.find(LowerPathIfInsensitive(path)); if (it != db->name2file_id.end()) { @@ -239,24 +246,8 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply, return ret; } } - if (out_file_id) *out_file_id = -1; - - if (reply.id.Valid()) { - bool has_entry = false; - { - std::lock_guard lock(project->mutex_); - for (auto &[root, folder] : project->root2folder) - has_entry |= folder.path2entry_index.count(path); - } - ResponseError err; - if (has_entry) - reply.Error(ErrorCode::ServerNotInitialized, path + " is being indexed"); - else - reply.Error(ErrorCode::InternalError, "unable to find " + path); - } - return ret; } diff --git a/src/message_handler.hh b/src/message_handler.hh index 14e64eafd..d60e44b03 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -202,6 +202,7 @@ struct ReplyOnce { if (id.Valid()) pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); }); } + void NotReady(bool file); }; struct MessageHandler { @@ -217,8 +218,7 @@ struct MessageHandler { MessageHandler(); void Run(InMessage &msg); - QueryFile *FindFile(ReplyOnce &reply, const std::string &path, - int *out_file_id = nullptr); + QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr); private: void Bind(const char *method, void (MessageHandler::*handler)(Reader &)); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 68acc942c..f1e07b74f 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -200,7 +200,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { Expand(this, &*result, param.callee, param.callType, param.qualified, param.levels); } else { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; if (!wf) return; diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 9560f2d95..c48dd5191 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -54,7 +54,7 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) { } void MessageHandler::ccls_fileInfo(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); if (!file) return; diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 5352a43a2..6be44fe4b 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -146,7 +146,7 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { Expand(m, &*result, param.derived, param.qualified, param.levels))) result.reset(); } else { - QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = m->FindFile(param.textDocument.uri.GetPath()); if (!file) return; WorkingFile *wf = m->wfiles->GetFile(file->def->path); diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index b204584da..cae89c861 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -281,10 +281,12 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { param.levels, param.kind))) result.reset(); } else { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { switch (sym.kind) { case Kind::Func: diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 991823f63..d097aa968 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -42,10 +42,12 @@ void MessageHandler::ccls_navigate(Reader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } Position ls_pos = param.position; if (wf->index_lines.size()) if (auto line = diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 560a07e29..bf0cbbf98 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -31,10 +31,12 @@ MAKE_REFLECT_STRUCT(Param, textDocument, position, kind); void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } std::vector result; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index aa45e134c..b96db1aea 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -34,8 +34,10 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { WorkingFile *wf = wfiles->GetFile(param.textDocument.uri.GetPath()); - if (!wf) + if (!wf) { + reply.NotReady(true); return; + } std::vector result; std::vector diagnostics; wfiles->WithLock([&]() { diagnostics = wf->diagnostics; }); @@ -92,15 +94,14 @@ struct CommonCodeLensParams { void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, ReplyOnce &reply) { - std::vector result; - std::string path = param.textDocument.uri.GetPath(); - - QueryFile *file = FindFile(reply, path); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; if (!wf) { + reply.NotReady(file); return; } + std::vector result; auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, bool force_display = false) { if (!num && !force_display) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a371c7535..4691189fe 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -449,13 +449,15 @@ class CompletionConsumer : public CodeCompleteConsumer { void MessageHandler::textDocument_completion(CompletionParam ¶m, ReplyOnce &reply) { static CompleteConsumerCache> cache; - CompletionList result; std::string path = param.textDocument.uri.GetPath(); WorkingFile *file = wfiles->GetFile(path); if (!file) { + reply.NotReady(true); return; } + CompletionList result; + // It shouldn't be possible, but sometimes vscode will send queries out // of order, ie, we get completion request before buffer content update. std::string buffer_line; diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 93fbd5144..62927547c 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -48,10 +48,12 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } std::vector result; Maybe on_def; @@ -169,10 +171,12 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, void MessageHandler::textDocument_typeDefinition( TextDocumentPositionParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!file) { + reply.NotReady(file); return; - WorkingFile *working_file = wfiles->GetFile(file->def->path); + } std::vector result; auto Add = [&](const QueryType &type) { @@ -186,8 +190,7 @@ void MessageHandler::textDocument_typeDefinition( if (auto ls_loc = GetLsLocation(db, wfiles, dr)) result.push_back(*ls_loc); }; - for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, param.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { switch (sym.kind) { case Kind::Var: { const QueryVar::Def *def = db->GetVar(sym).AnyDef(); diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 3677bba86..2dc916290 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -44,8 +44,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { pipeline::LoadIndexedContent(path)) wf->SetIndexContent(*cached_file_contents); - ReplyOnce reply; - QueryFile *file = FindFile(reply, path); + QueryFile *file = FindFile(path); if (file) { EmitSkippedRanges(wf, *file); EmitSemanticHighlight(db, wf, *file); diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 5ad1b26ba..e65a6c772 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -44,10 +44,12 @@ MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role); void MessageHandler::textDocument_documentHighlight( TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } std::vector result; std::vector syms = @@ -88,10 +90,10 @@ MAKE_REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; if (!wf) { - reply.Error(ErrorCode::InternalError, "not opened"); + reply.NotReady(file); return; } @@ -163,10 +165,12 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader, Reflect(reader, param); int file_id; - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id); + QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } if (param.startLine >= 0) { std::vector result; diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index bf1c1ffcc..9f07b7a75 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -31,19 +31,19 @@ MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); - if (!file) - return; - WorkingFile *wfile = wfiles->GetFile(file->def->path); - if (!wfile) + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) { + reply.NotReady(file); return; + } std::vector result; std::optional ls_range; for (auto [sym, refcnt] : file->symbol2refcnt) if (refcnt > 0 && sym.extent.Valid() && (sym.kind == Kind::Func || sym.kind == Kind::Type) && - (ls_range = GetLsRange(wfile, sym.extent))) { + (ls_range = GetLsRange(wf, sym.extent))) { FoldingRange &fold = result.emplace_back(); fold.startLine = ls_range->start.line; fold.startCharacter = ls_range->start.character; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 4d86898e3..37bd7c46e 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -80,19 +80,23 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } Format(reply, wf, {0, (unsigned)wf->buffer_content.size()}); } void MessageHandler::textDocument_onTypeFormatting( DocumentOnTypeFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } std::string_view code = wf->buffer_content; int pos = GetOffsetForPosition(param.position, code); auto lbrace = code.find_last_of('{', pos); @@ -103,10 +107,12 @@ void MessageHandler::textDocument_onTypeFormatting( void MessageHandler::textDocument_rangeFormatting( DocumentRangeFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } std::string_view code = wf->buffer_content; int begin = GetOffsetForPosition(param.range.start, code), end = GetOffsetForPosition(param.range.end, code); diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 89ecd9b35..eec1edfb9 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -93,12 +93,14 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; - Hover result; + } + Hover result; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { std::optional ls_range = GetLsRange(wfiles->GetFile(file->def->path), sym.range); diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index db026eb0c..e8f8eeb46 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -44,10 +44,13 @@ MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders, void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { ReferenceParam param; Reflect(reader, param); - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } + for (auto &folder : param.folders) EnsureEndsInSlash(folder); std::vector file_set = db->GetFileSet(param.folders); diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index e6ea5b96c..05028263a 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -38,9 +38,9 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, const std::string &path = file.def->path; path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path); - WorkingFile *working_file = wfiles->GetFile(path); - if (working_file) - path_to_edit[file_id].textDocument.version = working_file->version; + WorkingFile *wf = wfiles->GetFile(path); + if (wf) + path_to_edit[file_id].textDocument.version = wf->version; } TextEdit &edit = path_to_edit[file_id].edits.emplace_back(); @@ -56,10 +56,12 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, } // namespace void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) + if (!wf) { + reply.NotReady(file); return; + } WorkspaceEdit result; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { From 04e80544b985c16a81b3b7bf3237b5551af564d0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 2 Dec 2018 15:53:33 -0800 Subject: [PATCH 312/378] Refactor serializer Delete virtual bases Reader & Writer Delete unused MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY Merge serializers/{json,binary}.hh into serializer.{hh,cc} MAKE_REFLECT_STRUCT => REFLECT_STRUCT MAKE_REFLECT_TYPE_PROXY => REFLECT_UNDERLYING --- src/config.hh | 24 +- src/indexer.cc | 154 ++++--- src/indexer.hh | 28 +- src/lsp.cc | 31 +- src/lsp.hh | 11 +- src/main.cc | 2 +- src/message_handler.cc | 76 ++-- src/message_handler.hh | 76 ++-- src/messages/ccls_call.cc | 12 +- src/messages/ccls_info.cc | 12 +- src/messages/ccls_inheritance.cc | 10 +- src/messages/ccls_member.cc | 10 +- src/messages/ccls_navigate.cc | 5 +- src/messages/ccls_reload.cc | 4 +- src/messages/ccls_vars.cc | 4 +- src/messages/initialize.cc | 95 ++--- src/messages/textDocument_code.cc | 14 +- src/messages/textDocument_completion.cc | 12 +- src/messages/textDocument_document.cc | 18 +- src/messages/textDocument_foldingRange.cc | 4 +- src/messages/textDocument_hover.cc | 8 +- src/messages/textDocument_references.cc | 9 +- src/messages/textDocument_signatureHelp.cc | 7 +- src/messages/workspace.cc | 2 +- src/pipeline.cc | 15 +- src/pipeline.hh | 10 +- src/position.cc | 69 ++- src/position.hh | 19 +- src/project.cc | 1 - src/query.cc | 3 +- src/serializer.cc | 400 ++++++++++-------- src/serializer.hh | 461 +++++++++++++-------- src/serializers/binary.hh | 139 ------- src/serializers/json.hh | 120 ------ 34 files changed, 882 insertions(+), 983 deletions(-) delete mode 100644 src/serializers/binary.hh delete mode 100644 src/serializers/json.hh diff --git a/src/config.hh b/src/config.hh index 1185697fd..b0f5ff4f5 100644 --- a/src/config.hh +++ b/src/config.hh @@ -259,28 +259,28 @@ struct Config { int maxNum = 2000; } xref; }; -MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, +REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, resourceDir); -MAKE_REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, +REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, snippetSupport); -MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); -MAKE_REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, +REFLECT_STRUCT(Config::CodeLens, localVariables); +REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, suffixWhitelist, whitelist); -MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, +REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, dropOldRequests, duplicateOptional, filterAndSort, include, maxNum); -MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, +REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) -MAKE_REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, +REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) -MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, +REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, initialWhitelist, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, threads, trackDependency, whitelist); -MAKE_REFLECT_STRUCT(Config::Session, maxNum); -MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); -MAKE_REFLECT_STRUCT(Config::Xref, maxNum); -MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, +REFLECT_STRUCT(Config::Session, maxNum); +REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); +REFLECT_STRUCT(Config::Xref, maxNum); +REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat, clang, client, codeLens, completion, diagnostics, highlight, index, session, workspaceSymbol, xref); diff --git a/src/indexer.cc b/src/indexer.cc index ea9f3ca44..584dd20ae 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -20,7 +20,6 @@ limitations under the License. #include "pipeline.hh" #include "platform.hh" #include "sema_manager.hh" -#include "serializer.hh" #include #include @@ -1185,7 +1184,7 @@ class IndexFrontendAction : public ASTFrontendAction { } // namespace const int IndexFile::kMajorVersion = 19; -const int IndexFile::kMinorVersion = 0; +const int IndexFile::kMinorVersion = 1; IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, const std::string &contents) @@ -1377,90 +1376,85 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, } } // namespace idx -void Reflect(Reader &vis, SymbolRef &v) { - if (vis.Format() == SerializeFormat::Json) { - std::string t = vis.GetString(); - char *s = const_cast(t.c_str()); - v.range = Range::FromString(s); - s = strchr(s, '|'); - v.usr = strtoull(s + 1, &s, 10); - v.kind = static_cast(strtol(s + 1, &s, 10)); - v.role = static_cast(strtol(s + 1, &s, 10)); - } else { - Reflect(vis, v.range); - Reflect(vis, v.usr); - Reflect(vis, v.kind); - Reflect(vis, v.role); - } +void Reflect(JsonReader &vis, SymbolRef &v) { + std::string t = vis.GetString(); + char *s = const_cast(t.c_str()); + v.range = Range::FromString(s); + s = strchr(s, '|'); + v.usr = strtoull(s + 1, &s, 10); + v.kind = static_cast(strtol(s + 1, &s, 10)); + v.role = static_cast(strtol(s + 1, &s, 10)); } -void Reflect(Writer &vis, SymbolRef &v) { - if (vis.Format() == SerializeFormat::Json) { - char buf[99]; - snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", - v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role)); - std::string s(buf); - Reflect(vis, s); - } else { - Reflect(vis, v.range); - Reflect(vis, v.usr); - Reflect(vis, v.kind); - Reflect(vis, v.role); - } +void Reflect(JsonReader &vis, Use &v) { + std::string t = vis.GetString(); + char *s = const_cast(t.c_str()); + v.range = Range::FromString(s); + s = strchr(s, '|'); + v.role = static_cast(strtol(s + 1, &s, 10)); + v.file_id = static_cast(strtol(s + 1, &s, 10)); +} +void Reflect(JsonReader &vis, DeclRef &v) { + std::string t = vis.GetString(); + char *s = const_cast(t.c_str()); + v.range = Range::FromString(s); + s = strchr(s, '|') + 1; + v.extent = Range::FromString(s); + s = strchr(s, '|'); + v.role = static_cast(strtol(s + 1, &s, 10)); + v.file_id = static_cast(strtol(s + 1, &s, 10)); } -void Reflect(Reader &vis, Use &v) { - if (vis.Format() == SerializeFormat::Json) { - std::string t = vis.GetString(); - char *s = const_cast(t.c_str()); - v.range = Range::FromString(s); - s = strchr(s, '|'); - v.role = static_cast(strtol(s + 1, &s, 10)); - v.file_id = static_cast(strtol(s + 1, &s, 10)); - } else { - Reflect(vis, v.range); - Reflect(vis, v.role); - Reflect(vis, v.file_id); - } +void Reflect(JsonWriter &vis, SymbolRef &v) { + char buf[99]; + snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", v.range.ToString().c_str(), + v.usr, int(v.kind), int(v.role)); + std::string s(buf); + Reflect(vis, s); } -void Reflect(Writer &vis, Use &v) { - if (vis.Format() == SerializeFormat::Json) { - char buf[99]; - snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(), - int(v.role), v.file_id); - std::string s(buf); - Reflect(vis, s); - } else { - Reflect(vis, v.range); - Reflect(vis, v.role); - Reflect(vis, v.file_id); - } +void Reflect(JsonWriter &vis, Use &v) { + char buf[99]; + snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(), int(v.role), + v.file_id); + std::string s(buf); + Reflect(vis, s); +} +void Reflect(JsonWriter &vis, DeclRef &v) { + char buf[99]; + snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(), + v.extent.ToString().c_str(), int(v.role), v.file_id); + std::string s(buf); + Reflect(vis, s); } -void Reflect(Reader &vis, DeclRef &v) { - if (vis.Format() == SerializeFormat::Json) { - std::string t = vis.GetString(); - char *s = const_cast(t.c_str()); - v.range = Range::FromString(s); - s = strchr(s, '|') + 1; - v.extent = Range::FromString(s); - s = strchr(s, '|'); - v.role = static_cast(strtol(s + 1, &s, 10)); - v.file_id = static_cast(strtol(s + 1, &s, 10)); - } else { - Reflect(vis, static_cast(v)); - Reflect(vis, v.extent); - } +void Reflect(BinaryReader &vis, SymbolRef &v) { + Reflect(vis, v.range); + Reflect(vis, v.usr); + Reflect(vis, v.kind); + Reflect(vis, v.role); } -void Reflect(Writer &vis, DeclRef &v) { - if (vis.Format() == SerializeFormat::Json) { - char buf[99]; - snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(), - v.extent.ToString().c_str(), int(v.role), v.file_id); - std::string s(buf); - Reflect(vis, s); - } else { - Reflect(vis, static_cast(v)); - Reflect(vis, v.extent); - } +void Reflect(BinaryReader &vis, Use &v) { + Reflect(vis, v.range); + Reflect(vis, v.role); + Reflect(vis, v.file_id); +} +void Reflect(BinaryReader &vis, DeclRef &v) { + Reflect(vis, static_cast(v)); + Reflect(vis, v.extent); +} + +void Reflect(BinaryWriter &vis, SymbolRef &v) { + Reflect(vis, v.range); + Reflect(vis, v.usr); + Reflect(vis, v.kind); + Reflect(vis, v.role); +} +void Reflect(BinaryWriter &vis, Use &v) { + Reflect(vis, v.range); + Reflect(vis, v.role); + Reflect(vis, v.file_id); +} +void Reflect(BinaryWriter &vis, DeclRef &v) { + Reflect(vis, static_cast(v)); + Reflect(vis, v.extent); } } // namespace ccls diff --git a/src/indexer.hh b/src/indexer.hh index 8e55f6669..885985102 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -46,7 +46,7 @@ using Usr = uint64_t; // The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in // front of others. enum class Kind : uint8_t { Invalid, File, Type, Func, Var }; -MAKE_REFLECT_TYPE_PROXY(Kind); +REFLECT_UNDERLYING_B(Kind); enum class Role : uint16_t { None = 0, @@ -61,7 +61,7 @@ enum class Role : uint16_t { Implicit = 1 << 8, All = (1 << 9) - 1, }; -MAKE_REFLECT_TYPE_PROXY(Role); +REFLECT_UNDERLYING_B(Role); inline uint16_t operator&(Role lhs, Role rhs) { return uint16_t(lhs) & uint16_t(rhs); } @@ -130,12 +130,18 @@ struct DeclRef : Use { Range extent; }; -void Reflect(Reader &visitor, SymbolRef &value); -void Reflect(Writer &visitor, SymbolRef &value); -void Reflect(Reader &visitor, Use &value); -void Reflect(Writer &visitor, Use &value); -void Reflect(Reader &visitor, DeclRef &value); -void Reflect(Writer &visitor, DeclRef &value); +void Reflect(JsonReader &visitor, SymbolRef &value); +void Reflect(JsonReader &visitor, Use &value); +void Reflect(JsonReader &visitor, DeclRef &value); +void Reflect(JsonWriter &visitor, SymbolRef &value); +void Reflect(JsonWriter &visitor, Use &value); +void Reflect(JsonWriter &visitor, DeclRef &value); +void Reflect(BinaryReader &visitor, SymbolRef &value); +void Reflect(BinaryReader &visitor, Use &value); +void Reflect(BinaryReader &visitor, DeclRef &value); +void Reflect(BinaryWriter &visitor, SymbolRef &value); +void Reflect(BinaryWriter &visitor, Use &value); +void Reflect(BinaryWriter &visitor, DeclRef &value); template struct NameMixin { std::string_view Name(bool qualified) const { @@ -174,7 +180,7 @@ struct FuncDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars, +REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars, callees, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind, storage); @@ -211,7 +217,7 @@ struct TypeDef : NameMixin { std::vector GetBases() const { return bases; } }; -MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases, +REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases, funcs, types, vars, alias_of, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind); @@ -255,7 +261,7 @@ struct VarDef : NameMixin { std::vector GetBases() const { return {}; } }; -MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type, +REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type, qual_name_offset, short_name_offset, short_name_size, kind, parent_kind, storage); diff --git a/src/lsp.cc b/src/lsp.cc index 3a95a9d80..caf7eec82 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -16,29 +16,30 @@ limitations under the License. #include "lsp.hh" #include "log.hh" -#include "serializers/json.hh" + +#include #include #include namespace ccls { -void Reflect(Reader &visitor, RequestId &value) { - if (visitor.IsInt64()) { - value.type = RequestId::kInt; - value.value = int(visitor.GetInt64()); - } else if (visitor.IsInt()) { - value.type = RequestId::kInt; - value.value = visitor.GetInt(); - } else if (visitor.IsString()) { - value.type = RequestId::kString; - value.value = atoll(visitor.GetString()); +void Reflect(JsonReader &vis, RequestId &v) { + if (vis.m->IsInt64()) { + v.type = RequestId::kInt; + v.value = int(vis.m->GetInt64()); + } else if (vis.m->IsInt()) { + v.type = RequestId::kInt; + v.value = vis.m->GetInt(); + } else if (vis.m->IsString()) { + v.type = RequestId::kString; + v.value = atoll(vis.m->GetString()); } else { - value.type = RequestId::kNone; - value.value = -1; + v.type = RequestId::kNone; + v.value = -1; } } -void Reflect(Writer &visitor, RequestId &value) { +void Reflect(JsonWriter &visitor, RequestId &value) { switch (value.type) { case RequestId::kNone: visitor.Null(); @@ -48,7 +49,7 @@ void Reflect(Writer &visitor, RequestId &value) { break; case RequestId::kString: auto s = std::to_string(value.value); - visitor.String(s.c_str(), s.length()); + visitor.String(s.c_str(), s.size()); break; } } diff --git a/src/lsp.hh b/src/lsp.hh index 9677aea58..fecf9da27 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -35,8 +35,8 @@ struct RequestId { bool Valid() const { return type != kNone; } }; -void Reflect(Reader &visitor, RequestId &value); -void Reflect(Writer &visitor, RequestId &value); +void Reflect(JsonReader &visitor, RequestId &value); +void Reflect(JsonWriter &visitor, RequestId &value); struct InMessage { RequestId id; @@ -80,11 +80,6 @@ struct DocumentUri { std::string raw_uri; }; -template -void Reflect(TVisitor &visitor, DocumentUri &value) { - Reflect(visitor, value.raw_uri); -} - struct Position { int line = 0; int character = 0; @@ -220,7 +215,7 @@ struct WorkspaceFolder { }; enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; -MAKE_REFLECT_TYPE_PROXY(MessageType) +REFLECT_UNDERLYING(MessageType) struct Diagnostic { lsRange range; diff --git a/src/main.cc b/src/main.cc index 8dc5f95f4..9a4ea630b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -17,7 +17,6 @@ limitations under the License. #include "pipeline.hh" #include "platform.hh" #include "serializer.hh" -#include "serializers/json.hh" #include "test.hh" #include "working_files.hh" @@ -29,6 +28,7 @@ limitations under the License. #include #include +#include #include #include diff --git a/src/message_handler.cc b/src/message_handler.cc index e7f25d2cc..238baf0b8 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -19,7 +19,9 @@ limitations under the License. #include "pipeline.hh" #include "project.hh" #include "query.hh" -#include "serializers/json.hh" + +#include +#include #include #include @@ -29,35 +31,35 @@ using namespace clang; MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { -MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics); -MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context); -void Reflect(Reader &, EmptyParam &) {} -MAKE_REFLECT_STRUCT(TextDocumentParam, textDocument); -MAKE_REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument); -MAKE_REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text); -MAKE_REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges); -MAKE_REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position); -MAKE_REFLECT_STRUCT(RenameParam, textDocument, position, newName); +REFLECT_STRUCT(CodeActionParam::Context, diagnostics); +REFLECT_STRUCT(CodeActionParam, textDocument, range, context); +void Reflect(JsonReader &, EmptyParam &) {} +REFLECT_STRUCT(TextDocumentParam, textDocument); +REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument); +REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text); +REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges); +REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position); +REFLECT_STRUCT(RenameParam, textDocument, position, newName); // completion -MAKE_REFLECT_TYPE_PROXY(CompletionTriggerKind); -MAKE_REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter); -MAKE_REFLECT_STRUCT(CompletionParam, textDocument, position, context); +REFLECT_UNDERLYING(CompletionTriggerKind); +REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter); +REFLECT_STRUCT(CompletionParam, textDocument, position, context); // formatting -MAKE_REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces); -MAKE_REFLECT_STRUCT(DocumentFormattingParam, textDocument, options); -MAKE_REFLECT_STRUCT(DocumentOnTypeFormattingParam, textDocument, position, - ch, options); -MAKE_REFLECT_STRUCT(DocumentRangeFormattingParam, textDocument, range, options); +REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces); +REFLECT_STRUCT(DocumentFormattingParam, textDocument, options); +REFLECT_STRUCT(DocumentOnTypeFormattingParam, textDocument, position, ch, + options); +REFLECT_STRUCT(DocumentRangeFormattingParam, textDocument, range, options); // workspace -MAKE_REFLECT_TYPE_PROXY(FileChangeType); -MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type); -MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam, changes); -MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed); -MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event); -MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query, folders); +REFLECT_UNDERLYING(FileChangeType); +REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type); +REFLECT_STRUCT(DidChangeWatchedFilesParam, changes); +REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed); +REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event); +REFLECT_STRUCT(WorkspaceSymbolParam, query, folders); namespace { struct CclsSemanticHighlightSymbol { @@ -75,15 +77,15 @@ struct CclsSemanticHighlight { DocumentUri uri; std::vector symbols; }; -MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, - ranges, lsRanges); -MAKE_REFLECT_STRUCT(CclsSemanticHighlight, uri, symbols); +REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage, + ranges, lsRanges); +REFLECT_STRUCT(CclsSemanticHighlight, uri, symbols); struct CclsSetSkippedRanges { DocumentUri uri; std::vector skippedRanges; }; -MAKE_REFLECT_STRUCT(CclsSetSkippedRanges, uri, skippedRanges); +REFLECT_STRUCT(CclsSetSkippedRanges, uri, skippedRanges); struct ScanLineEvent { Position pos; @@ -114,8 +116,9 @@ void ReplyOnce::NotReady(bool file) { Error(ErrorCode::InternalError, "not indexed"); } -void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Reader &)) { - method2notification[method] = [this, handler](Reader &reader) { +void MessageHandler::Bind(const char *method, + void (MessageHandler::*handler)(JsonReader &)) { + method2notification[method] = [this, handler](JsonReader &reader) { (this->*handler)(reader); }; } @@ -123,7 +126,7 @@ void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Re template void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Param &)) { - method2notification[method] = [this, handler](Reader &reader) { + method2notification[method] = [this, handler](JsonReader &reader) { Param param{}; Reflect(reader, param); (this->*handler)(param); @@ -131,9 +134,10 @@ void MessageHandler::Bind(const char *method, } void MessageHandler::Bind(const char *method, - void (MessageHandler::*handler)(Reader &, + void (MessageHandler::*handler)(JsonReader &, ReplyOnce &)) { - method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) { + method2request[method] = [this, handler](JsonReader &reader, + ReplyOnce &reply) { (this->*handler)(reader, reply); }; } @@ -142,7 +146,8 @@ template void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Param &, ReplyOnce &)) { - method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) { + method2request[method] = [this, handler](JsonReader &reader, + ReplyOnce &reply) { Param param{}; Reflect(reader, param); (this->*handler)(param, reply); @@ -214,7 +219,8 @@ void MessageHandler::Run(InMessage &msg) { it->second(reader, reply); } catch (std::invalid_argument &ex) { reply.Error(ErrorCode::InvalidParams, - "invalid params of " + msg.method + ": " + ex.what()); + "invalid params of " + msg.method + ": expected " + + ex.what() + " for " + reader.GetPath()); } catch (...) { reply.Error(ErrorCode::InternalError, "failed to process " + msg.method); } diff --git a/src/message_handler.hh b/src/message_handler.hh index d60e44b03..a0b6f1cef 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -32,8 +32,8 @@ struct WorkingFile; struct WorkingFiles; namespace pipeline { -void Reply(RequestId id, const std::function &fn); -void ReplyError(RequestId id, const std::function &fn); +void Reply(RequestId id, const std::function &fn); +void ReplyError(RequestId id, const std::function &fn); } struct CodeActionParam { @@ -63,11 +63,11 @@ struct TextDocumentEdit { VersionedTextDocumentIdentifier textDocument; std::vector edits; }; -MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits); +REFLECT_STRUCT(TextDocumentEdit, textDocument, edits); struct WorkspaceEdit { std::vector documentChanges; }; -MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges); +REFLECT_STRUCT(WorkspaceEdit, documentChanges); // completion enum class CompletionTriggerKind { @@ -175,32 +175,39 @@ struct WorkspaceSymbolParam { // ccls extensions std::vector folders; }; -MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name); +REFLECT_STRUCT(WorkspaceFolder, uri, name); -MAKE_REFLECT_TYPE_PROXY(ErrorCode); -MAKE_REFLECT_STRUCT(ResponseError, code, message); -MAKE_REFLECT_STRUCT(Position, line, character); -MAKE_REFLECT_STRUCT(lsRange, start, end); -MAKE_REFLECT_STRUCT(Location, uri, range); -MAKE_REFLECT_TYPE_PROXY(SymbolKind); -MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri); -MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); -MAKE_REFLECT_STRUCT(TextEdit, range, newText); -MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); -MAKE_REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); -MAKE_REFLECT_STRUCT(ShowMessageParam, type, message); -MAKE_REFLECT_TYPE_PROXY(LanguageId); +inline void Reflect(JsonReader &visitor, DocumentUri &value) { + Reflect(visitor, value.raw_uri); +} +inline void Reflect(JsonWriter &visitor, DocumentUri &value) { + Reflect(visitor, value.raw_uri); +} + +REFLECT_UNDERLYING(ErrorCode); +REFLECT_STRUCT(ResponseError, code, message); +REFLECT_STRUCT(Position, line, character); +REFLECT_STRUCT(lsRange, start, end); +REFLECT_STRUCT(Location, uri, range); +REFLECT_UNDERLYING_B(SymbolKind); +REFLECT_STRUCT(TextDocumentIdentifier, uri); +REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); +REFLECT_STRUCT(TextEdit, range, newText); +REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); +REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); +REFLECT_STRUCT(ShowMessageParam, type, message); +REFLECT_UNDERLYING_B(LanguageId); struct ReplyOnce { RequestId id; template void operator()(Res &&result) const { if (id.Valid()) - pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); }); + pipeline::Reply(id, [&](JsonWriter &w) { Reflect(w, result); }); } void Error(ErrorCode code, std::string message) const { ResponseError err{code, std::move(message)}; if (id.Valid()) - pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); }); + pipeline::ReplyError(id, [&](JsonWriter &w) { Reflect(w, err); }); } void NotReady(bool file); }; @@ -213,33 +220,34 @@ struct MessageHandler { VFS *vfs = nullptr; WorkingFiles *wfiles = nullptr; - llvm::StringMap> method2notification; - llvm::StringMap> method2request; + llvm::StringMap> method2notification; + llvm::StringMap> + method2request; MessageHandler(); void Run(InMessage &msg); QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr); private: - void Bind(const char *method, void (MessageHandler::*handler)(Reader &)); + void Bind(const char *method, void (MessageHandler::*handler)(JsonReader &)); template void Bind(const char *method, void (MessageHandler::*handler)(Param &)); void Bind(const char *method, - void (MessageHandler::*handler)(Reader &, ReplyOnce &)); + void (MessageHandler::*handler)(JsonReader &, ReplyOnce &)); template void Bind(const char *method, void (MessageHandler::*handler)(Param &, ReplyOnce &)); - void ccls_call(Reader &, ReplyOnce &); + void ccls_call(JsonReader &, ReplyOnce &); void ccls_fileInfo(TextDocumentParam &, ReplyOnce &); void ccls_info(EmptyParam &, ReplyOnce &); - void ccls_inheritance(Reader &, ReplyOnce &); - void ccls_member(Reader &, ReplyOnce &); - void ccls_navigate(Reader &, ReplyOnce &); - void ccls_reload(Reader &); - void ccls_vars(Reader &, ReplyOnce &); + void ccls_inheritance(JsonReader &, ReplyOnce &); + void ccls_member(JsonReader &, ReplyOnce &); + void ccls_navigate(JsonReader &, ReplyOnce &); + void ccls_reload(JsonReader &); + void ccls_vars(JsonReader &, ReplyOnce &); void exit(EmptyParam &); - void initialize(Reader &, ReplyOnce &); + void initialize(JsonReader &, ReplyOnce &); void shutdown(EmptyParam &, ReplyOnce &); void textDocument_codeAction(CodeActionParam &, ReplyOnce &); void textDocument_codeLens(TextDocumentParam &, ReplyOnce &); @@ -251,7 +259,7 @@ private: void textDocument_didSave(TextDocumentParam &); void textDocument_documentHighlight(TextDocumentPositionParam &, ReplyOnce &); void textDocument_documentLink(TextDocumentParam &, ReplyOnce &); - void textDocument_documentSymbol(Reader &, ReplyOnce &); + void textDocument_documentSymbol(JsonReader &, ReplyOnce &); void textDocument_foldingRange(TextDocumentParam &, ReplyOnce &); void textDocument_formatting(DocumentFormattingParam &, ReplyOnce &); void textDocument_hover(TextDocumentPositionParam &, ReplyOnce &); @@ -260,14 +268,14 @@ private: ReplyOnce &); void textDocument_rangeFormatting(DocumentRangeFormattingParam &, ReplyOnce &); - void textDocument_references(Reader &, ReplyOnce &); + void textDocument_references(JsonReader &, ReplyOnce &); void textDocument_rename(RenameParam &, ReplyOnce &); void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &); void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &); void workspace_didChangeConfiguration(EmptyParam &); void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &); void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &); - void workspace_executeCommand(Reader &, ReplyOnce &); + void workspace_executeCommand(JsonReader &, ReplyOnce &); void workspace_symbol(WorkspaceSymbolParam &, ReplyOnce &); }; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index f1e07b74f..5a0e6d8e2 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -30,7 +30,7 @@ enum class CallType : uint8_t { Derived = 2, All = 1 | 2 }; -MAKE_REFLECT_TYPE_PROXY(CallType); +REFLECT_UNDERLYING(CallType); bool operator&(CallType lhs, CallType rhs) { return uint8_t(lhs) & uint8_t(rhs); @@ -52,8 +52,8 @@ struct Param : TextDocumentPositionParam { int levels = 1; bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(Param, textDocument, position, id, callee, callType, - qualified, levels, hierarchy); +REFLECT_STRUCT(Param, textDocument, position, id, callee, callType, qualified, + levels, hierarchy); struct Out_cclsCall { Usr usr; @@ -69,8 +69,8 @@ struct Out_cclsCall { } bool operator<(const Out_cclsCall &o) const { return location < o.location; } }; -MAKE_REFLECT_STRUCT(Out_cclsCall, id, name, location, callType, numChildren, - children); +REFLECT_STRUCT(Out_cclsCall, id, name, location, callType, numChildren, + children); bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee, CallType call_type, bool qualified, int levels) { @@ -182,7 +182,7 @@ std::optional BuildInitial(MessageHandler *m, Usr root_usr, } } // namespace -void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) { +void MessageHandler::ccls_call(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); std::optional result; diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index c48dd5191..9befa32fa 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -19,8 +19,8 @@ limitations under the License. #include "query.hh" namespace ccls { -MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, - dependencies); +REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges, + dependencies); namespace { struct Out_cclsInfo { @@ -34,10 +34,10 @@ struct Out_cclsInfo { int entries; } project; }; -MAKE_REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars); -MAKE_REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests); -MAKE_REFLECT_STRUCT(Out_cclsInfo::Project, entries); -MAKE_REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project); +REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars); +REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests); +REFLECT_STRUCT(Out_cclsInfo::Project, entries); +REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project); } // namespace void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) { diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 6be44fe4b..b7520ddf7 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -36,8 +36,8 @@ struct Param : TextDocumentPositionParam { bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified, - levels, hierarchy); +REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified, + levels, hierarchy); struct Out_cclsInheritance { Usr usr; @@ -51,8 +51,8 @@ struct Out_cclsInheritance { // Empty if the |levels| limit is reached. std::vector children; }; -MAKE_REFLECT_STRUCT(Out_cclsInheritance, id, kind, name, location, numChildren, - children); +REFLECT_STRUCT(Out_cclsInheritance, id, kind, name, location, numChildren, + children); bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived, bool qualified, int levels); @@ -165,7 +165,7 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { } } // namespace -void MessageHandler::ccls_inheritance(Reader &reader, ReplyOnce &reply) { +void MessageHandler::ccls_inheritance(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); Inheritance(this, param, reply); diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index cae89c861..d94a3d88d 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -42,8 +42,8 @@ struct Param : TextDocumentPositionParam { bool hierarchy = false; }; -MAKE_REFLECT_STRUCT(Param, textDocument, position, id, qualified, levels, kind, - hierarchy); +REFLECT_STRUCT(Param, textDocument, position, id, qualified, levels, kind, + hierarchy); struct Out_cclsMember { Usr usr; @@ -57,8 +57,8 @@ struct Out_cclsMember { // Empty if the |levels| limit is reached. std::vector children; }; -MAKE_REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren, - children); +REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren, + children); bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified, int levels, Kind memberKind); @@ -263,7 +263,7 @@ std::optional BuildInitial(MessageHandler *m, Kind kind, } } // namespace -void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) { +void MessageHandler::ccls_member(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); std::optional result; diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index d097aa968..d09d57a83 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -23,7 +23,7 @@ struct Param { Position position; std::string direction; }; -MAKE_REFLECT_STRUCT(Param, textDocument, position, direction); +REFLECT_STRUCT(Param, textDocument, position, direction); Maybe FindParent(QueryFile *file, Pos pos) { Maybe parent; @@ -38,8 +38,7 @@ Maybe FindParent(QueryFile *file, Pos pos) { } } // namespace -void MessageHandler::ccls_navigate(Reader &reader, - ReplyOnce &reply) { +void MessageHandler::ccls_navigate(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); QueryFile *file = FindFile(param.textDocument.uri.GetPath()); diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 0ca2d446f..3a4268c4f 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -29,10 +29,10 @@ struct Param { std::vector whitelist; std::vector blacklist; }; -MAKE_REFLECT_STRUCT(Param, dependencies, whitelist, blacklist); +REFLECT_STRUCT(Param, dependencies, whitelist, blacklist); } // namespace -void MessageHandler::ccls_reload(Reader &reader) { +void MessageHandler::ccls_reload(JsonReader &reader) { Param param; Reflect(reader, param); // Send index requests for every file. diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index bf0cbbf98..03941491c 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -25,10 +25,10 @@ struct Param : TextDocumentPositionParam { // 4: parameter unsigned kind = ~0u; }; -MAKE_REFLECT_STRUCT(Param, textDocument, position, kind); +REFLECT_STRUCT(Param, textDocument, position, kind); } // namespace -void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) { +void MessageHandler::ccls_vars(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); QueryFile *file = FindFile(param.textDocument.uri.GetPath()); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 0f8f6ca82..474f01edb 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -21,12 +21,14 @@ limitations under the License. #include "pipeline.hh" #include "platform.hh" #include "project.hh" -#include "serializers/json.hh" #include "working_files.hh" #include #include +#include +#include + #include #include #include @@ -39,7 +41,7 @@ extern std::string g_init_options; namespace { enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 }; -MAKE_REFLECT_TYPE_PROXY(TextDocumentSyncKind) +REFLECT_UNDERLYING(TextDocumentSyncKind) struct ServerCap { struct SaveOptions { @@ -104,37 +106,36 @@ struct ServerCap { } workspaceFolders; } workspace; }; -MAKE_REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds); -MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); -MAKE_REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider, - triggerCharacters); -MAKE_REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider); -MAKE_REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions, - firstTriggerCharacter, moreTriggerCharacter); -MAKE_REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands); -MAKE_REFLECT_STRUCT(ServerCap::SaveOptions, includeText); -MAKE_REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters); -MAKE_REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change, - willSave, willSaveWaitUntil, save); -MAKE_REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported, - changeNotifications); -MAKE_REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders); -MAKE_REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, - completionProvider, signatureHelpProvider, - definitionProvider, implementationProvider, - typeDefinitionProvider, referencesProvider, - documentHighlightProvider, documentSymbolProvider, - workspaceSymbolProvider, codeActionProvider, - codeLensProvider, documentFormattingProvider, - documentRangeFormattingProvider, - documentOnTypeFormattingProvider, renameProvider, - documentLinkProvider, foldingRangeProvider, - executeCommandProvider, workspace); +REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds); +REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); +REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider, + triggerCharacters); +REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider); +REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions, + firstTriggerCharacter, moreTriggerCharacter); +REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands); +REFLECT_STRUCT(ServerCap::SaveOptions, includeText); +REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters); +REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change, willSave, + willSaveWaitUntil, save); +REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported, + changeNotifications); +REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders); +REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider, + signatureHelpProvider, definitionProvider, + implementationProvider, typeDefinitionProvider, + referencesProvider, documentHighlightProvider, + documentSymbolProvider, workspaceSymbolProvider, + codeActionProvider, codeLensProvider, documentFormattingProvider, + documentRangeFormattingProvider, + documentOnTypeFormattingProvider, renameProvider, + documentLinkProvider, foldingRangeProvider, + executeCommandProvider, workspace); struct DynamicReg { bool dynamicRegistration = false; }; -MAKE_REFLECT_STRUCT(DynamicReg, dynamicRegistration); +REFLECT_STRUCT(DynamicReg, dynamicRegistration); // Workspace specific client capabilities. struct WorkspaceClientCap { @@ -154,10 +155,10 @@ struct WorkspaceClientCap { DynamicReg executeCommand; }; -MAKE_REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges); -MAKE_REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit, - didChangeConfiguration, didChangeWatchedFiles, symbol, - executeCommand); +REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges); +REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit, + didChangeConfiguration, didChangeWatchedFiles, symbol, + executeCommand); // Text document specific client capabilities. struct TextDocumentClientCap { @@ -178,18 +179,18 @@ struct TextDocumentClientCap { } documentSymbol; }; -MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem, - snippetSupport); -MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem); -MAKE_REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol, - hierarchicalDocumentSymbolSupport); -MAKE_REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol); +REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem, + snippetSupport); +REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem); +REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol, + hierarchicalDocumentSymbolSupport); +REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol); struct ClientCap { WorkspaceClientCap workspace; TextDocumentClientCap textDocument; }; -MAKE_REFLECT_STRUCT(ClientCap, workspace, textDocument); +REFLECT_STRUCT(ClientCap, workspace, textDocument); struct InitializeParam { // The rootUri of the workspace. Is null if no @@ -211,12 +212,12 @@ struct InitializeParam { std::vector workspaceFolders; }; -void Reflect(Reader &reader, InitializeParam::Trace &value) { - if (!reader.IsString()) { +void Reflect(JsonReader &reader, InitializeParam::Trace &value) { + if (!reader.m->IsString()) { value = InitializeParam::Trace::Off; return; } - std::string v = reader.GetString(); + std::string v = reader.m->GetString(); if (v == "off") value = InitializeParam::Trace::Off; else if (v == "messages") @@ -225,13 +226,13 @@ void Reflect(Reader &reader, InitializeParam::Trace &value) { value = InitializeParam::Trace::Verbose; } -MAKE_REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, - capabilities, trace, workspaceFolders); +REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, capabilities, + trace, workspaceFolders); struct InitializeResult { ServerCap capabilities; }; -MAKE_REFLECT_STRUCT(InitializeResult, capabilities); +REFLECT_STRUCT(InitializeResult, capabilities); void *Indexer(void *arg_) { MessageHandler *h; @@ -341,7 +342,7 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { m->manager->sessions.SetCapacity(g_config->session.maxNum); } -void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) { +void MessageHandler::initialize(JsonReader &reader, ReplyOnce &reply) { InitializeParam param; Reflect(reader, param); if (!param.rootUri) { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index b96db1aea..4d288f036 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -16,10 +16,12 @@ limitations under the License. #include "message_handler.hh" #include "pipeline.hh" #include "query.hh" -#include "serializers/json.hh" #include +#include +#include + #include namespace ccls { @@ -29,7 +31,7 @@ struct CodeAction { const char *kind = "quickfix"; WorkspaceEdit edit; }; -MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); +REFLECT_STRUCT(CodeAction, title, kind, edit); } void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { @@ -72,9 +74,9 @@ struct CodeLens { lsRange range; std::optional command; }; -MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field); -MAKE_REFLECT_STRUCT(Command, title, command, arguments); -MAKE_REFLECT_STRUCT(CodeLens, range, command); +REFLECT_STRUCT(Cmd_xref, usr, kind, field); +REFLECT_STRUCT(Command, title, command, arguments); +REFLECT_STRUCT(CodeLens, range, command); template std::string ToString(T &v) { @@ -174,7 +176,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, reply(result); } -void MessageHandler::workspace_executeCommand(Reader &reader, +void MessageHandler::workspace_executeCommand(JsonReader &reader, ReplyOnce &reply) { Command param; Reflect(reader, param); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 4691189fe..771169904 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -32,11 +32,11 @@ namespace ccls { using namespace clang; using namespace llvm; -MAKE_REFLECT_TYPE_PROXY(InsertTextFormat); -MAKE_REFLECT_TYPE_PROXY(CompletionItemKind); +REFLECT_UNDERLYING(InsertTextFormat); +REFLECT_UNDERLYING(CompletionItemKind); -void Reflect(Writer &vis, CompletionItem &v) { - REFLECT_MEMBER_START(); +void Reflect(JsonWriter &vis, CompletionItem &v) { + ReflectMemberStart(vis); REFLECT_MEMBER(label); REFLECT_MEMBER(kind); REFLECT_MEMBER(detail); @@ -49,7 +49,7 @@ void Reflect(Writer &vis, CompletionItem &v) { REFLECT_MEMBER(textEdit); if (v.additionalTextEdits.size()) REFLECT_MEMBER(additionalTextEdits); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } namespace { @@ -57,7 +57,7 @@ struct CompletionList { bool isIncomplete = false; std::vector items; }; -MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items); +REFLECT_STRUCT(CompletionList, isIncomplete, items); #if LLVM_VERSION_MAJOR < 8 void DecorateIncludePaths(const std::smatch &match, diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index e65a6c772..32271c2f4 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -22,7 +22,7 @@ limitations under the License. MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind); namespace ccls { -MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); +REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); namespace { struct DocumentHighlight { @@ -38,7 +38,7 @@ struct DocumentHighlight { return !(range == o.range) ? range < o.range : kind < o.kind; } }; -MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role); +REFLECT_STRUCT(DocumentHighlight, range, kind, role); } // namespace void MessageHandler::textDocument_documentHighlight( @@ -85,7 +85,7 @@ struct DocumentLink { lsRange range; DocumentUri target; }; -MAKE_REFLECT_STRUCT(DocumentLink, range, target); +REFLECT_STRUCT(DocumentLink, range, target); } // namespace void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, @@ -118,7 +118,7 @@ struct DocumentSymbolParam : TextDocumentParam { int startLine = -1; int endLine = -1; }; -MAKE_REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine); +REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine); struct DocumentSymbol { std::string name; @@ -128,10 +128,10 @@ struct DocumentSymbol { lsRange selectionRange; std::vector> children; }; -void Reflect(Writer &vis, std::unique_ptr &v); -MAKE_REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange, - children); -void Reflect(Writer &vis, std::unique_ptr &v) { +void Reflect(JsonWriter &vis, std::unique_ptr &v); +REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange, + children); +void Reflect(JsonWriter &vis, std::unique_ptr &v) { Reflect(vis, *v); } @@ -159,7 +159,7 @@ void Uniquify(std::vector> &cs) { } } // namespace -void MessageHandler::textDocument_documentSymbol(Reader &reader, +void MessageHandler::textDocument_documentSymbol(JsonReader &reader, ReplyOnce &reply) { DocumentSymbolParam param; Reflect(reader, param); diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index 9f07b7a75..67fb0c0aa 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -25,8 +25,8 @@ struct FoldingRange { int startLine, startCharacter, endLine, endCharacter; std::string kind = "region"; }; -MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, - endCharacter, kind); +REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, endCharacter, + kind); } // namespace void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index eec1edfb9..7a3e03416 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -27,19 +27,19 @@ struct Hover { std::optional range; }; -void Reflect(Writer &vis, MarkedString &v) { +void Reflect(JsonWriter &vis, MarkedString &v) { // If there is a language, emit a `{language:string, value:string}` object. If // not, emit a string. if (v.language) { - REFLECT_MEMBER_START(); + vis.StartObject(); REFLECT_MEMBER(language); REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); + vis.EndObject(); } else { Reflect(vis, v.value); } } -MAKE_REFLECT_STRUCT(Hover, contents, range); +REFLECT_STRUCT(Hover, contents, range); const char *LanguageIdentifier(LanguageId lang) { switch (lang) { diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index e8f8eeb46..8c784553d 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -36,12 +36,13 @@ struct ReferenceParam : public TextDocumentPositionParam { // Include references with all |Role| bits set. Role role = Role::None; }; -MAKE_REFLECT_STRUCT(ReferenceParam::Context, includeDeclaration); -MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders, - base, excludeRole, role); +REFLECT_STRUCT(ReferenceParam::Context, includeDeclaration); +REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders, base, + excludeRole, role); } // namespace -void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) { +void MessageHandler::textDocument_references(JsonReader &reader, + ReplyOnce &reply) { ReferenceParam param; Reflect(reader, param); QueryFile *file = FindFile(param.textDocument.uri.GetPath()); diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 21238898f..b15def2a9 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -36,10 +36,9 @@ struct SignatureHelp { int activeSignature = 0; int activeParameter = 0; }; -MAKE_REFLECT_STRUCT(ParameterInformation, label); -MAKE_REFLECT_STRUCT(SignatureInformation, label, documentation, parameters); -MAKE_REFLECT_STRUCT(SignatureHelp, signatures, activeSignature, - activeParameter); +REFLECT_STRUCT(ParameterInformation, label); +REFLECT_STRUCT(SignatureInformation, label, documentation, parameters); +REFLECT_STRUCT(SignatureHelp, signatures, activeSignature, activeParameter); std::string BuildOptional(const CodeCompletionString &CCS, std::vector &ls_params) { diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index d4b4da582..5661a5d65 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -30,7 +30,7 @@ limitations under the License. #include namespace ccls { -MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); +REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { for (const std::string &folder : g_config->workspaceFolders) diff --git a/src/pipeline.cc b/src/pipeline.cc index c7f8aa7ce..ab6fd2e16 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -25,7 +25,6 @@ limitations under the License. #include "project.hh" #include "query.hh" #include "sema_manager.hh" -#include "serializers/json.hh" #include #include @@ -49,7 +48,7 @@ struct PublishDiagnosticParam { DocumentUri uri; std::vector diagnostics; }; -MAKE_REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics); +REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics); } // namespace void VFS::Clear() { @@ -457,8 +456,8 @@ void LaunchStdin() { assert(!document->HasParseError()); JsonReader reader{document.get()}; - if (!reader.HasMember("jsonrpc") || - std::string(reader["jsonrpc"]->GetString()) != "2.0") + if (!reader.m->HasMember("jsonrpc") || + std::string((*reader.m)["jsonrpc"].GetString()) != "2.0") return; RequestId id; std::string method; @@ -610,7 +609,7 @@ std::optional LoadIndexedContent(const std::string &path) { return ReadContent(GetCachePath(path)); } -void Notify(const char *method, const std::function &fn) { +void Notify(const char *method, const std::function &fn) { rapidjson::StringBuffer output; rapidjson::Writer w(output); w.StartObject(); @@ -626,7 +625,7 @@ void Notify(const char *method, const std::function &fn) { } static void Reply(RequestId id, const char *key, - const std::function &fn) { + const std::function &fn) { rapidjson::StringBuffer output; rapidjson::Writer w(output); w.StartObject(); @@ -652,11 +651,11 @@ static void Reply(RequestId id, const char *key, for_stdout->PushBack(output.GetString()); } -void Reply(RequestId id, const std::function &fn) { +void Reply(RequestId id, const std::function &fn) { Reply(id, "result", fn); } -void ReplyError(RequestId id, const std::function &fn) { +void ReplyError(RequestId id, const std::function &fn) { Reply(id, "error", fn); } } // namespace pipeline diff --git a/src/pipeline.hh b/src/pipeline.hh index c75a371f0..e70d9dd8e 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -51,16 +51,16 @@ void Index(const std::string &path, const std::vector &args, std::optional LoadIndexedContent(const std::string& path); -void Notify(const char *method, const std::function &fn); +void Notify(const char *method, const std::function &fn); template void Notify(const char *method, T &result) { - Notify(method, [&](Writer &w) { Reflect(w, result); }); + Notify(method, [&](JsonWriter &w) { Reflect(w, result); }); } -void Reply(RequestId id, const std::function &fn); +void Reply(RequestId id, const std::function &fn); -void ReplyError(RequestId id, const std::function &fn); +void ReplyError(RequestId id, const std::function &fn); template void ReplyError(RequestId id, T &result) { - ReplyError(id, [&](Writer &w) { Reflect(w, result); }); + ReplyError(id, [&](JsonWriter &w) { Reflect(w, result); }); } } // namespace pipeline } // namespace ccls diff --git a/src/position.cc b/src/position.cc index b82d30975..8211ff982 100644 --- a/src/position.cc +++ b/src/position.cc @@ -17,6 +17,9 @@ limitations under the License. #include "serializer.hh" +#include +#include + #include #include #include @@ -69,45 +72,39 @@ std::string Range::ToString() { return buf; } -// Position -void Reflect(Reader &visitor, Pos &value) { - if (visitor.Format() == SerializeFormat::Json) { - value = Pos::FromString(visitor.GetString()); - } else { - Reflect(visitor, value.line); - Reflect(visitor, value.column); - } +void Reflect(JsonReader &vis, Pos &v) { v = Pos::FromString(vis.GetString()); } +void Reflect(JsonReader &vis, Range &v) { + v = Range::FromString(vis.GetString()); +} + +void Reflect(JsonWriter &vis, Pos &v) { + std::string output = v.ToString(); + vis.String(output.c_str(), output.size()); +} +void Reflect(JsonWriter &vis, Range &v) { + std::string output = v.ToString(); + vis.String(output.c_str(), output.size()); +} + +void Reflect(BinaryReader &visitor, Pos &value) { + Reflect(visitor, value.line); + Reflect(visitor, value.column); } -void Reflect(Writer &visitor, Pos &value) { - if (visitor.Format() == SerializeFormat::Json) { - std::string output = value.ToString(); - visitor.String(output.c_str(), output.size()); - } else { - Reflect(visitor, value.line); - Reflect(visitor, value.column); - } +void Reflect(BinaryReader &visitor, Range &value) { + Reflect(visitor, value.start.line); + Reflect(visitor, value.start.column); + Reflect(visitor, value.end.line); + Reflect(visitor, value.end.column); } -// Range -void Reflect(Reader &visitor, Range &value) { - if (visitor.Format() == SerializeFormat::Json) { - value = Range::FromString(visitor.GetString()); - } else { - Reflect(visitor, value.start.line); - Reflect(visitor, value.start.column); - Reflect(visitor, value.end.line); - Reflect(visitor, value.end.column); - } +void Reflect(BinaryWriter &vis, Pos &v) { + Reflect(vis, v.line); + Reflect(vis, v.column); } -void Reflect(Writer &visitor, Range &value) { - if (visitor.Format() == SerializeFormat::Json) { - std::string output = value.ToString(); - visitor.String(output.c_str(), output.size()); - } else { - Reflect(visitor, value.start.line); - Reflect(visitor, value.start.column); - Reflect(visitor, value.end.line); - Reflect(visitor, value.end.column); - } +void Reflect(BinaryWriter &vis, Range &v) { + Reflect(vis, v.start.line); + Reflect(vis, v.start.column); + Reflect(vis, v.end.line); + Reflect(vis, v.end.column); } } // namespace ccls diff --git a/src/position.hh b/src/position.hh index 11075e90a..d5bf241b8 100644 --- a/src/position.hh +++ b/src/position.hh @@ -63,12 +63,19 @@ struct Range { }; // Reflection -class Reader; -class Writer; -void Reflect(Reader &visitor, Pos &value); -void Reflect(Writer &visitor, Pos &value); -void Reflect(Reader &visitor, Range &value); -void Reflect(Writer &visitor, Range &value); +struct JsonReader; +struct JsonWriter; +struct BinaryReader; +struct BinaryWriter; + +void Reflect(JsonReader &visitor, Pos &value); +void Reflect(JsonReader &visitor, Range &value); +void Reflect(JsonWriter &visitor, Pos &value); +void Reflect(JsonWriter &visitor, Range &value); +void Reflect(BinaryReader &visitor, Pos &value); +void Reflect(BinaryReader &visitor, Range &value); +void Reflect(BinaryWriter &visitor, Pos &value); +void Reflect(BinaryWriter &visitor, Range &value); } // namespace ccls namespace std { diff --git a/src/project.cc b/src/project.cc index c2c23a6cb..5a2de3dae 100644 --- a/src/project.cc +++ b/src/project.cc @@ -20,7 +20,6 @@ limitations under the License. #include "log.hh" #include "pipeline.hh" #include "platform.hh" -#include "serializers/json.hh" #include "utils.hh" #include "working_files.hh" diff --git a/src/query.cc b/src/query.cc index 036cba602..0906ee244 100644 --- a/src/query.cc +++ b/src/query.cc @@ -18,7 +18,8 @@ limitations under the License. #include "indexer.hh" #include "pipeline.hh" #include "serializer.hh" -#include "serializers/json.hh" + +#include #include #include diff --git a/src/serializer.cc b/src/serializer.cc index 11c751979..c754f83a9 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -19,8 +19,9 @@ limitations under the License. #include "indexer.hh" #include "log.hh" #include "message_handler.hh" -#include "serializers/binary.hh" -#include "serializers/json.hh" + +#include +#include #include #include @@ -33,181 +34,198 @@ using namespace llvm; bool gTestOutputMode = false; namespace ccls { -Reader::~Reader() {} -BinaryReader::~BinaryReader() {} -JsonReader::~JsonReader() {} - -Writer::~Writer() {} -BinaryWriter::~BinaryWriter() {} -JsonWriter::~JsonWriter() {} - -void Reflect(Reader &vis, uint8_t &v) { v = vis.GetUInt8(); } -void Reflect(Writer &vis, uint8_t &v) { vis.UInt8(v); } - -void Reflect(Reader &vis, short &v) { - if (!vis.IsInt()) - throw std::invalid_argument("short"); - v = (short)vis.GetInt(); -} -void Reflect(Writer &vis, short &v) { vis.Int(v); } - -void Reflect(Reader &vis, unsigned short &v) { - if (!vis.IsInt()) - throw std::invalid_argument("unsigned short"); - v = (unsigned short)vis.GetInt(); -} -void Reflect(Writer &vis, unsigned short &v) { vis.Int(v); } - -void Reflect(Reader &vis, int &v) { - if (!vis.IsInt()) - throw std::invalid_argument("int"); - v = vis.GetInt(); -} -void Reflect(Writer &vis, int &v) { vis.Int(v); } - -void Reflect(Reader &vis, unsigned &v) { - if (!vis.IsUInt64()) - throw std::invalid_argument("unsigned"); - v = vis.GetUInt32(); -} -void Reflect(Writer &vis, unsigned &v) { vis.UInt32(v); } - -void Reflect(Reader &vis, long &v) { - if (!vis.IsInt64()) - throw std::invalid_argument("long"); - v = long(vis.GetInt64()); -} -void Reflect(Writer &vis, long &v) { vis.Int64(v); } - -void Reflect(Reader &vis, unsigned long &v) { - if (!vis.IsUInt64()) - throw std::invalid_argument("unsigned long"); - v = (unsigned long)vis.GetUInt64(); -} -void Reflect(Writer &vis, unsigned long &v) { vis.UInt64(v); } -void Reflect(Reader &vis, long long &v) { - if (!vis.IsInt64()) - throw std::invalid_argument("long long"); - v = vis.GetInt64(); -} -void Reflect(Writer &vis, long long &v) { vis.Int64(v); } - -void Reflect(Reader &vis, unsigned long long &v) { - if (!vis.IsUInt64()) - throw std::invalid_argument("unsigned long long"); - v = vis.GetUInt64(); -} -void Reflect(Writer &vis, unsigned long long &v) { vis.UInt64(v); } - -void Reflect(Reader &vis, double &v) { - if (!vis.IsDouble()) - throw std::invalid_argument("double"); - v = vis.GetDouble(); -} -void Reflect(Writer &vis, double &v) { vis.Double(v); } - -void Reflect(Reader &vis, bool &v) { - if (!vis.IsBool()) - throw std::invalid_argument("bool"); - v = vis.GetBool(); -} -void Reflect(Writer &vis, bool &v) { vis.Bool(v); } - -void Reflect(Reader &vis, std::string &v) { - if (!vis.IsString()) - throw std::invalid_argument("std::string"); - v = vis.GetString(); -} -void Reflect(Writer &vis, std::string &v) { - vis.String(v.c_str(), (rapidjson::SizeType)v.size()); -} - -void Reflect(Reader &, std::string_view &) { assert(0); } -void Reflect(Writer &vis, std::string_view &data) { +void JsonReader::IterArray(std::function fn) { + if (!m->IsArray()) + throw std::invalid_argument("array"); + // Use "0" to indicate any element for now. + path_.push_back("0"); + for (auto &entry : m->GetArray()) { + auto saved = m; + m = &entry; + fn(); + m = saved; + } + path_.pop_back(); +} +void JsonReader::Member(const char *name, std::function fn) { + path_.push_back(name); + auto it = m->FindMember(name); + if (it != m->MemberEnd()) { + auto saved = m; + m = &it->value; + fn(); + m = saved; + } + path_.pop_back(); +} +bool JsonReader::IsNull() { return m->IsNull(); } +std::string JsonReader::GetString() { return m->GetString(); } +std::string JsonReader::GetPath() const { + std::string ret; + for (auto &t : path_) + if (t[0] == '0') { + ret += '['; + ret += t; + ret += ']'; + } else { + ret += '/'; + ret += t; + } + return ret; +} + +void JsonWriter::StartArray() { m->StartArray(); } +void JsonWriter::EndArray() { m->EndArray(); } +void JsonWriter::StartObject() { m->StartObject(); } +void JsonWriter::EndObject() { m->EndObject(); } +void JsonWriter::Key(const char *name) { m->Key(name); } +void JsonWriter::Null() { m->Null(); } +void JsonWriter::Int(int v) { m->Int(v); } +void JsonWriter::String(const char *s) { m->String(s); } +void JsonWriter::String(const char *s, size_t len) { m->String(s, len); } + +// clang-format off +void Reflect(JsonReader &vis, bool &v ) { if (!vis.m->IsBool()) throw std::invalid_argument("bool"); v = vis.m->GetBool(); } +void Reflect(JsonReader &vis, unsigned char &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("uint8_t"); v = (uint8_t)vis.m->GetInt(); } +void Reflect(JsonReader &vis, short &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("short"); v = (short)vis.m->GetInt(); } +void Reflect(JsonReader &vis, unsigned short &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("unsigned short"); v = (unsigned short)vis.m->GetInt(); } +void Reflect(JsonReader &vis, int &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("int"); v = vis.m->GetInt(); } +void Reflect(JsonReader &vis, unsigned &v ) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned"); v = (unsigned)vis.m->GetUint64(); } +void Reflect(JsonReader &vis, long &v ) { if (!vis.m->IsInt64()) throw std::invalid_argument("long"); v = (long)vis.m->GetInt64(); } +void Reflect(JsonReader &vis, unsigned long &v ) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned long"); v = (unsigned long)vis.m->GetUint64(); } +void Reflect(JsonReader &vis, long long &v ) { if (!vis.m->IsInt64()) throw std::invalid_argument("long long"); v = vis.m->GetInt64(); } +void Reflect(JsonReader &vis, unsigned long long &v) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned long long"); v = vis.m->GetUint64(); } +void Reflect(JsonReader &vis, double &v ) { if (!vis.m->IsDouble()) throw std::invalid_argument("double"); v = vis.m->GetDouble(); } +void Reflect(JsonReader &vis, const char *&v ) { if (!vis.m->IsString()) throw std::invalid_argument("string"); v = Intern(vis.GetString()); } +void Reflect(JsonReader &vis, std::string &v ) { if (!vis.m->IsString()) throw std::invalid_argument("string"); v = vis.GetString(); } + +void Reflect(JsonWriter &vis, bool &v ) { vis.m->Bool(v); } +void Reflect(JsonWriter &vis, unsigned char &v ) { vis.m->Int(v); } +void Reflect(JsonWriter &vis, short &v ) { vis.m->Int(v); } +void Reflect(JsonWriter &vis, unsigned short &v ) { vis.m->Int(v); } +void Reflect(JsonWriter &vis, int &v ) { vis.m->Int(v); } +void Reflect(JsonWriter &vis, unsigned &v ) { vis.m->Uint64(v); } +void Reflect(JsonWriter &vis, long &v ) { vis.m->Int64(v); } +void Reflect(JsonWriter &vis, unsigned long &v ) { vis.m->Uint64(v); } +void Reflect(JsonWriter &vis, long long &v ) { vis.m->Int64(v); } +void Reflect(JsonWriter &vis, unsigned long long &v) { vis.m->Uint64(v); } +void Reflect(JsonWriter &vis, double &v ) { vis.m->Double(v); } +void Reflect(JsonWriter &vis, const char *&v ) { vis.String(v); } +void Reflect(JsonWriter &vis, std::string &v ) { vis.String(v.c_str(), v.size()); } + +void Reflect(BinaryReader &vis, bool &v ) { v = vis.Get(); } +void Reflect(BinaryReader &vis, unsigned char &v ) { v = vis.Get(); } +void Reflect(BinaryReader &vis, short &v ) { v = (short)vis.VarInt(); } +void Reflect(BinaryReader &vis, unsigned short &v ) { v = (unsigned short)vis.VarUInt(); } +void Reflect(BinaryReader &vis, int &v ) { v = (int)vis.VarInt(); } +void Reflect(BinaryReader &vis, unsigned &v ) { v = (unsigned)vis.VarUInt(); } +void Reflect(BinaryReader &vis, long &v ) { v = (long)vis.VarInt(); } +void Reflect(BinaryReader &vis, unsigned long &v ) { v = (unsigned long)vis.VarUInt(); } +void Reflect(BinaryReader &vis, long long &v ) { v = vis.VarInt(); } +void Reflect(BinaryReader &vis, unsigned long long &v) { v = vis.VarUInt(); } +void Reflect(BinaryReader &vis, double &v ) { v = vis.Get(); } +void Reflect(BinaryReader &vis, const char *&v ) { v = Intern(vis.GetString()); } +void Reflect(BinaryReader &vis, std::string &v ) { v = vis.GetString(); } + +void Reflect(BinaryWriter &vis, bool &v ) { vis.Pack(v); } +void Reflect(BinaryWriter &vis, unsigned char &v ) { vis.Pack(v); } +void Reflect(BinaryWriter &vis, short &v ) { vis.VarInt(v); } +void Reflect(BinaryWriter &vis, unsigned short &v ) { vis.VarUInt(v); } +void Reflect(BinaryWriter &vis, int &v ) { vis.VarInt(v); } +void Reflect(BinaryWriter &vis, unsigned &v ) { vis.VarUInt(v); } +void Reflect(BinaryWriter &vis, long &v ) { vis.VarInt(v); } +void Reflect(BinaryWriter &vis, unsigned long &v ) { vis.VarUInt(v); } +void Reflect(BinaryWriter &vis, long long &v ) { vis.VarInt(v); } +void Reflect(BinaryWriter &vis, unsigned long long &v) { vis.VarUInt(v); } +void Reflect(BinaryWriter &vis, double &v ) { vis.Pack(v); } +void Reflect(BinaryWriter &vis, const char *&v ) { vis.String(v); } +void Reflect(BinaryWriter &vis, std::string &v ) { vis.String(v.c_str(), v.size()); } +// clang-format on + +void Reflect(JsonWriter &vis, std::string_view &data) { if (data.empty()) vis.String(""); else vis.String(&data[0], (rapidjson::SizeType)data.size()); } -void Reflect(Reader &vis, const char *&v) { - const char *str = vis.GetString(); - v = Intern(str); -} -void Reflect(Writer &vis, const char *&v) { vis.String(v); } - -void Reflect(Reader &vis, JsonNull &v) { - assert(vis.Format() == SerializeFormat::Json); - vis.GetNull(); -} - -void Reflect(Writer &vis, JsonNull &v) { vis.Null(); } +void Reflect(JsonReader &vis, JsonNull &v) {} +void Reflect(JsonWriter &vis, JsonNull &v) { vis.m->Null(); } -// std::unordered_map template -void Reflect(Reader &vis, std::unordered_map &map) { - vis.IterArray([&](Reader &entry) { +void Reflect(JsonReader &vis, std::unordered_map &v) { + vis.IterArray([&]() { V val; - Reflect(entry, val); - auto usr = val.usr; - map[usr] = std::move(val); + Reflect(vis, val); + v[val.usr] = std::move(val); }); } template -void Reflect(Writer &vis, std::unordered_map &map) { - std::vector> xs(map.begin(), map.end()); +void Reflect(JsonWriter &vis, std::unordered_map &v) { + // Determinism + std::vector> xs(v.begin(), v.end()); std::sort(xs.begin(), xs.end(), [](const auto &a, const auto &b) { return a.first < b.first; }); - vis.StartArray(xs.size()); + vis.StartArray(); for (auto &it : xs) Reflect(vis, it.second); vis.EndArray(); } +template +void Reflect(BinaryReader &vis, std::unordered_map &v) { + for (auto n = vis.VarUInt(); n; n--) { + V val; + Reflect(vis, val); + v[val.usr] = std::move(val); + } +} +template +void Reflect(BinaryWriter &vis, std::unordered_map &v) { + vis.VarUInt(v.size()); + for (auto &it : v) + Reflect(vis, it.second); +} // Used by IndexFile::dependencies. -void Reflect(Reader &vis, DenseMap &v) { +void Reflect(JsonReader &vis, DenseMap &v) { std::string name; - if (vis.Format() == SerializeFormat::Json) { - auto &vis1 = static_cast(vis); - for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it) - v[InternH(it->name.GetString())] = it->value.GetInt64(); - } else { - vis.IterArray([&](Reader &entry) { - Reflect(entry, name); - Reflect(entry, v[InternH(name)]); - }); + for (auto it = vis.m->MemberBegin(); it != vis.m->MemberEnd(); ++it) + v[InternH(it->name.GetString())] = it->value.GetInt64(); +} +void Reflect(JsonWriter &vis, DenseMap &v) { + vis.StartObject(); + for (auto &it : v) { + vis.m->Key(it.first.val().data()); // llvm 8 -> data() + vis.m->Int64(it.second); } + vis.EndObject(); } -void Reflect(Writer &vis, DenseMap &v) { - if (vis.Format() == SerializeFormat::Json) { - auto &vis1 = static_cast(vis); - vis.StartObject(); - for (auto &it : v) { - vis1.m().Key(it.first.val().data()); // llvm 8 -> data() - vis1.m().Int64(it.second); - } - vis.EndObject(); - } else { - vis.StartArray(v.size()); - for (auto &it : v) { - std::string key = it.first.val().str(); - Reflect(vis, key); - Reflect(vis, it.second); - } - vis.EndArray(); +void Reflect(BinaryReader &vis, DenseMap &v) { + std::string name; + for (auto n = vis.VarUInt(); n; n--) { + Reflect(vis, name); + Reflect(vis, v[InternH(name)]); + } +} +void Reflect(BinaryWriter &vis, DenseMap &v) { + std::string key; + vis.VarUInt(v.size()); + for (auto &it : v) { + key = it.first.val().str(); + Reflect(vis, key); + Reflect(vis, it.second); } } -// TODO: Move this to indexer.cc -void Reflect(Reader &vis, IndexInclude &v) { - REFLECT_MEMBER_START(); +template void Reflect(Vis &vis, IndexInclude &v) { + ReflectMemberStart(vis); REFLECT_MEMBER(line); REFLECT_MEMBER(resolved_path); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } -void Reflect(Writer &vis, IndexInclude &v) { - REFLECT_MEMBER_START(); +void Reflect(JsonWriter &vis, IndexInclude &v) { + ReflectMemberStart(vis); REFLECT_MEMBER(line); if (gTestOutputMode) { std::string basename = llvm::sys::path::filename(v.resolved_path); @@ -217,23 +235,34 @@ void Reflect(Writer &vis, IndexInclude &v) { } else { REFLECT_MEMBER(resolved_path); } - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } -template void ReflectHoverAndComments(Reader &vis, Def &def) { +template +void ReflectHoverAndComments(JsonReader &vis, Def &def) { ReflectMember(vis, "hover", def.hover); ReflectMember(vis, "comments", def.comments); } - -template void ReflectHoverAndComments(Writer &vis, Def &def) { +template +void ReflectHoverAndComments(JsonWriter &vis, Def &def) { // Don't emit empty hover and comments in JSON test mode. if (!gTestOutputMode || def.hover[0]) ReflectMember(vis, "hover", def.hover); if (!gTestOutputMode || def.comments[0]) ReflectMember(vis, "comments", def.comments); } +template +void ReflectHoverAndComments(BinaryReader &vis, Def &def) { + Reflect(vis, def.hover); + Reflect(vis, def.comments); +} +template +void ReflectHoverAndComments(BinaryWriter &vis, Def &def) { + Reflect(vis, def.hover); + Reflect(vis, def.comments); +} -template void ReflectShortName(Reader &vis, Def &def) { +template void ReflectShortName(JsonReader &vis, Def &def) { if (gTestOutputMode) { std::string short_name; ReflectMember(vis, "short_name", short_name); @@ -246,8 +275,7 @@ template void ReflectShortName(Reader &vis, Def &def) { ReflectMember(vis, "short_name_size", def.short_name_size); } } - -template void ReflectShortName(Writer &vis, Def &def) { +template void ReflectShortName(JsonWriter &vis, Def &def) { if (gTestOutputMode) { std::string_view short_name(def.detailed_name + def.short_name_offset, def.short_name_size); @@ -257,9 +285,17 @@ template void ReflectShortName(Writer &vis, Def &def) { ReflectMember(vis, "short_name_size", def.short_name_size); } } +template void ReflectShortName(BinaryReader &vis, Def &def) { + Reflect(vis, def.short_name_offset); + Reflect(vis, def.short_name_size); +} +template void ReflectShortName(BinaryWriter &vis, Def &def) { + Reflect(vis, def.short_name_offset); + Reflect(vis, def.short_name_size); +} -template void Reflect(TVisitor &vis, IndexFunc &v) { - REFLECT_MEMBER_START(); +template void Reflect1(TVisitor &vis, IndexFunc &v) { + ReflectMemberStart(vis); REFLECT_MEMBER2("usr", v.usr); REFLECT_MEMBER2("detailed_name", v.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); @@ -276,11 +312,15 @@ template void Reflect(TVisitor &vis, IndexFunc &v) { REFLECT_MEMBER2("declarations", v.declarations); REFLECT_MEMBER2("derived", v.derived); REFLECT_MEMBER2("uses", v.uses); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } +void Reflect(JsonReader &vis, IndexFunc &v) { Reflect1(vis, v); } +void Reflect(JsonWriter &vis, IndexFunc &v) { Reflect1(vis, v); } +void Reflect(BinaryReader &vis, IndexFunc &v) { Reflect1(vis, v); } +void Reflect(BinaryWriter &vis, IndexFunc &v) { Reflect1(vis, v); } -template void Reflect(TVisitor &vis, IndexType &v) { - REFLECT_MEMBER_START(); +template void Reflect1(TVisitor &vis, IndexType &v) { + ReflectMemberStart(vis); REFLECT_MEMBER2("usr", v.usr); REFLECT_MEMBER2("detailed_name", v.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); @@ -299,11 +339,15 @@ template void Reflect(TVisitor &vis, IndexType &v) { REFLECT_MEMBER2("derived", v.derived); REFLECT_MEMBER2("instances", v.instances); REFLECT_MEMBER2("uses", v.uses); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } +void Reflect(JsonReader &vis, IndexType &v) { Reflect1(vis, v); } +void Reflect(JsonWriter &vis, IndexType &v) { Reflect1(vis, v); } +void Reflect(BinaryReader &vis, IndexType &v) { Reflect1(vis, v); } +void Reflect(BinaryWriter &vis, IndexType &v) { Reflect1(vis, v); } -template void Reflect(TVisitor &vis, IndexVar &v) { - REFLECT_MEMBER_START(); +template void Reflect1(TVisitor &vis, IndexVar &v) { + ReflectMemberStart(vis); REFLECT_MEMBER2("usr", v.usr); REFLECT_MEMBER2("detailed_name", v.def.detailed_name); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset); @@ -317,16 +361,16 @@ template void Reflect(TVisitor &vis, IndexVar &v) { REFLECT_MEMBER2("declarations", v.declarations); REFLECT_MEMBER2("uses", v.uses); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } +void Reflect(JsonReader &vis, IndexVar &v) { Reflect1(vis, v); } +void Reflect(JsonWriter &vis, IndexVar &v) { Reflect1(vis, v); } +void Reflect(BinaryReader &vis, IndexVar &v) { Reflect1(vis, v); } +void Reflect(BinaryWriter &vis, IndexVar &v) { Reflect1(vis, v); } // IndexFile -bool ReflectMemberStart(Writer &vis, IndexFile &v) { - vis.StartObject(); - return true; -} -template void Reflect(TVisitor &vis, IndexFile &v) { - REFLECT_MEMBER_START(); +template void Reflect1(TVisitor &vis, IndexFile &v) { + ReflectMemberStart(vis); if (!gTestOutputMode) { REFLECT_MEMBER(mtime); REFLECT_MEMBER(language); @@ -340,15 +384,19 @@ template void Reflect(TVisitor &vis, IndexFile &v) { REFLECT_MEMBER(usr2func); REFLECT_MEMBER(usr2type); REFLECT_MEMBER(usr2var); - REFLECT_MEMBER_END(); + ReflectMemberEnd(vis); } +void ReflectFile(JsonReader &vis, IndexFile &v) { Reflect1(vis, v); } +void ReflectFile(JsonWriter &vis, IndexFile &v) { Reflect1(vis, v); } +void ReflectFile(BinaryReader &vis, IndexFile &v) { Reflect1(vis, v); } +void ReflectFile(BinaryWriter &vis, IndexFile &v) { Reflect1(vis, v); } -void Reflect(Reader &vis, SerializeFormat &v) { +void Reflect(JsonReader &vis, SerializeFormat &v) { v = vis.GetString()[0] == 'j' ? SerializeFormat::Json : SerializeFormat::Binary; } -void Reflect(Writer &vis, SerializeFormat &v) { +void Reflect(JsonWriter &vis, SerializeFormat &v) { switch (v) { case SerializeFormat::Binary: vis.String("binary"); @@ -390,7 +438,7 @@ std::string Serialize(SerializeFormat format, IndexFile &file) { int minor = IndexFile::kMinorVersion; Reflect(writer, major); Reflect(writer, minor); - Reflect(writer, file); + ReflectFile(writer, file); return writer.Take(); } case SerializeFormat::Json: { @@ -406,7 +454,7 @@ std::string Serialize(SerializeFormat format, IndexFile &file) { output.Put(c); output.Put('\n'); } - Reflect(json_writer, file); + ReflectFile(json_writer, file); return output.GetString(); } } @@ -436,7 +484,7 @@ Deserialize(SerializeFormat format, const std::string &path, throw std::invalid_argument("Invalid version"); file = std::make_unique(sys::fs::UniqueID(0, 0), path, file_content); - Reflect(reader, *file); + ReflectFile(reader, *file); } catch (std::invalid_argument &e) { LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what(); return nullptr; @@ -462,7 +510,7 @@ Deserialize(SerializeFormat format, const std::string &path, file_content); JsonReader json_reader{&reader}; try { - Reflect(json_reader, *file); + ReflectFile(json_reader, *file); } catch (std::invalid_argument &e) { LOG_S(INFO) << "'" << path << "': failed to deserialize " << json_reader.GetPath() << "." << e.what(); diff --git a/src/serializer.hh b/src/serializer.hh index dc469d309..de5c24ac2 100644 --- a/src/serializer.hh +++ b/src/serializer.hh @@ -20,6 +20,7 @@ limitations under the License. #include #include +#include #include #include @@ -40,159 +41,208 @@ enum class SerializeFormat { Binary, Json }; struct JsonNull {}; -class Reader { -public: - virtual ~Reader(); - virtual SerializeFormat Format() const = 0; - - virtual bool IsBool() = 0; - virtual bool IsNull() = 0; - virtual bool IsInt() = 0; - virtual bool IsInt64() = 0; - virtual bool IsUInt64() = 0; - virtual bool IsDouble() = 0; - virtual bool IsString() = 0; - - virtual void GetNull() = 0; - virtual bool GetBool() = 0; - virtual uint8_t GetUInt8() = 0; - virtual int GetInt() = 0; - virtual uint32_t GetUInt32() = 0; - virtual int64_t GetInt64() = 0; - virtual uint64_t GetUInt64() = 0; - virtual double GetDouble() = 0; - virtual const char *GetString() = 0; - - virtual bool HasMember(const char *x) = 0; - virtual std::unique_ptr operator[](const char *x) = 0; - - virtual void IterArray(std::function fn) = 0; - virtual void Member(const char *name, std::function fn) = 0; +struct JsonReader { + rapidjson::Value *m; + std::vector path_; + + JsonReader(rapidjson::Value *m) : m(m) {} + void StartObject() {} + void EndObject() {} + void IterArray(std::function fn); + void Member(const char *name, std::function fn); + bool IsNull(); + std::string GetString(); + std::string GetPath() const; }; -class Writer { -public: - virtual ~Writer(); - virtual SerializeFormat Format() const = 0; - - virtual void Null() = 0; - virtual void Bool(bool x) = 0; - virtual void Int(int x) = 0; - virtual void Int64(int64_t x) = 0; - virtual void UInt8(uint8_t x) = 0; - virtual void UInt32(uint32_t x) = 0; - virtual void UInt64(uint64_t x) = 0; - virtual void Double(double x) = 0; - virtual void String(const char *x) = 0; - virtual void String(const char *x, size_t len) = 0; - virtual void StartArray(size_t) = 0; - virtual void EndArray() = 0; - virtual void StartObject() = 0; - virtual void EndObject() = 0; - virtual void Key(const char *name) = 0; +struct JsonWriter { + using W = + rapidjson::Writer, + rapidjson::UTF8, rapidjson::CrtAllocator, 0>; + + W *m; + + JsonWriter(W *m) : m(m) {} + void StartArray(); + void EndArray(); + void StartObject(); + void EndObject(); + void Key(const char *name); + void Null(); + void Int(int v); + void String(const char *s); + void String(const char *s, size_t len); }; -struct IndexFile; +struct BinaryReader { + const char *p_; -#define REFLECT_MEMBER_START() ReflectMemberStart(vis) -#define REFLECT_MEMBER_END() ReflectMemberEnd(vis); -#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name) -#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v) - -#define MAKE_REFLECT_TYPE_PROXY(type_name) \ - MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) -#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &vis, type &v) { \ - as_type value0; \ - ::ccls::Reflect(vis, value0); \ - v = static_cast(value0); \ - } \ - LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &vis, type &v) { \ - auto value0 = static_cast(v); \ - ::ccls::Reflect(vis, value0); \ + BinaryReader(std::string_view buf) : p_(buf.data()) {} + template T Get() { + T ret; + memcpy(&ret, p_, sizeof(T)); + p_ += sizeof(T); + return ret; } - -#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); - -#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ - template void Reflect(TVisitor &vis, type &v) { \ - REFLECT_MEMBER_START(); \ - REFLECT_MEMBER_END(); \ + uint64_t VarUInt() { + auto x = *reinterpret_cast(p_++); + if (x < 253) + return x; + if (x == 253) + return Get(); + if (x == 254) + return Get(); + return Get(); } - -#define MAKE_REFLECT_STRUCT(type, ...) \ - template void Reflect(TVisitor &vis, type &v) { \ - REFLECT_MEMBER_START(); \ - MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ - REFLECT_MEMBER_END(); \ + int64_t VarInt() { + uint64_t x = VarUInt(); + return int64_t(x >> 1 ^ -(x & 1)); } - -// clang-format off -// Config has many fields, we need to support at least its number of fields. -#define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N -#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) -// clang-format on - -#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name); - -// Reflects the struct so it is serialized as an array instead of an object. -// This currently only supports writers. -#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \ - inline void Reflect(Writer &vis, type &v) { \ - vis.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ - MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \ - vis.EndArray(); \ + const char *GetString() { + const char *ret = p_; + while (*p_) + p_++; + p_++; + return ret; } +}; -//// Elementary types - -void Reflect(Reader &vis, uint8_t &v); -void Reflect(Writer &vis, uint8_t &v); - -void Reflect(Reader &vis, short &v); -void Reflect(Writer &vis, short &v); - -void Reflect(Reader &vis, unsigned short &v); -void Reflect(Writer &vis, unsigned short &v); - -void Reflect(Reader &vis, int &v); -void Reflect(Writer &vis, int &v); - -void Reflect(Reader &vis, unsigned &v); -void Reflect(Writer &vis, unsigned &v); - -void Reflect(Reader &vis, long &v); -void Reflect(Writer &vis, long &v); +struct BinaryWriter { + std::string buf_; -void Reflect(Reader &vis, unsigned long &v); -void Reflect(Writer &vis, unsigned long &v); + template void Pack(T x) { + auto i = buf_.size(); + buf_.resize(i + sizeof(x)); + memcpy(buf_.data() + i, &x, sizeof(x)); + } -void Reflect(Reader &vis, long long &v); -void Reflect(Writer &vis, long long &v); + void VarUInt(uint64_t n) { + if (n < 253) + Pack(n); + else if (n < 65536) { + Pack(253); + Pack(n); + } else if (n < 4294967296) { + Pack(254); + Pack(n); + } else { + Pack(255); + Pack(n); + } + } + void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); } + std::string Take() { return std::move(buf_); } + + void String(const char *x) { String(x, strlen(x)); } + void String(const char *x, size_t len) { + auto i = buf_.size(); + buf_.resize(i + len + 1); + memcpy(buf_.data() + i, x, len); + } +}; -void Reflect(Reader &vis, unsigned long long &v); -void Reflect(Writer &vis, unsigned long long &v); +struct IndexFile; -void Reflect(Reader &vis, double &v); -void Reflect(Writer &vis, double &v); +#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name) +#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v) -void Reflect(Reader &vis, bool &v); -void Reflect(Writer &vis, bool &v); +#define REFLECT_UNDERLYING(T) \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(JsonReader &vis, T &v) { \ + std::underlying_type_t v0; \ + ::ccls::Reflect(vis, v0); \ + v = static_cast(v0); \ + } \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(JsonWriter &vis, T &v) { \ + auto v0 = static_cast>(v); \ + ::ccls::Reflect(vis, v0); \ + } -void Reflect(Reader &vis, std::string &v); -void Reflect(Writer &vis, std::string &v); +#define REFLECT_UNDERLYING_B(T) \ + REFLECT_UNDERLYING(T) \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(BinaryReader &vis, T &v) { \ + std::underlying_type_t v0; \ + ::ccls::Reflect(vis, v0); \ + v = static_cast(v0); \ + } \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(BinaryWriter &vis, T &v) { \ + auto v0 = static_cast>(v); \ + ::ccls::Reflect(vis, v0); \ + } -void Reflect(Reader &vis, std::string_view &v); -void Reflect(Writer &vis, std::string_view &v); +#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); -void Reflect(Reader &vis, const char *&v); -void Reflect(Writer &vis, const char *&v); +#define REFLECT_STRUCT(type, ...) \ + template void Reflect(Vis &vis, type &v) { \ + ReflectMemberStart(vis); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ + ReflectMemberEnd(vis); \ + } -void Reflect(Reader &vis, JsonNull &v); -void Reflect(Writer &vis, JsonNull &v); +#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name); -void Reflect(Reader &vis, SerializeFormat &v); -void Reflect(Writer &vis, SerializeFormat &v); +void Reflect(JsonReader &vis, bool &v); +void Reflect(JsonReader &vis, unsigned char &v); +void Reflect(JsonReader &vis, short &v); +void Reflect(JsonReader &vis, unsigned short &v); +void Reflect(JsonReader &vis, int &v); +void Reflect(JsonReader &vis, unsigned &v); +void Reflect(JsonReader &vis, long &v); +void Reflect(JsonReader &vis, unsigned long &v); +void Reflect(JsonReader &vis, long long &v); +void Reflect(JsonReader &vis, unsigned long long &v); +void Reflect(JsonReader &vis, double &v); +void Reflect(JsonReader &vis, const char *&v); +void Reflect(JsonReader &vis, std::string &v); + +void Reflect(JsonWriter &vis, bool &v); +void Reflect(JsonWriter &vis, unsigned char &v); +void Reflect(JsonWriter &vis, short &v); +void Reflect(JsonWriter &vis, unsigned short &v); +void Reflect(JsonWriter &vis, int &v); +void Reflect(JsonWriter &vis, unsigned &v); +void Reflect(JsonWriter &vis, long &v); +void Reflect(JsonWriter &vis, unsigned long &v); +void Reflect(JsonWriter &vis, long long &v); +void Reflect(JsonWriter &vis, unsigned long long &v); +void Reflect(JsonWriter &vis, double &v); +void Reflect(JsonWriter &vis, const char *&v); +void Reflect(JsonWriter &vis, std::string &v); + +void Reflect(BinaryReader &vis, bool &v); +void Reflect(BinaryReader &vis, unsigned char &v); +void Reflect(BinaryReader &vis, short &v); +void Reflect(BinaryReader &vis, unsigned short &v); +void Reflect(BinaryReader &vis, int &v); +void Reflect(BinaryReader &vis, unsigned &v); +void Reflect(BinaryReader &vis, long &v); +void Reflect(BinaryReader &vis, unsigned long &v); +void Reflect(BinaryReader &vis, long long &v); +void Reflect(BinaryReader &vis, unsigned long long &v); +void Reflect(BinaryReader &vis, double &v); +void Reflect(BinaryReader &vis, const char *&v); +void Reflect(BinaryReader &vis, std::string &v); + +void Reflect(BinaryWriter &vis, bool &v); +void Reflect(BinaryWriter &vis, unsigned char &v); +void Reflect(BinaryWriter &vis, short &v); +void Reflect(BinaryWriter &vis, unsigned short &v); +void Reflect(BinaryWriter &vis, int &v); +void Reflect(BinaryWriter &vis, unsigned &v); +void Reflect(BinaryWriter &vis, long &v); +void Reflect(BinaryWriter &vis, unsigned long &v); +void Reflect(BinaryWriter &vis, long long &v); +void Reflect(BinaryWriter &vis, unsigned long long &v); +void Reflect(BinaryWriter &vis, double &v); +void Reflect(BinaryWriter &vis, const char *&v); +void Reflect(BinaryWriter &vis, std::string &v); + +void Reflect(JsonReader &vis, JsonNull &v); +void Reflect(JsonWriter &vis, JsonNull &v); + +void Reflect(JsonReader &vis, SerializeFormat &v); +void Reflect(JsonWriter &vis, SerializeFormat &v); + +void Reflect(JsonWriter &vis, std::string_view &v); //// Type constructors @@ -200,109 +250,154 @@ void Reflect(Writer &vis, SerializeFormat &v); // properties (in `key: value` context). Reflect std::optional is used for a // different purpose, whether an object is nullable (possibly in `value` // context). -template void Reflect(Reader &vis, std::optional &v) { - if (vis.IsNull()) { - vis.GetNull(); - return; +template void Reflect(JsonReader &vis, std::optional &v) { + if (!vis.IsNull()) { + v.emplace(); + Reflect(vis, *v); } - T val; - Reflect(vis, val); - v = std::move(val); } -template void Reflect(Writer &vis, std::optional &v) { - if (v) { - if (vis.Format() != SerializeFormat::Json) - vis.UInt8(1); +template void Reflect(JsonWriter &vis, std::optional &v) { + if (v) Reflect(vis, *v); - } else + else vis.Null(); } - -// The same as std::optional -template void Reflect(Reader &vis, Maybe &v) { - if (vis.IsNull()) { - vis.GetNull(); - return; +template void Reflect(BinaryReader &vis, std::optional &v) { + if (*vis.p_++) { + v.emplace(); + Reflect(vis, *v); } - T val; - Reflect(vis, val); - v = std::move(val); } -template void Reflect(Writer &vis, Maybe &v) { +template void Reflect(BinaryWriter &vis, std::optional &v) { if (v) { - if (vis.Format() != SerializeFormat::Json) - vis.UInt8(1); + vis.Pack(1); + Reflect(vis, *v); + } else { + vis.Pack(0); + } +} + +// The same as std::optional +template void Reflect(JsonReader &vis, Maybe &v) { + if (!vis.IsNull()) Reflect(vis, *v); - } else +} +template void Reflect(JsonWriter &vis, Maybe &v) { + if (v) + Reflect(vis, *v); + else vis.Null(); } +template void Reflect(BinaryReader &vis, Maybe &v) { + if (*vis.p_++) + Reflect(vis, *v); +} +template void Reflect(BinaryWriter &vis, Maybe &v) { + if (v) { + vis.Pack(1); + Reflect(vis, *v); + } else { + vis.Pack(0); + } +} template -void ReflectMember(Writer &vis, const char *name, std::optional &v) { +void ReflectMember(JsonWriter &vis, const char *name, std::optional &v) { // For TypeScript std::optional property key?: value in the spec, // We omit both key and value if value is std::nullopt (null) for JsonWriter // to reduce output. But keep it for other serialization formats. - if (v || vis.Format() != SerializeFormat::Json) { + if (v) { vis.Key(name); - Reflect(vis, v); + Reflect(vis, *v); } } +template +void ReflectMember(BinaryWriter &vis, const char *, std::optional &v) { + Reflect(vis, v); +} // The same as std::optional template -void ReflectMember(Writer &vis, const char *name, Maybe &v) { - if (v.Valid() || vis.Format() != SerializeFormat::Json) { +void ReflectMember(JsonWriter &vis, const char *name, Maybe &v) { + if (v.Valid()) { vis.Key(name); Reflect(vis, v); } } +template +void ReflectMember(BinaryWriter &vis, const char *, Maybe &v) { + Reflect(vis, v); +} template -void Reflect(Reader &vis, std::pair &v) { +void Reflect(JsonReader &vis, std::pair &v) { vis.Member("L", [&]() { Reflect(vis, v.first); }); vis.Member("R", [&]() { Reflect(vis, v.second); }); } template -void Reflect(Writer &vis, std::pair &v) { +void Reflect(JsonWriter &vis, std::pair &v) { vis.StartObject(); ReflectMember(vis, "L", v.first); ReflectMember(vis, "R", v.second); vis.EndObject(); } +template +void Reflect(BinaryReader &vis, std::pair &v) { + Reflect(vis, v.first); + Reflect(vis, v.second); +} +template +void Reflect(BinaryWriter &vis, std::pair &v) { + Reflect(vis, v.first); + Reflect(vis, v.second); +} // std::vector -template void Reflect(Reader &vis, std::vector &vs) { - vis.IterArray([&](Reader &entry) { - T entry_value; - Reflect(entry, entry_value); - vs.push_back(std::move(entry_value)); +template void Reflect(JsonReader &vis, std::vector &v) { + vis.IterArray([&]() { + v.emplace_back(); + Reflect(vis, v.back()); }); } -template void Reflect(Writer &vis, std::vector &vs) { - vis.StartArray(vs.size()); - for (auto &v : vs) - Reflect(vis, v); +template void Reflect(JsonWriter &vis, std::vector &v) { + vis.StartArray(); + for (auto &it : v) + Reflect(vis, it); vis.EndArray(); } +template void Reflect(BinaryReader &vis, std::vector &v) { + for (auto n = vis.VarUInt(); n; n--) { + v.emplace_back(); + Reflect(vis, v.back()); + } +} +template void Reflect(BinaryWriter &vis, std::vector &v) { + vis.VarUInt(v.size()); + for (auto &it : v) + Reflect(vis, it); +} // ReflectMember -inline bool ReflectMemberStart(Reader &vis) { return false; } -inline bool ReflectMemberStart(Writer &vis) { - vis.StartObject(); - return true; -} +template void ReflectMemberStart(T &) {} +inline void ReflectMemberStart(JsonWriter &vis) { vis.StartObject(); } -inline void ReflectMemberEnd(Reader &vis) {} -inline void ReflectMemberEnd(Writer &vis) { vis.EndObject(); } +template void ReflectMemberEnd(T &) {} +inline void ReflectMemberEnd(JsonWriter &vis) { vis.EndObject(); } -template void ReflectMember(Reader &vis, const char *name, T &v) { +template void ReflectMember(JsonReader &vis, const char *name, T &v) { vis.Member(name, [&]() { Reflect(vis, v); }); } -template void ReflectMember(Writer &vis, const char *name, T &v) { +template void ReflectMember(JsonWriter &vis, const char *name, T &v) { vis.Key(name); Reflect(vis, v); } +template void ReflectMember(BinaryReader &vis, const char *, T &v) { + Reflect(vis, v); +} +template void ReflectMember(BinaryWriter &vis, const char *, T &v) { + Reflect(vis, v); +} // API diff --git a/src/serializers/binary.hh b/src/serializers/binary.hh deleted file mode 100644 index e995ec444..000000000 --- a/src/serializers/binary.hh +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "serializer.hh" - -#include - -namespace ccls { -class BinaryReader : public Reader { - const char *p_; - - template T Get() { - T ret; - memcpy(&ret, p_, sizeof(T)); - p_ += sizeof(T); - return ret; - } - - uint64_t VarUInt() { - auto x = *reinterpret_cast(p_++); - if (x < 253) - return x; - if (x == 253) - return Get(); - if (x == 254) - return Get(); - return Get(); - } - int64_t VarInt() { - uint64_t x = VarUInt(); - return int64_t(x >> 1 ^ -(x & 1)); - } - -public: - BinaryReader(std::string_view buf) : p_(buf.data()) {} - virtual ~BinaryReader(); - SerializeFormat Format() const override { return SerializeFormat::Binary; } - - bool IsBool() override { return true; } - // Abuse how the function is called in serializer.h - bool IsNull() override { return !*p_++; } - bool IsInt() override { return true; } - bool IsInt64() override { return true; } - bool IsUInt64() override { return true; } - bool IsDouble() override { return true; } - bool IsString() override { return true; } - - void GetNull() override {} - bool GetBool() override { return Get(); } - int GetInt() override { return VarInt(); } - int64_t GetInt64() override { return VarInt(); } - uint8_t GetUInt8() override { return Get(); } - uint32_t GetUInt32() override { return VarUInt(); } - uint64_t GetUInt64() override { return VarUInt(); } - double GetDouble() override { return Get(); } - const char *GetString() override { - const char *ret = p_; - while (*p_) - p_++; - p_++; - return ret; - } - - bool HasMember(const char *x) override { return true; } - std::unique_ptr operator[](const char *x) override { return {}; } - - void IterArray(std::function fn) override { - for (auto n = VarUInt(); n; n--) - fn(*this); - } - - void Member(const char *, std::function fn) override { fn(); } -}; - -class BinaryWriter : public Writer { - std::string buf_; - - template void Pack(T x) { - auto i = buf_.size(); - buf_.resize(i + sizeof(x)); - memcpy(buf_.data() + i, &x, sizeof(x)); - } - - void VarUInt(uint64_t n) { - if (n < 253) - Pack(n); - else if (n < 65536) { - Pack(253); - Pack(n); - } else if (n < 4294967296) { - Pack(254); - Pack(n); - } else { - Pack(255); - Pack(n); - } - } - void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); } - -public: - virtual ~BinaryWriter(); - SerializeFormat Format() const override { return SerializeFormat::Binary; } - std::string Take() { return std::move(buf_); } - - void Null() override { Pack(uint8_t(0)); } - void Bool(bool x) override { Pack(x); } - void Int(int x) override { VarInt(x); } - void Int64(int64_t x) override { VarInt(x); } - void UInt8(uint8_t x) override { Pack(x); } - void UInt32(uint32_t x) override { VarUInt(x); } - void UInt64(uint64_t x) override { VarUInt(x); } - void Double(double x) override { Pack(x); } - void String(const char *x) override { String(x, strlen(x)); } - void String(const char *x, size_t len) override { - auto i = buf_.size(); - buf_.resize(i + len + 1); - memcpy(buf_.data() + i, x, len); - } - void StartArray(size_t n) override { VarUInt(n); } - void EndArray() override {} - void StartObject() override {} - void EndObject() override {} - void Key(const char *name) override {} -}; -} // namespace ccls diff --git a/src/serializers/json.hh b/src/serializers/json.hh deleted file mode 100644 index a1d29b728..000000000 --- a/src/serializers/json.hh +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2017-2018 ccls Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#pragma once - -#include "serializer.hh" - -#include -#include - -namespace ccls { -class JsonReader : public Reader { - rapidjson::GenericValue> *m_; - std::vector path_; - -public: - JsonReader(rapidjson::GenericValue> *m) : m_(m) {} - virtual ~JsonReader(); - SerializeFormat Format() const override { return SerializeFormat::Json; } - rapidjson::GenericValue> &m() { return *m_; } - - bool IsBool() override { return m_->IsBool(); } - bool IsNull() override { return m_->IsNull(); } - bool IsInt() override { return m_->IsInt(); } - bool IsInt64() override { return m_->IsInt64(); } - bool IsUInt64() override { return m_->IsUint64(); } - bool IsDouble() override { return m_->IsDouble(); } - bool IsString() override { return m_->IsString(); } - - void GetNull() override {} - bool GetBool() override { return m_->GetBool(); } - int GetInt() override { return m_->GetInt(); } - int64_t GetInt64() override { return m_->GetInt64(); } - uint8_t GetUInt8() override { return uint8_t(m_->GetInt()); } - uint32_t GetUInt32() override { return uint32_t(m_->GetUint64()); } - uint64_t GetUInt64() override { return m_->GetUint64(); } - double GetDouble() override { return m_->GetDouble(); } - const char *GetString() override { return m_->GetString(); } - - bool HasMember(const char *x) override { return m_->HasMember(x); } - std::unique_ptr operator[](const char *x) override { - auto &sub = (*m_)[x]; - return std::unique_ptr(new JsonReader(&sub)); - } - - void IterArray(std::function fn) override { - if (!m_->IsArray()) - throw std::invalid_argument("array"); - // Use "0" to indicate any element for now. - path_.push_back("0"); - for (auto &entry : m_->GetArray()) { - auto saved = m_; - m_ = &entry; - fn(*this); - m_ = saved; - } - path_.pop_back(); - } - - void Member(const char *name, std::function fn) override { - path_.push_back(name); - auto it = m_->FindMember(name); - if (it != m_->MemberEnd()) { - auto saved = m_; - m_ = &it->value; - fn(); - m_ = saved; - } - path_.pop_back(); - } - - std::string GetPath() const { - std::string ret; - for (auto &t : path_) { - ret += '/'; - ret += t; - } - ret.pop_back(); - return ret; - } -}; - -class JsonWriter : public Writer { - rapidjson::Writer *m_; - -public: - JsonWriter(rapidjson::Writer *m) : m_(m) {} - virtual ~JsonWriter(); - SerializeFormat Format() const override { return SerializeFormat::Json; } - rapidjson::Writer &m() { return *m_; } - - void Null() override { m_->Null(); } - void Bool(bool x) override { m_->Bool(x); } - void Int(int x) override { m_->Int(x); } - void Int64(int64_t x) override { m_->Int64(x); } - void UInt8(uint8_t x) override { m_->Int(x); } - void UInt32(uint32_t x) override { m_->Uint64(x); } - void UInt64(uint64_t x) override { m_->Uint64(x); } - void Double(double x) override { m_->Double(x); } - void String(const char *x) override { m_->String(x); } - void String(const char *x, size_t len) override { m_->String(x, len); } - void StartArray(size_t) override { m_->StartArray(); } - void EndArray() override { m_->EndArray(); } - void StartObject() override { m_->StartObject(); } - void EndObject() override { m_->EndObject(); } - void Key(const char *name) override { m_->Key(name); } -}; -} // namespace ccls From d43b994557a948211d2f8e2d7e22b998ef837fb0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 3 Dec 2018 09:42:16 -0800 Subject: [PATCH 313/378] query: fix UpdateUses when a new entity is seen; simplify {DeclRef,Use,Usr}Update Thanks to Leszek Swirski --- src/query.cc | 2 +- src/query.hh | 28 ++++++++++++---------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/query.cc b/src/query.cc index 0906ee244..48247fac0 100644 --- a/src/query.cc +++ b/src/query.cc @@ -264,7 +264,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { auto &entities, auto &p, bool hint_implicit) { auto R = entity_usr.try_emplace(usr, entity_usr.size()); if (R.second) - vars.emplace_back().usr = usr; + entities.emplace_back().usr = usr; auto &entity = entities[R.first->second]; for (Use &use : p.first) { if (hint_implicit && use.role & Role::Implicit) { diff --git a/src/query.hh b/src/query.hh index 60f234335..a624b04fc 100644 --- a/src/query.hh +++ b/src/query.hh @@ -73,13 +73,9 @@ template struct QueryEntity { } }; -using DeclRefUpdate = - std::unordered_map, std::vector>>; -using UseUpdate = - std::unordered_map, std::vector>>; -using UsrUpdate = - std::unordered_map, std::vector>>; +template +using Update = + std::unordered_map, std::vector>>; struct QueryFunc : QueryEntity { Usr usr; @@ -126,25 +122,25 @@ struct IndexUpdate { int funcs_hint; std::vector> funcs_removed; std::vector> funcs_def_update; - DeclRefUpdate funcs_declarations; - UseUpdate funcs_uses; - UsrUpdate funcs_derived; + Update funcs_declarations; + Update funcs_uses; + Update funcs_derived; // Type updates. int types_hint; std::vector> types_removed; std::vector> types_def_update; - DeclRefUpdate types_declarations; - UseUpdate types_uses; - UsrUpdate types_derived; - UsrUpdate types_instances; + Update types_declarations; + Update types_uses; + Update types_derived; + Update types_instances; // Variable updates. int vars_hint; std::vector> vars_removed; std::vector> vars_def_update; - DeclRefUpdate vars_declarations; - UseUpdate vars_uses; + Update vars_declarations; + Update vars_uses; }; struct DenseMapInfoForUsr { From 259b9fefb30a1b2c69264ad34aef1ad1abba914f Mon Sep 17 00:00:00 2001 From: Leszek Swirski Date: Tue, 4 Dec 2018 18:28:40 +0100 Subject: [PATCH 314/378] Spin IncludeComplete's destructor until scanning completes (#147) --- src/include_complete.cc | 6 ++++++ src/include_complete.hh | 1 + 2 files changed, 7 insertions(+) diff --git a/src/include_complete.cc b/src/include_complete.cc index b7834d61d..05439ad4e 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -102,6 +102,12 @@ CompletionItem BuildCompletionItem(const std::string &path, IncludeComplete::IncludeComplete(Project *project) : is_scanning(false), project_(project) {} +IncludeComplete::~IncludeComplete() { + // Spin until the scanning has completed. + while (is_scanning.load()) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); +} + void IncludeComplete::Rescan() { if (is_scanning || LLVM_VERSION_MAJOR >= 8) return; diff --git a/src/include_complete.hh b/src/include_complete.hh index 6340c48d2..003dc7efd 100644 --- a/src/include_complete.hh +++ b/src/include_complete.hh @@ -26,6 +26,7 @@ struct Project; struct IncludeComplete { IncludeComplete(Project *project); + ~IncludeComplete(); // Starts scanning directories. Clears existing cache. void Rescan(); From 6945a56fb87268488a78c46570409b619c6973d1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 9 Dec 2018 13:50:58 -0800 Subject: [PATCH 315/378] Support multiple -init= Initialization options are applied (deserialized to the same object) in the following order: * "initializationOptions" from client * first -init= * second -init= * ... Scalar options will be overridden but arrays will get concatenated, e.g. ccls -log-file=/dev/stderr -index . -init='{"clang":{"extraArgs":["-DA"]}}' -init='{"clang":{"extraArgs":["-DB"]}}' results in clang.extraArgs: ["-DA", "-DB"] --- src/main.cc | 40 ++++++++++++++++++++------------------ src/messages/initialize.cc | 21 ++++++++++---------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/main.cc b/src/main.cc index 9a4ea630b..439302989 100644 --- a/src/main.cc +++ b/src/main.cc @@ -42,7 +42,7 @@ using namespace llvm; using namespace llvm::cl; namespace ccls { -std::string g_init_options; +std::vector g_init_options; } namespace { @@ -56,8 +56,8 @@ opt opt_test_index("test-index", ValueOptional, init("!"), opt opt_index("index", desc("standalone mode: index a project and exit"), value_desc("root"), cat(C)); -opt opt_init("init", desc("extra initialization options in JSON"), - cat(C)); +list opt_init("init", desc("extra initialization options in JSON"), + cat(C)); opt opt_log_file("log-file", desc("log"), value_desc("filename"), cat(C)); opt opt_log_file_append("log-file-append", desc("log"), @@ -118,23 +118,25 @@ int main(int argc, char **argv) { if (!opt_init.empty()) { // We check syntax error here but override client-side // initializationOptions in messages/initialize.cc - g_init_options = opt_init.getValue(); + g_init_options = opt_init; rapidjson::Document reader; - rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); - if (!ok) { - fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", - rapidjson::GetParseError_En(ok.Code()), ok.Offset()); - return 1; - } - JsonReader json_reader{&reader}; - try { - Config config; - Reflect(json_reader, config); - } catch (std::invalid_argument &e) { - fprintf(stderr, "Failed to parse --init %s, expected %s\n", - static_cast(json_reader).GetPath().c_str(), - e.what()); - return 1; + for (const std::string &str : g_init_options) { + rapidjson::ParseResult ok = reader.Parse(str.c_str()); + if (!ok) { + fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", + rapidjson::GetParseError_En(ok.Code()), ok.Offset()); + return 1; + } + JsonReader json_reader{&reader}; + try { + Config config; + Reflect(json_reader, config); + } catch (std::invalid_argument &e) { + fprintf(stderr, "Failed to parse --init %s, expected %s\n", + static_cast(json_reader).GetPath().c_str(), + e.what()); + return 1; + } } } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 474f01edb..e80b09d8a 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -36,8 +36,7 @@ limitations under the License. namespace ccls { using namespace llvm; -// TODO Cleanup global variables -extern std::string g_init_options; +extern std::vector g_init_options; namespace { enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 }; @@ -255,14 +254,16 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { { g_config = new Config(param.initializationOptions); rapidjson::Document reader; - reader.Parse(g_init_options.c_str()); - if (!reader.HasParseError()) { - JsonReader json_reader{&reader}; - try { - Reflect(json_reader, *g_config); - } catch (std::invalid_argument &) { - // This will not trigger because parse error is handled in - // MessageRegistry::Parse in lsp.cc + for (const std::string &str : g_init_options) { + reader.Parse(str.c_str()); + if (!reader.HasParseError()) { + JsonReader json_reader{&reader}; + try { + Reflect(json_reader, *g_config); + } catch (std::invalid_argument &) { + // This will not trigger because parse error is handled in + // MessageRegistry::Parse in lsp.cc + } } } From df7221affc339cebcec7c6f004f8addb24946d95 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 13 Dec 2018 20:13:35 -0800 Subject: [PATCH 316/378] Rendezvous after receiving "exit" notification (#159) --- src/messages/initialize.cc | 4 +-- src/pipeline.cc | 64 +++++++++++++++++++++++++++++++------- src/pipeline.hh | 4 +++ src/platform.hh | 2 ++ src/platform_posix.cc | 13 ++++++-- src/platform_win.cc | 2 ++ src/sema_manager.cc | 18 +++++++++++ src/sema_manager.hh | 3 +- src/threaded_queue.hh | 9 ++++-- 9 files changed, 100 insertions(+), 19 deletions(-) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index e80b09d8a..022da1921 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -242,6 +242,7 @@ void *Indexer(void *arg_) { std::string name = "indexer" + std::to_string(idx); set_thread_name(name.c_str()); pipeline::Indexer_Main(h->manager, h->vfs, h->project, h->wfiles); + pipeline::ThreadLeave(); return nullptr; } } // namespace @@ -365,7 +366,6 @@ void MessageHandler::shutdown(EmptyParam &, ReplyOnce &reply) { } void MessageHandler::exit(EmptyParam &) { - // FIXME cancel threads - ::exit(0); + pipeline::quit.store(true, std::memory_order_relaxed); } } // namespace ccls diff --git a/src/pipeline.cc b/src/pipeline.cc index ab6fd2e16..1d84669e6 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -77,6 +77,7 @@ void StandaloneInitialize(MessageHandler &, const std::string &root); namespace pipeline { +std::atomic quit; std::atomic loaded_ts = ATOMIC_VAR_INIT(0), pending_index_requests = ATOMIC_VAR_INIT(0); int64_t tick = 0; @@ -91,6 +92,10 @@ struct Index_Request { int64_t ts = tick++; }; +std::mutex thread_mtx; +std::condition_variable no_active_threads; +int active_threads; + MultiQueueWaiter *main_waiter; MultiQueueWaiter *indexer_waiter; MultiQueueWaiter *stdout_waiter; @@ -361,8 +366,31 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, return true; } +void Quit(SemaManager &manager) { + quit.store(true, std::memory_order_relaxed); + manager.Quit(); + + { std::lock_guard lock(index_request->mutex_); } + indexer_waiter->cv.notify_all(); + { std::lock_guard lock(for_stdout->mutex_); } + stdout_waiter->cv.notify_one(); + std::unique_lock lock(thread_mtx); + no_active_threads.wait(lock, [] { return !active_threads; }); +} + } // namespace +void ThreadEnter() { + std::lock_guard lock(thread_mtx); + active_threads++; +} + +void ThreadLeave() { + std::lock_guard lock(thread_mtx); + if (!--active_threads) + no_active_threads.notify_one(); +} + void Init() { main_waiter = new MultiQueueWaiter; on_request = new ThreadedQueue(main_waiter); @@ -380,7 +408,8 @@ void Indexer_Main(SemaManager *manager, VFS *vfs, Project *project, GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); while (true) if (!Indexer_Parse(manager, wfiles, project, vfs, matcher)) - indexer_waiter->Wait(index_request); + if (indexer_waiter->Wait(quit, index_request)) + break; } void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { @@ -419,6 +448,7 @@ void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { } void LaunchStdin() { + ThreadEnter(); std::thread([]() { set_thread_name("stdin"); std::string str; @@ -458,23 +488,27 @@ void LaunchStdin() { JsonReader reader{document.get()}; if (!reader.m->HasMember("jsonrpc") || std::string((*reader.m)["jsonrpc"].GetString()) != "2.0") - return; + break; RequestId id; std::string method; ReflectMember(reader, "id", id); ReflectMember(reader, "method", method); + if (method.empty()) + continue; + bool should_exit = method == "exit"; on_request->PushBack( {id, std::move(method), std::move(message), std::move(document)}); - if (method == "exit") + if (should_exit) break; } - }) - .detach(); + ThreadLeave(); + }).detach(); } void LaunchStdout() { - std::thread([=]() { + ThreadEnter(); + std::thread([]() { set_thread_name("stdout"); while (true) { @@ -483,10 +517,11 @@ void LaunchStdout() { llvm::outs() << "Content-Length: " << s.size() << "\r\n\r\n" << s; llvm::outs().flush(); } - stdout_waiter->Wait(for_stdout); + if (stdout_waiter->Wait(quit, for_stdout)) + break; } - }) - .detach(); + ThreadLeave(); + }).detach(); } void MainLoop() { @@ -540,16 +575,20 @@ void MainLoop() { Main_OnIndexed(&db, &wfiles, &*update); } - if (did_work) + if (did_work) { has_indexed |= indexed; - else { + if (quit.load(std::memory_order_relaxed)) + break; + } else { if (has_indexed) { FreeUnusedMemory(); has_indexed = false; } - main_waiter->Wait(on_indexed, on_request); + main_waiter->Wait(quit, on_indexed, on_request); } } + + Quit(manager); } void Standalone(const std::string &root) { @@ -590,6 +629,7 @@ void Standalone(const std::string &root) { } if (tty) puts(""); + Quit(manager); } void Index(const std::string &path, const std::vector &args, diff --git a/src/pipeline.hh b/src/pipeline.hh index e70d9dd8e..da6b44bc3 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -36,8 +36,12 @@ enum class IndexMode { }; namespace pipeline { +extern std::atomic quit; extern std::atomic loaded_ts, pending_index_requests; extern int64_t tick; + +void ThreadEnter(); +void ThreadLeave(); void Init(); void LaunchStdin(); void LaunchStdout(); diff --git a/src/platform.hh b/src/platform.hh index 076860f57..12446263b 100644 --- a/src/platform.hh +++ b/src/platform.hh @@ -19,6 +19,7 @@ limitations under the License. #include #include +namespace ccls { std::string NormalizePath(const std::string &path); // Free any unused memory and return it to the system. @@ -31,3 +32,4 @@ std::string GetExternalCommandOutput(const std::vector &command, std::string_view input); void SpawnThread(void *(*fn)(void *), void *arg); +} // namespace ccls diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 9dd79726c..35d8d271f 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -42,8 +42,16 @@ limitations under the License. #include #include +#include +#include +#include #include +namespace ccls { +namespace pipeline { +void ThreadEnter(); +} + std::string NormalizePath(const std::string &path) { llvm::SmallString<256> P(path); llvm::sys::path::remove_dots(P, true); @@ -113,14 +121,15 @@ void SpawnThread(void *(*fn)(void *), void *arg) { pthread_attr_t attr; struct rlimit rlim; size_t stack_size = 4 * 1024 * 1024; - if (getrlimit(RLIMIT_STACK, &rlim) == 0 && - rlim.rlim_cur != RLIM_INFINITY) + if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY) stack_size = rlim.rlim_cur; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&attr, stack_size); + pipeline::ThreadEnter(); pthread_create(&thd, &attr, fn, arg); pthread_attr_destroy(&attr); } +} // namespace ccls #endif diff --git a/src/platform_win.cc b/src/platform_win.cc index 31ba74e93..a2ca5185a 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -30,6 +30,7 @@ limitations under the License. #include #include +namespace ccls { std::string NormalizePath(const std::string &path) { DWORD retval = 0; TCHAR buffer[MAX_PATH] = TEXT(""); @@ -64,5 +65,6 @@ std::string GetExternalCommandOutput(const std::vector &command, void SpawnThread(void *(*fn)(void *), void *arg) { std::thread(fn, arg).detach(); } +} #endif diff --git a/src/sema_manager.cc b/src/sema_manager.cc index f5dee4119..194e703dc 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -18,6 +18,7 @@ limitations under the License. #include "clang_tu.hh" #include "filesystem.hh" #include "log.hh" +#include "pipeline.hh" #include "platform.hh" #include @@ -403,6 +404,8 @@ void *PreambleMain(void *manager_) { set_thread_name("preamble"); while (true) { SemaManager::PreambleTask task = manager->preamble_tasks.Dequeue(); + if (pipeline::quit.load(std::memory_order_relaxed)) + break; bool created = false; std::shared_ptr session = @@ -424,6 +427,7 @@ void *PreambleMain(void *manager_) { manager->ScheduleDiag(task.path, debounce); } } + pipeline::ThreadLeave(); return nullptr; } @@ -432,6 +436,8 @@ void *CompletionMain(void *manager_) { set_thread_name("comp"); while (true) { std::unique_ptr task = manager->comp_tasks.Dequeue(); + if (pipeline::quit.load(std::memory_order_relaxed)) + break; // Drop older requests if we're not buffering. while (g_config->completion.dropOldRequests && @@ -440,6 +446,8 @@ void *CompletionMain(void *manager_) { task->Consumer.reset(); task->on_complete(nullptr); task = manager->comp_tasks.Dequeue(); + if (pipeline::quit.load(std::memory_order_relaxed)) + break; } std::shared_ptr session = manager->EnsureSession(task->path); @@ -480,6 +488,7 @@ void *CompletionMain(void *manager_) { task->on_complete(&Clang->getCodeCompletionConsumer()); } + pipeline::ThreadLeave(); return nullptr; } @@ -516,6 +525,8 @@ void *DiagnosticMain(void *manager_) { set_thread_name("diag"); while (true) { SemaManager::DiagTask task = manager->diag_tasks.Dequeue(); + if (pipeline::quit.load(std::memory_order_relaxed)) + break; int64_t wait = task.wait_until - chrono::duration_cast( chrono::high_resolution_clock::now().time_since_epoch()) @@ -627,6 +638,7 @@ void *DiagnosticMain(void *manager_) { } manager->on_diagnostic_(task.path, ls_diags); } + pipeline::ThreadLeave(); return nullptr; } @@ -704,4 +716,10 @@ void SemaManager::Clear() { std::lock_guard lock(mutex); sessions.Clear(); } + +void SemaManager::Quit() { + comp_tasks.PushBack(nullptr); + diag_tasks.PushBack({}); + preamble_tasks.PushBack({}); +} } // namespace ccls diff --git a/src/sema_manager.hh b/src/sema_manager.hh index 632b2eaa0..5d5733492 100644 --- a/src/sema_manager.hh +++ b/src/sema_manager.hh @@ -148,7 +148,8 @@ struct SemaManager { void OnClose(const std::string &path); std::shared_ptr EnsureSession(const std::string &path, bool *created = nullptr); - void Clear(void); + void Clear(); + void Quit(); // Global state. Project *project_; diff --git a/src/threaded_queue.hh b/src/threaded_queue.hh index ced88be43..a2b5f48aa 100644 --- a/src/threaded_queue.hh +++ b/src/threaded_queue.hh @@ -66,10 +66,15 @@ struct MultiQueueWaiter { return false; } - template void Wait(BaseThreadQueue... queues) { + template + bool Wait(std::atomic &quit, BaseThreadQueue... queues) { MultiQueueLock l(queues...); - while (!HasState({queues...})) + while (!quit.load(std::memory_order_relaxed)) { + if (HasState({queues...})) + return false; cv.wait(l); + } + return true; } }; From 37a9ad3f8188dea9f709f926094877b79593559a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 13 Dec 2018 20:58:13 -0800 Subject: [PATCH 317/378] cmake_minimum_required 3.8; clean up --- CMakeLists.txt | 2 +- src/messages/textDocument_completion.cc | 11 +++++------ src/messages/textDocument_signatureHelp.cc | 12 ++++++++---- src/working_files.cc | 12 +++++------- src/working_files.hh | 14 ++++---------- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01f49968b..bf39ebfd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.8) project(ccls LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 771169904..3eb76b3ad 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -450,8 +450,8 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, ReplyOnce &reply) { static CompleteConsumerCache> cache; std::string path = param.textDocument.uri.GetPath(); - WorkingFile *file = wfiles->GetFile(path); - if (!file) { + WorkingFile *wf = wfiles->GetFile(path); + if (!wf) { reply.NotReady(true); return; } @@ -461,9 +461,8 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, // It shouldn't be possible, but sometimes vscode will send queries out // of order, ie, we get completion request before buffer content update. std::string buffer_line; - if (param.position.line >= 0 && - param.position.line < file->buffer_lines.size()) - buffer_line = file->buffer_lines[param.position.line]; + if (param.position.line >= 0 && param.position.line < wf->buffer_lines.size()) + buffer_line = wf->buffer_lines[param.position.line]; clang::CodeCompleteOptions CCOpts; CCOpts.IncludeBriefComments = true; @@ -499,7 +498,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, std::string filter; Position end_pos = param.position; Position begin_pos = - file->FindStableCompletionSource(param.position, &filter, &end_pos); + wf->GetCompletionPosition(param.position, &filter, &end_pos); #if LLVM_VERSION_MAJOR < 8 ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index b15def2a9..aa22ed73e 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -155,11 +155,15 @@ void MessageHandler::textDocument_signatureHelp( std::string path = param.textDocument.uri.GetPath(); Position begin_pos = param.position; - if (WorkingFile *file = wfiles->GetFile(path)) { - std::string completion_text; + WorkingFile *wf = wfiles->GetFile(path); + if (!wf) { + reply.NotReady(true); + return; + } + { + std::string filter; Position end_pos = param.position; - begin_pos = file->FindStableCompletionSource(param.position, - &completion_text, &end_pos); + begin_pos = wf->GetCompletionPosition(param.position, &filter, &end_pos); } SemaManager::OnComplete callback = diff --git a/src/working_files.cc b/src/working_files.cc index 0165ee96a..ba930c299 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -348,21 +348,19 @@ std::optional WorkingFile::GetIndexPosFromBufferPos(int line, int *column, index_lines, is_end); } -Position -WorkingFile::FindStableCompletionSource(Position position, - std::string *existing_completion, - Position *replace_end_pos) const { - int start = GetOffsetForPosition(position, buffer_content); +Position WorkingFile::GetCompletionPosition(Position pos, std::string *filter, + Position *replace_end_pos) const { + int start = GetOffsetForPosition(pos, buffer_content); int i = start; while (i > 0 && isIdentifierBody(buffer_content[i - 1])) --i; - *replace_end_pos = position; + *replace_end_pos = pos; for (int i = start; i < buffer_content.size() && isIdentifierBody(buffer_content[i]); i++) replace_end_pos->character++; - *existing_completion = buffer_content.substr(i, start - i); + *filter = buffer_content.substr(i, start - i); return GetPositionForOffset(buffer_content, i); } diff --git a/src/working_files.hh b/src/working_files.hh index 76128254c..b95cd8fe9 100644 --- a/src/working_files.hh +++ b/src/working_files.hh @@ -62,16 +62,10 @@ struct WorkingFile { // Also resolves |column| if not NULL. std::optional GetIndexPosFromBufferPos(int line, int *column, bool is_end); - // Returns a relatively stable completion position (it jumps back until there - // is a non-alphanumeric character). - // - // The out param |is_global_completion| is set to true if this looks like a - // global completion. - // The out param |existing_completion| is set to any existing completion - // content the user has entered. - Position FindStableCompletionSource(Position position, - std::string *existing_completion, - Position *replace_end_pos) const; + // Returns the stable completion position (it jumps back until there is a + // non-alphanumeric character). + Position GetCompletionPosition(Position pos, std::string *filter, + Position *replace_end_pos) const; private: // Compute index_to_buffer and buffer_to_index. From fc384429678dff37010e2baacdef740968b607c3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Dec 2018 19:53:00 -0800 Subject: [PATCH 318/378] Support textDocument/declaration & LocationLink textDocument/{declaration,definition,typeDefinition} return either LocationLink[] or Location[] Add an initialization option client.linkSupport . When it is false, ccls will return Location[] disregarding client's linkSupport. `struct LocationLink` does not include originSelectionRange as it is wasteful. --- src/config.hh | 30 ++++----- src/lsp.cc | 4 -- src/lsp.hh | 25 +++++++- src/message_handler.cc | 48 +++++++++------ src/message_handler.hh | 3 + src/messages/ccls_vars.cc | 10 +-- src/messages/initialize.cc | 14 ++++- src/messages/textDocument_definition.cc | 82 +++++++++++++++---------- src/query.cc | 29 ++++----- src/query.hh | 6 +- 10 files changed, 152 insertions(+), 99 deletions(-) diff --git a/src/config.hh b/src/config.hh index b0f5ff4f5..1fec1140c 100644 --- a/src/config.hh +++ b/src/config.hh @@ -85,6 +85,8 @@ struct Config { struct ClientCapability { // TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport bool hierarchicalDocumentSymbolSupport = true; + // TextDocumentClientCapabilities.definition.linkSupport + bool linkSupport = true; // TextDocumentClientCapabilities.completion.completionItem.snippetSupport bool snippetSupport = true; } client; @@ -260,30 +262,28 @@ struct Config { } xref; }; REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, - resourceDir); + resourceDir); REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, - snippetSupport); + linkSupport, snippetSupport); REFLECT_STRUCT(Config::CodeLens, localVariables); REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, - suffixWhitelist, whitelist); + suffixWhitelist, whitelist); REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, - dropOldRequests, duplicateOptional, filterAndSort, include, - maxNum); + dropOldRequests, duplicateOptional, filterAndSort, include, + maxNum); REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, - spellChecking, whitelist) -REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, - whitelist) + spellChecking, whitelist) +REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, - initialWhitelist, multiVersion, multiVersionBlacklist, - multiVersionWhitelist, onChange, threads, trackDependency, - whitelist); + initialWhitelist, multiVersion, multiVersionBlacklist, + multiVersionWhitelist, onChange, threads, trackDependency, + whitelist); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); REFLECT_STRUCT(Config::Xref, maxNum); -REFLECT_STRUCT(Config, compilationDatabaseCommand, - compilationDatabaseDirectory, cacheDirectory, cacheFormat, - clang, client, codeLens, completion, diagnostics, highlight, - index, session, workspaceSymbol, xref); +REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, + cacheDirectory, cacheFormat, clang, client, codeLens, completion, + diagnostics, highlight, index, session, workspaceSymbol, xref); extern Config *g_config; diff --git a/src/lsp.cc b/src/lsp.cc index caf7eec82..f5e2f3e98 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -60,10 +60,6 @@ DocumentUri DocumentUri::FromPath(const std::string &path) { return result; } -bool DocumentUri::operator==(const DocumentUri &other) const { - return raw_uri == other.raw_uri; -} - void DocumentUri::SetPath(const std::string &path) { // file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests raw_uri = path; diff --git a/src/lsp.hh b/src/lsp.hh index fecf9da27..c44dbdf52 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -72,7 +72,8 @@ constexpr char window_showMessage[] = "window/showMessage"; struct DocumentUri { static DocumentUri FromPath(const std::string &path); - bool operator==(const DocumentUri &other) const; + bool operator==(const DocumentUri &o) const { return raw_uri == o.raw_uri; } + bool operator<(const DocumentUri &o) const { return raw_uri < o.raw_uri; } void SetPath(const std::string &path); std::string GetPath() const; @@ -119,8 +120,26 @@ struct Location { return uri == o.uri && range == o.range; } bool operator<(const Location &o) const { - return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri - : range < o.range; + return !(uri == o.uri) ? uri < o.uri : range < o.range; + } +}; + +struct LocationLink { + std::string targetUri; + lsRange targetRange; + lsRange targetSelectionRange; + explicit operator bool() const { return targetUri.size(); } + explicit operator Location() && { + return {DocumentUri{std::move(targetUri)}, targetSelectionRange}; + } + bool operator==(const LocationLink &o) const { + return targetUri == o.targetUri && + targetSelectionRange == o.targetSelectionRange; + } + bool operator<(const LocationLink &o) const { + return !(targetUri == o.targetUri) + ? targetUri < o.targetUri + : targetSelectionRange < o.targetSelectionRange; } }; diff --git a/src/message_handler.cc b/src/message_handler.cc index 238baf0b8..99e8197cf 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -116,6 +116,21 @@ void ReplyOnce::NotReady(bool file) { Error(ErrorCode::InternalError, "not indexed"); } +void ReplyOnce::ReplyLocationLink(std::vector &result) { + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + if (result.size() > g_config->xref.maxNum) + result.resize(g_config->xref.maxNum); + if (g_config->client.linkSupport) { + (*this)(result); + } else { + std::vector result1; + for (auto &loc : result) + result1.emplace_back(std::move(loc)); + (*this)(result1); + } +} + void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(JsonReader &)) { method2notification[method] = [this, handler](JsonReader &reader) { @@ -155,6 +170,7 @@ void MessageHandler::Bind(const char *method, } MessageHandler::MessageHandler() { + // clang-format off Bind("$ccls/call", &MessageHandler::ccls_call); Bind("$ccls/fileInfo", &MessageHandler::ccls_fileInfo); Bind("$ccls/info", &MessageHandler::ccls_info); @@ -169,39 +185,31 @@ MessageHandler::MessageHandler() { Bind("textDocument/codeAction", &MessageHandler::textDocument_codeAction); Bind("textDocument/codeLens", &MessageHandler::textDocument_codeLens); Bind("textDocument/completion", &MessageHandler::textDocument_completion); + Bind("textDocument/declaration", &MessageHandler::textDocument_declaration); Bind("textDocument/definition", &MessageHandler::textDocument_definition); Bind("textDocument/didChange", &MessageHandler::textDocument_didChange); Bind("textDocument/didClose", &MessageHandler::textDocument_didClose); Bind("textDocument/didOpen", &MessageHandler::textDocument_didOpen); Bind("textDocument/didSave", &MessageHandler::textDocument_didSave); - Bind("textDocument/documentHighlight", - &MessageHandler::textDocument_documentHighlight); + Bind("textDocument/documentHighlight", &MessageHandler::textDocument_documentHighlight); Bind("textDocument/documentLink", &MessageHandler::textDocument_documentLink); - Bind("textDocument/documentSymbol", - &MessageHandler::textDocument_documentSymbol); + Bind("textDocument/documentSymbol", &MessageHandler::textDocument_documentSymbol); Bind("textDocument/foldingRange", &MessageHandler::textDocument_foldingRange); Bind("textDocument/formatting", &MessageHandler::textDocument_formatting); Bind("textDocument/hover", &MessageHandler::textDocument_hover); - Bind("textDocument/implementation", - &MessageHandler::textDocument_implementation); - Bind("textDocument/onTypeFormatting", - &MessageHandler::textDocument_onTypeFormatting); - Bind("textDocument/rangeFormatting", - &MessageHandler::textDocument_rangeFormatting); + Bind("textDocument/implementation", &MessageHandler::textDocument_implementation); + Bind("textDocument/onTypeFormatting", &MessageHandler::textDocument_onTypeFormatting); + Bind("textDocument/rangeFormatting", &MessageHandler::textDocument_rangeFormatting); Bind("textDocument/references", &MessageHandler::textDocument_references); Bind("textDocument/rename", &MessageHandler::textDocument_rename); - Bind("textDocument/signatureHelp", - &MessageHandler::textDocument_signatureHelp); - Bind("textDocument/typeDefinition", - &MessageHandler::textDocument_typeDefinition); - Bind("workspace/didChangeConfiguration", - &MessageHandler::workspace_didChangeConfiguration); - Bind("workspace/didChangeWatchedFiles", - &MessageHandler::workspace_didChangeWatchedFiles); - Bind("workspace/didChangeWorkspaceFolders", - &MessageHandler::workspace_didChangeWorkspaceFolders); + Bind("textDocument/signatureHelp", &MessageHandler::textDocument_signatureHelp); + Bind("textDocument/typeDefinition", &MessageHandler::textDocument_typeDefinition); + Bind("workspace/didChangeConfiguration", &MessageHandler::workspace_didChangeConfiguration); + Bind("workspace/didChangeWatchedFiles", &MessageHandler::workspace_didChangeWatchedFiles); + Bind("workspace/didChangeWorkspaceFolders", &MessageHandler::workspace_didChangeWorkspaceFolders); Bind("workspace/executeCommand", &MessageHandler::workspace_executeCommand); Bind("workspace/symbol", &MessageHandler::workspace_symbol); + // clang-format on } void MessageHandler::Run(InMessage &msg) { diff --git a/src/message_handler.hh b/src/message_handler.hh index a0b6f1cef..8ccde4a50 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -189,6 +189,7 @@ REFLECT_STRUCT(ResponseError, code, message); REFLECT_STRUCT(Position, line, character); REFLECT_STRUCT(lsRange, start, end); REFLECT_STRUCT(Location, uri, range); +REFLECT_STRUCT(LocationLink, targetUri, targetRange, targetSelectionRange); REFLECT_UNDERLYING_B(SymbolKind); REFLECT_STRUCT(TextDocumentIdentifier, uri); REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); @@ -210,6 +211,7 @@ struct ReplyOnce { pipeline::ReplyError(id, [&](JsonWriter &w) { Reflect(w, err); }); } void NotReady(bool file); + void ReplyLocationLink(std::vector &result); }; struct MessageHandler { @@ -252,6 +254,7 @@ private: void textDocument_codeAction(CodeActionParam &, ReplyOnce &); void textDocument_codeLens(TextDocumentParam &, ReplyOnce &); void textDocument_completion(CompletionParam &, ReplyOnce &); + void textDocument_declaration(TextDocumentPositionParam &, ReplyOnce &); void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &); void textDocument_didChange(TextDocumentDidChangeParam &); void textDocument_didClose(TextDocumentParam &); diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 03941491c..2673ecf06 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -51,12 +51,14 @@ void MessageHandler::ccls_vars(JsonReader &reader, ReplyOnce &reply) { usr = def->type; [[fallthrough]]; } - case Kind::Type: - result = GetLsLocations( - db, wfiles, - GetVarDeclarations(db, db->Type(usr).instances, param.kind)); + case Kind::Type: { + for (DeclRef dr : + GetVarDeclarations(db, db->Type(usr).instances, param.kind)) + if (auto loc = GetLocationLink(db, wfiles, dr)) + result.push_back(Location(std::move(loc))); break; } + } } reply(result); } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 022da1921..0aa0488c9 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -173,6 +173,11 @@ struct TextDocumentClientCap { } completionItem; } completion; + // Ignore declaration, implementation, typeDefinition + struct LinkSupport { + bool linkSupport = false; + } definition; + struct DocumentSymbol { bool hierarchicalDocumentSymbolSupport = false; } documentSymbol; @@ -183,7 +188,8 @@ REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem, REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem); REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol, hierarchicalDocumentSymbolSupport); -REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol); +REFLECT_STRUCT(TextDocumentClientCap::LinkSupport, linkSupport); +REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol); struct ClientCap { WorkspaceClientCap workspace; @@ -284,11 +290,13 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { // Client capabilities const auto &capabilities = param.capabilities; - g_config->client.snippetSupport &= - capabilities.textDocument.completion.completionItem.snippetSupport; g_config->client.hierarchicalDocumentSymbolSupport &= capabilities.textDocument.documentSymbol .hierarchicalDocumentSymbolSupport; + g_config->client.linkSupport &= + capabilities.textDocument.definition.linkSupport; + g_config->client.snippetSupport &= + capabilities.textDocument.completion.completionItem.snippetSupport; // Ensure there is a resource directory. if (g_config->clang.resourceDir.empty()) diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 62927547c..46f04cf97 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -45,6 +45,27 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { } } // namespace +void MessageHandler::textDocument_declaration(TextDocumentPositionParam ¶m, + ReplyOnce &reply) { + int file_id; + QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); + WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + if (!wf) { + reply.NotReady(file); + return; + } + + std::vector result; + Position &ls_pos = param.position; + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) + for (DeclRef dr : GetNonDefDeclarations(db, sym)) + if (!(dr.file_id == file_id && + dr.range.Contains(ls_pos.line, ls_pos.character))) + if (auto loc = GetLocationLink(db, wfiles, dr)) + result.push_back(loc); + reply.ReplyLocationLink(result); +} + void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; @@ -55,54 +76,52 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, return; } - std::vector result; - Maybe on_def; + std::vector result; + Maybe on_def; Position &ls_pos = param.position; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, ls_pos, true)) { // Special cases which are handled: // - symbol has declaration but no definition (ie, pure virtual) // - goto declaration while in definition of recursive type - std::vector uses; + std::vector drs; EachEntityDef(db, sym, [&](const auto &def) { if (def.spell) { - Use spell = *def.spell; + DeclRef spell = *def.spell; if (spell.file_id == file_id && spell.range.Contains(ls_pos.line, ls_pos.character)) { on_def = spell; - uses.clear(); + drs.clear(); return false; } - uses.push_back(spell); + drs.push_back(spell); } return true; }); // |uses| is empty if on a declaration/definition, otherwise it includes // all declarations/definitions. - if (uses.empty()) { - for (Use use : GetNonDefDeclarationTargets(db, sym)) - if (!(use.file_id == file_id && - use.range.Contains(ls_pos.line, ls_pos.character))) - uses.push_back(use); + if (drs.empty()) { + for (DeclRef dr : GetNonDefDeclarationTargets(db, sym)) + if (!(dr.file_id == file_id && + dr.range.Contains(ls_pos.line, ls_pos.character))) + drs.push_back(dr); // There is no declaration but the cursor is on a definition. - if (uses.empty() && on_def) - uses.push_back(*on_def); + if (drs.empty() && on_def) + drs.push_back(*on_def); } - auto locs = GetLsLocations(db, wfiles, uses); - result.insert(result.end(), locs.begin(), locs.end()); + for (DeclRef dr : drs) + if (auto loc = GetLocationLink(db, wfiles, dr)) + result.push_back(loc); } - if (result.size()) { - std::sort(result.begin(), result.end()); - result.erase(std::unique(result.begin(), result.end()), result.end()); - } else { + if (result.empty()) { Maybe range; // Check #include for (const IndexInclude &include : file->def->includes) { if (include.line == ls_pos.line) { result.push_back( - Location{DocumentUri::FromPath(include.resolved_path)}); + {DocumentUri::FromPath(include.resolved_path).raw_uri}); range = {{0, 0}, {0, 0}}; break; } @@ -160,13 +179,13 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, if (best_sym.kind != Kind::Invalid) { Maybe dr = GetDefinitionSpell(db, best_sym); assert(dr); - if (auto loc = GetLsLocation(db, wfiles, *dr)) - result.push_back(*loc); + if (auto loc = GetLocationLink(db, wfiles, *dr)) + result.push_back(loc); } } } - reply(result); + reply.ReplyLocationLink(result); } void MessageHandler::textDocument_typeDefinition( @@ -178,17 +197,16 @@ void MessageHandler::textDocument_typeDefinition( return; } - std::vector result; + std::vector result; auto Add = [&](const QueryType &type) { for (const auto &def : type.def) - if (def.spell) { - if (auto ls_loc = GetLsLocation(db, wfiles, *def.spell)) - result.push_back(*ls_loc); - } + if (def.spell) + if (auto loc = GetLocationLink(db, wfiles, *def.spell)) + result.push_back(loc); if (result.empty()) for (const DeclRef &dr : type.declarations) - if (auto ls_loc = GetLsLocation(db, wfiles, dr)) - result.push_back(*ls_loc); + if (auto loc = GetLocationLink(db, wfiles, dr)) + result.push_back(loc); }; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { switch (sym.kind) { @@ -211,8 +229,6 @@ void MessageHandler::textDocument_typeDefinition( } } - std::sort(result.begin(), result.end()); - result.erase(std::unique(result.begin(), result.end()), result.end()); - reply(result); + reply.ReplyLocationLink(result); } } // namespace ccls diff --git a/src/query.cc b/src/query.cc index 48247fac0..aa305a3ea 100644 --- a/src/query.cc +++ b/src/query.cc @@ -532,9 +532,9 @@ std::vector GetFuncDeclarations(DB *db, const std::vector &usrs) { std::vector GetTypeDeclarations(DB *db, const std::vector &usrs) { return GetDeclarations(db->type_usr, db->types, usrs); } -std::vector GetVarDeclarations(DB *db, const std::vector &usrs, - unsigned kind) { - std::vector ret; +std::vector GetVarDeclarations(DB *db, const std::vector &usrs, + unsigned kind) { + std::vector ret; ret.reserve(usrs.size()); for (Usr usr : usrs) { QueryVar &var = db->Var(usr); @@ -681,17 +681,18 @@ std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id}); } -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, - const std::vector &uses) { - std::vector ret; - for (Use use : uses) - if (auto loc = GetLsLocation(db, wfiles, use)) - ret.push_back(*loc); - std::sort(ret.begin(), ret.end()); - ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); - if (ret.size() > g_config->xref.maxNum) - ret.resize(g_config->xref.maxNum); - return ret; +LocationLink GetLocationLink(DB *db, WorkingFiles *wfiles, DeclRef dr) { + std::string path; + DocumentUri uri = GetLsDocumentUri(db, dr.file_id, &path); + if (auto range = GetLsRange(wfiles->GetFile(path), dr.range)) + if (auto extent = GetLsRange(wfiles->GetFile(path), dr.extent)) { + LocationLink ret; + ret.targetUri = uri.raw_uri; + ret.targetSelectionRange = *range; + ret.targetRange = extent->Includes(*range) ? *extent : *range; + return ret; + } + return {}; } SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) { diff --git a/src/query.hh b/src/query.hh index a624b04fc..92befe885 100644 --- a/src/query.hh +++ b/src/query.hh @@ -200,7 +200,7 @@ Maybe GetDefinitionSpell(DB *db, SymbolIdx sym); // for each id. std::vector GetFuncDeclarations(DB *, const std::vector &); std::vector GetTypeDeclarations(DB *, const std::vector &); -std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); +std::vector GetVarDeclarations(DB *, const std::vector &, unsigned); // Get non-defining declarations. std::vector &GetNonDefDeclarations(DB *db, SymbolIdx sym); @@ -215,8 +215,8 @@ DocumentUri GetLsDocumentUri(DB *db, int file_id); std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, Use use); std::optional GetLsLocation(DB *db, WorkingFiles *wfiles, SymbolRef sym, int file_id); -std::vector GetLsLocations(DB *db, WorkingFiles *wfiles, - const std::vector &uses); +LocationLink GetLocationLink(DB *db, WorkingFiles *wfiles, DeclRef dr); + // Returns a symbol. The symbol will *NOT* have a location assigned. std::optional GetSymbolInfo(DB *db, SymbolIdx sym, bool detailed); From e0a6db8d9b15226b428f2519e29b76fbe0ff505d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 16 Dec 2018 20:47:14 -0800 Subject: [PATCH 319/378] ParameterInformation: use label: [number, number] Don't bother checking signatureHelp.signatureInformationparameterInformation.labelOffsetSupport --- src/messages/textDocument_signatureHelp.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index aa22ed73e..3806ffe89 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -24,7 +24,7 @@ using namespace clang; namespace { struct ParameterInformation { - std::string label; + std::vector label; }; struct SignatureInformation { std::string label; @@ -40,13 +40,12 @@ REFLECT_STRUCT(ParameterInformation, label); REFLECT_STRUCT(SignatureInformation, label, documentation, parameters); REFLECT_STRUCT(SignatureHelp, signatures, activeSignature, activeParameter); -std::string BuildOptional(const CodeCompletionString &CCS, - std::vector &ls_params) { - std::string ret; +void BuildOptional(const CodeCompletionString &CCS, std::string &label, + std::vector &ls_params) { for (const auto &Chunk : CCS) { switch (Chunk.Kind) { case CodeCompletionString::CK_Optional: - ret += BuildOptional(*Chunk.Optional, ls_params); + BuildOptional(*Chunk.Optional, label, ls_params); break; case CodeCompletionString::CK_Placeholder: // A string that acts as a placeholder for, e.g., a function call @@ -56,18 +55,18 @@ std::string BuildOptional(const CodeCompletionString &CCS, // A piece of text that describes the parameter that corresponds to // the code-completion location within a function call, message send, // macro invocation, etc. - ret += Chunk.Text; - ls_params.push_back({Chunk.Text}); + int off = (int)label.size(); + label += Chunk.Text; + ls_params.push_back({{off, (int)label.size()}}); break; } case CodeCompletionString::CK_VerticalSpace: break; default: - ret += Chunk.Text; + label += Chunk.Text; break; } } - return ret; } class SignatureHelpConsumer : public CodeCompleteConsumer { @@ -115,12 +114,13 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { break; case CodeCompletionString::CK_Placeholder: case CodeCompletionString::CK_CurrentParameter: { + int off = (int)ls_sig.label.size(); ls_sig.label += Chunk.Text; - ls_sig.parameters.push_back({Chunk.Text}); + ls_sig.parameters.push_back({{off, (int)ls_sig.label.size()}}); break; } case CodeCompletionString::CK_Optional: - ls_sig.label += BuildOptional(*Chunk.Optional, ls_sig.parameters); + BuildOptional(*Chunk.Optional, ls_sig.label, ls_sig.parameters); break; case CodeCompletionString::CK_VerticalSpace: break; From 18e4be616c8edefd975af524a72923c7183a0197 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Dec 2018 00:00:42 -0800 Subject: [PATCH 320/378] Add `strict` to FuzzyMatcher::Match In completion, underscore prefixed builtin macros may be annoying when the first type character is not an underscore. When `strict` is true, `Match` enforces the first characters should be loosely of the same category. --- src/fuzzy_match.cc | 6 +++++- src/fuzzy_match.hh | 2 +- src/messages/textDocument_completion.cc | 2 +- src/messages/workspace.cc | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/fuzzy_match.cc b/src/fuzzy_match.cc index 680aa4acb..7f70b168e 100644 --- a/src/fuzzy_match.cc +++ b/src/fuzzy_match.cc @@ -107,7 +107,9 @@ FuzzyMatcher::FuzzyMatcher(std::string_view pattern, int sensitivity) { } } -int FuzzyMatcher::Match(std::string_view text) { +int FuzzyMatcher::Match(std::string_view text, bool strict) { + if (pat.empty() != text.empty()) + return kMinScore; int n = int(text.size()); if (n > kMaxText) return kMinScore + 1; @@ -115,6 +117,8 @@ int FuzzyMatcher::Match(std::string_view text) { for (int i = 0; i < n; i++) low_text[i] = ::tolower(text[i]); CalculateRoles(text, text_role, &text_set); + if (strict && n && !!pat_role[0] != !!text_role[0]) + return kMinScore; dp[0][0][0] = dp[0][0][1] = 0; for (int j = 0; j < n; j++) { dp[0][j + 1][0] = dp[0][j][0] + MissScore(j, false); diff --git a/src/fuzzy_match.hh b/src/fuzzy_match.hh index 9153c6c01..a7a98a9e6 100644 --- a/src/fuzzy_match.hh +++ b/src/fuzzy_match.hh @@ -29,7 +29,7 @@ public: constexpr static int kMinScore = INT_MIN / 4; FuzzyMatcher(std::string_view pattern, int case_sensitivity); - int Match(std::string_view text); + int Match(std::string_view text, bool strict); private: int case_sensitivity; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 3eb76b3ad..be84bad74 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -175,7 +175,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, const std::string &filter = item.filterText.size() ? item.filterText : item.label; item.score_ = ReverseSubseqMatch(complete_text, filter, sensitive) >= 0 - ? fuzzy.Match(filter) + ? fuzzy.Match(filter, true) : FuzzyMatcher::kMinScore; } items.erase(std::remove_if(items.begin(), items.end(), diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 5661a5d65..5b0499586 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -180,8 +180,8 @@ void MessageHandler::workspace_symbol(WorkspaceSymbolParam ¶m, longest, int(db->GetSymbolName(std::get<2>(cand), true).size())); FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity); for (auto &cand : cands) - std::get<1>(cand) = - fuzzy.Match(db->GetSymbolName(std::get<2>(cand), std::get<1>(cand))); + std::get<1>(cand) = fuzzy.Match( + db->GetSymbolName(std::get<2>(cand), std::get<1>(cand)), false); std::sort(cands.begin(), cands.end(), [](const auto &l, const auto &r) { return std::get<1>(l) > std::get<1>(r); }); From 8ca0978804618a5f3797e8c07c99e5b46564cb79 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 21 Dec 2018 18:23:35 -0800 Subject: [PATCH 321/378] Make -v=1 work and log cflags for SemaManager session and Indexer --- src/log.hh | 3 ++- src/main.cc | 1 + src/pipeline.cc | 10 +++++++++- src/sema_manager.cc | 8 +++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/log.hh b/src/log.hh index 64fc63d6b..5d06d41af 100644 --- a/src/log.hh +++ b/src/log.hh @@ -37,4 +37,5 @@ struct Message { #define LOG_IF_S(v, cond) \ LOG_IF(ccls::log::Verbosity_##v, \ (cond) && ccls::log::Verbosity_##v <= ccls::log::verbosity) -#define LOG_V(v) LOG_IF(ccls::log::Verbosity(v), v <= ccls::log::verbosity) +#define LOG_V_ENABLED(v) (v <= ccls::log::verbosity) +#define LOG_V(v) LOG_IF(ccls::log::Verbosity(v), LOG_V_ENABLED(v)) diff --git a/src/main.cc b/src/main.cc index 439302989..95cd0363c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -86,6 +86,7 @@ int main(int argc, char **argv) { PrintHelpMessage(); return 0; } + ccls::log::verbosity = ccls::log::Verbosity(opt_verbose.getValue()); pipeline::Init(); const char *env = getenv("CCLS_CRASH_RECOVERY"); diff --git a/src/pipeline.cc b/src/pipeline.cc index 1d84669e6..26e57d823 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -300,7 +300,15 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, return true; } while (0); - LOG_IF_S(INFO, loud) << "parse " << path_to_index; + if (loud) { + std::string line; + if (LOG_V_ENABLED(1)) { + line = "\n "; + for (auto &arg : entry.args) + (line += ' ') += arg; + } + LOG_S(INFO) << "parse " << path_to_index << line; + } std::vector> remapped; if (g_config->index.onChange) { diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 194e703dc..3d969b364 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -703,7 +703,13 @@ SemaManager::EnsureSession(const std::string &path, bool *created) { if (!session) { session = std::make_shared( project_->FindEntry(path, false), wfiles, PCH); - LOG_S(INFO) << "create session for " << path; + std::string line; + if (LOG_V_ENABLED(1)) { + line = "\n "; + for (auto &arg : session->file.args) + (line += ' ') += arg; + } + LOG_S(INFO) << "create session for " << path << line; sessions.Insert(path, session); if (created) *created = true; From 573bfc27a10938427da67863efdda081d2ccd8cd Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 21 Dec 2018 01:05:23 -0800 Subject: [PATCH 322/378] Extend .ccls * Add %h for C header files (the suffix .h is considered a C header, not a C++ header) * Add %hpp for C++ header files * If .ccls exists, it provides full command line for files not specified by compile_commands.json (before, compile_commands.json was ignored) * If the first line of .ccls is %compile_commands.json, it appends flags to compile_commands.json "arguments", instead of overriding. Files not specified by compile_commands.json will not be added to folder.entries, but their command line can be inferred from other files. Also fix `#include <` completion of -I flags for clang < 8 --- src/include_complete.cc | 119 +++---- src/include_complete.hh | 5 - src/message_handler.hh | 2 +- src/messages/textDocument_completion.cc | 15 +- src/pipeline.cc | 4 +- src/project.cc | 427 +++++++++++++----------- src/project.hh | 13 +- 7 files changed, 298 insertions(+), 287 deletions(-) diff --git a/src/include_complete.cc b/src/include_complete.cc index 05439ad4e..03e206c13 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -60,40 +60,26 @@ size_t TrimCommonPathPrefix(const std::string &result, return 0; } -// Returns true iff angle brackets should be used. -bool TrimPath(Project *project, std::string &path) { +int TrimPath(Project *project, std::string &path) { size_t pos = 0; - bool angle = false; - for (auto &[root, folder] : project->root2folder) { - size_t pos1 = 0; - for (auto &search : folder.angle_search_list) - pos1 = std::max(pos1, TrimCommonPathPrefix(path, search)); - if (pos1 > pos) { - pos = pos1; - angle = true; - } - - pos1 = TrimCommonPathPrefix(path, root); - for (auto &search : folder.quote_search_list) - pos1 = std::max(pos1, TrimCommonPathPrefix(path, search)); - if (pos1 > pos) { - pos = pos1; - angle = false; - } - } + int kind = 0; + for (auto &[root, folder] : project->root2folder) + for (auto &[search, search_dir_kind] : folder.search_dir2kind) + if (int t = TrimCommonPathPrefix(path, search); t > pos) + pos = t, kind = search_dir_kind; path = path.substr(pos); - return angle; + return kind; } CompletionItem BuildCompletionItem(const std::string &path, - bool use_angle_brackets) { + int kind) { CompletionItem item; item.label = ElideLongPath(path); item.detail = path; // the include path, used in de-duplicating item.textEdit.newText = path; item.insertTextFormat = InsertTextFormat::PlainText; - item.use_angle_brackets_ = use_angle_brackets; item.kind = CompletionItemKind::File; + item.quote_kind_ = kind; item.priority_ = 0; return item; } @@ -125,14 +111,41 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { set_thread_name("include"); - std::unordered_set angle_set, quote_set; for (auto &[root, folder] : project_->root2folder) { - for (const std::string &search : folder.angle_search_list) - if (angle_set.insert(search).second) - InsertIncludesFromDirectory(search, true); - for (const std::string &search : folder.quote_search_list) - if (quote_set.insert(search).second) - InsertIncludesFromDirectory(search, false); + for (auto &search_kind : folder.search_dir2kind) { + const std::string &search = search_kind.first; + int kind = search_kind.second; + assert(search.back() == '/'); + if (match_ && !match_->Matches(search)) + return; + bool include_cpp = search.find("include/c++") != std::string::npos; + + std::vector results; + GetFilesInFolder(search, true /*recursive*/, + false /*add_folder_to_path*/, + [&](const std::string &path) { + bool ok = include_cpp; + for (StringRef suffix : + g_config->completion.include.suffixWhitelist) + if (StringRef(path).endswith(suffix)) + ok = true; + if (!ok) + return; + if (match_ && !match_->Matches(search + path)) + return; + + CompletionCandidate candidate; + candidate.absolute_path = search + path; + candidate.completion_item = + BuildCompletionItem(path, kind); + results.push_back(candidate); + }); + + std::lock_guard lock(completion_items_mutex); + for (CompletionCandidate &result : results) + InsertCompletionItem(result.absolute_path, + std::move(result.completion_item)); + } } is_scanning = false; @@ -142,7 +155,7 @@ void IncludeComplete::Rescan() { void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, CompletionItem &&item) { - if (inserted_paths.insert({item.detail, inserted_paths.size()}).second) { + if (inserted_paths.try_emplace(item.detail, inserted_paths.size()).second) { completion_items.push_back(item); // insert if not found or with shorter include path auto it = absolute_path_to_completion_item.find(absolute_path); @@ -151,12 +164,6 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, absolute_path_to_completion_item[absolute_path] = completion_items.size() - 1; } - } else { - CompletionItem &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; } } @@ -171,8 +178,8 @@ void IncludeComplete::AddFile(const std::string &path) { return; std::string trimmed_path = path; - bool use_angle_brackets = TrimPath(project_, trimmed_path); - CompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets); + int kind = TrimPath(project_, trimmed_path); + CompletionItem item = BuildCompletionItem(trimmed_path, kind); std::unique_lock lock(completion_items_mutex, std::defer_lock); if (is_scanning) @@ -180,40 +187,6 @@ void IncludeComplete::AddFile(const std::string &path) { InsertCompletionItem(path, std::move(item)); } -void IncludeComplete::InsertIncludesFromDirectory(std::string directory, - bool use_angle_brackets) { - directory = NormalizePath(directory); - EnsureEndsInSlash(directory); - if (match_ && !match_->Matches(directory)) - return; - bool include_cpp = directory.find("include/c++") != std::string::npos; - - std::vector results; - GetFilesInFolder( - directory, true /*recursive*/, false /*add_folder_to_path*/, - [&](const std::string &path) { - bool ok = include_cpp; - for (StringRef suffix : g_config->completion.include.suffixWhitelist) - if (StringRef(path).endswith(suffix)) - ok = true; - if (!ok) - return; - if (match_ && !match_->Matches(directory + path)) - return; - - CompletionCandidate candidate; - candidate.absolute_path = directory + path; - candidate.completion_item = - BuildCompletionItem(path, use_angle_brackets); - results.push_back(candidate); - }); - - std::lock_guard lock(completion_items_mutex); - for (CompletionCandidate &result : results) - InsertCompletionItem(result.absolute_path, - std::move(result.completion_item)); -} - std::optional IncludeComplete::FindCompletionItemForAbsolutePath( const std::string &absolute_path) { diff --git a/src/include_complete.hh b/src/include_complete.hh index 003dc7efd..7256195a7 100644 --- a/src/include_complete.hh +++ b/src/include_complete.hh @@ -34,11 +34,6 @@ struct IncludeComplete { // Ensures the one-off file is inside |completion_items|. void AddFile(const std::string &absolute_path); - // Scans the given directory and inserts all includes from this. This is a - // blocking function and should be run off the querydb thread. - void InsertIncludesFromDirectory(std::string directory, - bool use_angle_brackets); - std::optional FindCompletionItemForAbsolutePath(const std::string &absolute_path); diff --git a/src/message_handler.hh b/src/message_handler.hh index 8ccde4a50..7063fe1ca 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -127,7 +127,7 @@ struct CompletionItem { std::vector parameters_; int score_; unsigned priority_; - bool use_angle_brackets_ = false; + int quote_kind_ = 0; }; // formatting diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index be84bad74..318401936 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -61,9 +61,10 @@ REFLECT_STRUCT(CompletionList, isIncomplete, items); #if LLVM_VERSION_MAJOR < 8 void DecorateIncludePaths(const std::smatch &match, - std::vector *items) { + std::vector *items, + char quote) { std::string spaces_after_include = " "; - if (match[3].compare("include") == 0 && match[5].length()) + if (match[3].compare("include") == 0 && quote != '\0') spaces_after_include = match[4].str(); std::string prefix = @@ -72,8 +73,7 @@ void DecorateIncludePaths(const std::smatch &match, for (CompletionItem &item : *items) { char quote0, quote1; - if (match[5].compare("<") == 0 || - (match[5].length() == 0 && item.use_angle_brackets_)) + if (quote != '"') quote0 = '<', quote1 = '>'; else quote0 = quote1 = '"'; @@ -504,21 +504,22 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); if (preprocess.ok && preprocess.keyword.compare("include") == 0) { CompletionList result; + char quote = std::string(preprocess.match[5])[0]; { std::unique_lock lock( include_complete->completion_items_mutex, std::defer_lock); if (include_complete->is_scanning) lock.lock(); - std::string quote = preprocess.match[5]; for (auto &item : include_complete->completion_items) - if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) + if (quote == '\0' || (item.quote_kind_ & 1 && quote == '"') || + (item.quote_kind_ & 2 && quote == '<')) result.items.push_back(item); } begin_pos.character = 0; end_pos.character = (int)buffer_line.size(); FilterCandidates(result, preprocess.pattern, begin_pos, end_pos, buffer_line); - DecorateIncludePaths(preprocess.match, &result.items); + DecorateIncludePaths(preprocess.match, &result.items, quote); reply(result); return; } diff --git a/src/pipeline.cc b/src/pipeline.cc index 26e57d823..829fe796f 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -293,7 +293,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, on_indexed->PushBack(std::move(update), request.mode != IndexMode::NonInteractive); if (entry.id >= 0) { - std::lock_guard lock2(project->mutex_); + std::lock_guard lock2(project->mtx); project->root2folder[entry.root].path2entry_index[path] = entry.id; } } @@ -363,7 +363,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, vfs->state[path].loaded = true; } if (entry.id >= 0) { - std::lock_guard lock(project->mutex_); + std::lock_guard lock(project->mtx); auto &folder = project->root2folder[entry.root]; for (auto &dep : curr->dependencies) folder.path2entry_index[dep.first.val().str()] = entry.id; diff --git a/src/project.cc b/src/project.cc index 5a2de3dae..050e645c2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -67,15 +67,6 @@ std::pair lookupExtension(std::string_view filename) { namespace { -enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; - -struct ProjectConfig { - std::unordered_set quote_dirs; - std::unordered_set angle_dirs; - std::string root; - ProjectMode mode = ProjectMode::CompileCommandsJson; -}; - enum OptionClass { EqOrJoinOrSep, EqOrSep, @@ -84,30 +75,33 @@ enum OptionClass { }; struct ProjectProcessor { - ProjectConfig *config; + Project::Folder &folder; std::unordered_set command_set; StringSet<> excludeArgs; - ProjectProcessor(ProjectConfig *config) : config(config) { + ProjectProcessor(Project::Folder &folder) : folder(folder) { for (auto &arg : g_config->clang.excludeArgs) excludeArgs.insert(arg); } + // Expand %c %cpp ... in .ccls void Process(Project::Entry &entry) { - const std::string base_name = sys::path::filename(entry.filename); - - // Expand %c %cpp %clang - std::vector args; - args.reserve(entry.args.size() + g_config->clang.extraArgs.size() + 1); - const LanguageId lang = lookupExtension(entry.filename).first; - for (const char *arg : entry.args) { + std::vector args(entry.args.begin(), + entry.args.begin() + entry.compdb_size); + auto [lang, header] = lookupExtension(entry.filename); + for (int i = entry.compdb_size; i < entry.args.size(); i++) { + const char *arg = entry.args[i]; StringRef A(arg); if (A[0] == '%') { bool ok = false; for (;;) { if (A.consume_front("%c ")) ok |= lang == LanguageId::C; + else if (A.consume_front("%h ")) + ok |= lang == LanguageId::C && header; else if (A.consume_front("%cpp ")) ok |= lang == LanguageId::Cpp; + else if (A.consume_front("%hpp ")) + ok |= lang == LanguageId::Cpp && header; else if (A.consume_front("%objective-c ")) ok |= lang == LanguageId::ObjC; else if (A.consume_front("%objective-cpp ")) @@ -121,14 +115,16 @@ struct ProjectProcessor { args.push_back(arg); } } - if (args.empty()) - return; - for (const std::string &arg : g_config->clang.extraArgs) - args.push_back(Intern(arg)); + entry.args = args; + GetSearchDirs(entry); + } + void GetSearchDirs(Project::Entry &entry) { +#if LLVM_VERSION_MAJOR < 8 + const std::string base_name = sys::path::filename(entry.filename); size_t hash = std::hash{}(entry.directory); bool OPT_o = false; - for (auto &arg : args) { + for (auto &arg : entry.args) { bool last_o = OPT_o; OPT_o = false; if (arg[0] == '-') { @@ -146,12 +142,14 @@ struct ProjectProcessor { } hash_combine(hash, std::hash{}(arg)); } - args.push_back(Intern("-working-directory=" + entry.directory)); - entry.args = args; -#if LLVM_VERSION_MAJOR < 8 - args.push_back("-fsyntax-only"); if (!command_set.insert(hash).second) return; + auto args = entry.args; + args.push_back("-fsyntax-only"); + for (const std::string &arg : g_config->clang.extraArgs) + args.push_back(Intern(arg)); + args.push_back(Intern("-working-directory=" + entry.directory)); + args.push_back(Intern("-resource-dir=" + g_config->clang.resourceDir)); // a weird C++ deduction guide heap-use-after-free causes libclang to crash. IgnoringDiagConsumer DiagC; @@ -186,16 +184,16 @@ struct ProjectProcessor { for (auto &E : HeaderOpts.UserEntries) { std::string path = NormalizePath(ResolveIfRelative(entry.directory, E.Path)); + EnsureEndsInSlash(path); switch (E.Group) { default: - config->angle_dirs.insert(path); + folder.search_dir2kind[path] |= 2; break; case frontend::Quoted: - config->quote_dirs.insert(path); + folder.search_dir2kind[path] |= 1; break; case frontend::Angled: - config->angle_dirs.insert(path); - config->quote_dirs.insert(path); + folder.search_dir2kind[path] |= 3; break; } } @@ -217,23 +215,47 @@ ReadCompilerArgumentsFromFile(const std::string &path) { return args; } -std::vector LoadFromDirectoryListing(ProjectConfig *config) { - std::vector result; - config->mode = ProjectMode::DotCcls; +bool AppendToCDB(const std::vector &args) { + return args.size() && StringRef("%compile_commands.json") == args[0]; +} - std::unordered_map> folder_args; +std::vector GetFallback(const std::string path) { + std::vector argv{"clang"}; + if (sys::path::extension(path) == ".h") + argv.push_back("-xobjective-c++-header"); + argv.push_back(Intern(path)); + return argv; +} + +void LoadDirectoryListing(ProjectProcessor &proc, const std::string &root, + const StringSet<> &Seen) { + Project::Folder &folder = proc.folder; std::vector files; - const std::string &root = config->root; - GetFilesInFolder(root, true /*recursive*/, - true /*add_folder_to_path*/, - [&folder_args, &files](const std::string &path) { + auto GetDotCcls = [&root, &folder](std::string cur) { + while (!(cur = sys::path::parent_path(cur)).empty()) { + auto it = folder.dot_ccls.find(cur); + if (it != folder.dot_ccls.end()) + return it->second; + std::string normalized = NormalizePath(cur); + // Break if outside of the project root. + if (normalized.size() <= root.size() || + normalized.compare(0, root.size(), root) != 0) + break; + } + return folder.dot_ccls[root]; + }; + + GetFilesInFolder(root, true /*recursive*/, true /*add_folder_to_path*/, + [&folder, &files, &Seen](const std::string &path) { std::pair lang = lookupExtension(path); if (lang.first != LanguageId::Unknown && !lang.second) { - files.push_back(path); + if (!Seen.count(path)) + files.push_back(path); } else if (sys::path::filename(path) == ".ccls") { std::vector args = ReadCompilerArgumentsFromFile(path); - folder_args.emplace(sys::path::parent_path(path), args); + folder.dot_ccls.emplace(sys::path::parent_path(path), + args); std::string l; for (size_t i = 0; i < args.size(); i++) { if (i) @@ -244,71 +266,72 @@ std::vector LoadFromDirectoryListing(ProjectConfig *config) { } }); - auto GetCompilerArgumentForFile = [&root, - &folder_args](std::string cur) { - while (!(cur = sys::path::parent_path(cur)).empty()) { - auto it = folder_args.find(cur); - if (it != folder_args.end()) - return it->second; - std::string normalized = NormalizePath(cur); - // Break if outside of the project root. - if (normalized.size() <= root.size() || - normalized.compare(0, root.size(), root) != 0) - break; + // If the first line of .ccls is %compile_commands.json, append extra flags. + for (auto &e : folder.entries) + if (const auto &args = GetDotCcls(e.filename); AppendToCDB(args)) { + if (args.size()) + e.args.insert(e.args.end(), args.begin() + 1, args.end()); + proc.Process(e); } - return folder_args[root]; - }; - - ProjectProcessor proc(config); - for (const std::string &file : files) { - Project::Entry e; - e.root = config->root; - e.directory = config->root; - e.filename = file; - e.args = GetCompilerArgumentForFile(file); - if (e.args.empty()) - e.args.push_back("%clang"); - e.args.push_back(Intern(e.filename)); - proc.Process(e); - result.push_back(e); - } + // Set flags for files not in compile_commands.json + for (const std::string &file : files) + if (const auto &args = GetDotCcls(file); !AppendToCDB(args)) { + Project::Entry e; + e.root = e.directory = root; + e.filename = file; + if (args.empty()) { + e.args = GetFallback(e.filename); + } else { + e.args = args; + e.args.push_back(Intern(e.filename)); + } + proc.Process(e); + folder.entries.push_back(e); + } +} - return result; +// Computes a score based on how well |a| and |b| match. This is used for +// argument guessing. +int ComputeGuessScore(std::string_view a, std::string_view b) { + // Increase score based on common prefix and suffix. Prefixes are prioritized. + if (a.size() > b.size()) + std::swap(a, b); + size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); + size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); + int score = 10 * i + j; + if (i + j < a.size()) + score -= 100 * (std::count(a.begin() + i, a.end() - j, '/') + + std::count(b.begin() + i, b.end() - j, '/')); + return score; } -std::vector -LoadEntriesFromDirectory(ProjectConfig *project, - const std::string &opt_compdb_dir) { - // If there is a .ccls file always load using directory listing. - SmallString<256> Path, CclsPath; - sys::path::append(CclsPath, project->root, ".ccls"); - if (sys::fs::exists(CclsPath)) - return LoadFromDirectoryListing(project); - - // If |compilationDatabaseCommand| is specified, execute it to get the compdb. - std::string comp_db_dir; +} // namespace + +void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { + SmallString<256> Path, CDBDir; + folder.entries.clear(); if (g_config->compilationDatabaseCommand.empty()) { - project->mode = ProjectMode::CompileCommandsJson; - // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = opt_compdb_dir.empty() ? project->root : opt_compdb_dir; - sys::path::append(Path, comp_db_dir, "compile_commands.json"); + CDBDir = root; + if (g_config->compilationDatabaseDirectory.size()) + sys::path::append(CDBDir, g_config->compilationDatabaseDirectory); + sys::path::append(Path, CDBDir, "compile_commands.json"); } else { - project->mode = ProjectMode::ExternalCommand; + // If `compilationDatabaseCommand` is specified, execute it to get the + // compdb. #ifdef _WIN32 // TODO #else char tmpdir[] = "/tmp/ccls-compdb-XXXXXX"; if (!mkdtemp(tmpdir)) - return {}; - comp_db_dir = tmpdir; - sys::path::append(Path, comp_db_dir, "compile_commands.json"); + return; + CDBDir = tmpdir; + sys::path::append(Path, CDBDir, "compile_commands.json"); rapidjson::StringBuffer input; rapidjson::Writer writer(input); JsonWriter json_writer(&writer); Reflect(json_writer, *g_config); std::string contents = GetExternalCommandOutput( - std::vector{g_config->compilationDatabaseCommand, - project->root}, + std::vector{g_config->compilationDatabaseCommand, root}, input.GetString()); FILE *fout = fopen(Path.c_str(), "wb"); fwrite(contents.c_str(), contents.size(), 1, fout); @@ -318,99 +341,81 @@ LoadEntriesFromDirectory(ProjectConfig *project, std::string err_msg; std::unique_ptr CDB = - tooling::CompilationDatabase::loadFromDirectory(comp_db_dir, err_msg); + tooling::CompilationDatabase::loadFromDirectory(CDBDir, err_msg); if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 // TODO #else unlink(Path.c_str()); - rmdir(comp_db_dir.c_str()); + rmdir(CDBDir.c_str()); #endif } - if (!CDB) { - LOG_S(WARNING) << "no .ccls or compile_commands.json . Consider adding one"; - return LoadFromDirectoryListing(project); - } - - LOG_S(INFO) << "loaded " << Path.c_str(); + ProjectProcessor proc(folder); StringSet<> Seen; std::vector result; - ProjectProcessor proc(project); - for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { - static bool once; - Project::Entry entry; - entry.root = project->root; - DoPathMapping(entry.root); - entry.directory = NormalizePath(Cmd.Directory); - DoPathMapping(entry.directory); - entry.filename = - NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); - DoPathMapping(entry.filename); - std::vector args = std::move(Cmd.CommandLine); - entry.args.reserve(args.size()); - for (std::string &arg : args) { - DoPathMapping(arg); - entry.args.push_back(Intern(arg)); - } + if (CDB) { + LOG_S(INFO) << "loaded " << Path.c_str(); + for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { + static bool once; + Project::Entry entry; + entry.root = root; + DoPathMapping(entry.root); + entry.directory = NormalizePath(Cmd.Directory); + DoPathMapping(entry.directory); + entry.filename = + NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); + DoPathMapping(entry.filename); + std::vector args = std::move(Cmd.CommandLine); + entry.args.reserve(args.size()); + for (std::string &arg : args) { + DoPathMapping(arg); + if (!proc.excludeArgs.count(arg)) + entry.args.push_back(Intern(arg)); + } + entry.compdb_size = entry.args.size(); + + // Work around relative --sysroot= as it isn't affected by + // -working-directory=. chdir is thread hostile but this function runs + // before indexers do actual work and it works when there is only one + // workspace folder. + if (!once) { + once = true; + llvm::vfs::getRealFileSystem()->setCurrentWorkingDirectory( + entry.directory); + } + proc.GetSearchDirs(entry); - // Work around relative --sysroot= as it isn't affected by - // -working-directory=. chdir is thread hostile but this function runs - // before indexers do actual work and it works when there is only one - // workspace folder. - if (!once) { - once = true; - llvm::vfs::getRealFileSystem()->setCurrentWorkingDirectory( - entry.directory); + if (Seen.insert(entry.filename).second) + folder.entries.push_back(entry); } - proc.Process(entry); - - if (Seen.insert(entry.filename).second) - result.push_back(entry); } - return result; -} -// Computes a score based on how well |a| and |b| match. This is used for -// argument guessing. -int ComputeGuessScore(std::string_view a, std::string_view b) { - // Increase score based on common prefix and suffix. Prefixes are prioritized. - if (a.size() > b.size()) - std::swap(a, b); - size_t i = std::mismatch(a.begin(), a.end(), b.begin()).first - a.begin(); - size_t j = std::mismatch(a.rbegin(), a.rend(), b.rbegin()).first - a.rbegin(); - int score = 10 * i + j; - if (i + j < b.size()) - score -= 100 * (std::count(a.begin() + i, a.end() - j, '/') + - std::count(b.begin() + i, b.end() - j, '/')); - return score; + // Use directory listing if .ccls exists or compile_commands.json does not + // exist. + Path.clear(); + sys::path::append(Path, root, ".ccls"); + if (sys::fs::exists(Path)) + LoadDirectoryListing(proc, root, Seen); + std::vector extra_args; + for (const std::string &arg : g_config->clang.extraArgs) + extra_args.push_back(Intern(arg)); + for (auto &e : folder.entries) { + e.args.insert(e.args.end(), extra_args.begin(), extra_args.end()); + e.args.push_back(Intern("-working-directory=" + e.directory)); + } } -} // namespace - void Project::Load(const std::string &root) { assert(root.back() == '/'); - ProjectConfig project; - project.root = root; + std::lock_guard lock(mtx); Folder &folder = root2folder[root]; - folder.entries = LoadEntriesFromDirectory( - &project, g_config->compilationDatabaseDirectory); - folder.quote_search_list.assign(project.quote_dirs.begin(), - project.quote_dirs.end()); - folder.angle_search_list.assign(project.angle_dirs.begin(), - project.angle_dirs.end()); - for (std::string &path : folder.angle_search_list) { - EnsureEndsInSlash(path); - LOG_S(INFO) << "angle search: " << path; - } - for (std::string &path : folder.quote_search_list) { - EnsureEndsInSlash(path); - LOG_S(INFO) << "quote search: " << path; - } + LoadDirectory(root, folder); + for (auto &[path, kind] : folder.search_dir2kind) + LOG_S(INFO) << "search directory: " << path << ' ' << " \"< "[kind]; // Setup project entries. - std::lock_guard lock(mutex_); folder.path2entry_index.reserve(folder.entries.size()); for (size_t i = 0; i < folder.entries.size(); ++i) { folder.entries[i].id = i; @@ -420,7 +425,9 @@ void Project::Load(const std::string &root) { Project::Entry Project::FindEntry(const std::string &path, bool can_be_inferred) { - std::lock_guard lock(mutex_); + Project::Folder *best_folder = nullptr; + const Entry *best = nullptr; + std::lock_guard lock(mtx); for (auto &[root, folder] : root2folder) { auto it = folder.path2entry_index.find(path); if (it != folder.path2entry_index.end()) { @@ -430,46 +437,80 @@ Project::Entry Project::FindEntry(const std::string &path, } } - Project::Entry result; - const Entry *best_entry = nullptr; - int best_score = INT_MIN; - for (auto &[root, folder] : root2folder) { - for (const Entry &entry : folder.entries) { - int score = ComputeGuessScore(path, entry.filename); - if (score > best_score) { - best_score = score; - best_entry = &entry; - } - } + std::string dir; + const std::vector *extra = nullptr; + Project::Entry ret; + for (auto &[root, folder] : root2folder) if (StringRef(path).startswith(root)) - result.root = root; + for (auto &[dir1, args] : folder.dot_ccls) + if (StringRef(path).startswith(dir1)) { + if (AppendToCDB(args)) { + dir = dir1; + extra = &args; + goto out; + } + ret.root = ret.directory = root; + ret.filename = path; + if (args.empty()) { + ret.args = GetFallback(path); + } else { + ret.args = args; + ret.args.push_back(Intern(path)); + } + ProjectProcessor(folder).Process(ret); + for (const std::string &arg : g_config->clang.extraArgs) + ret.args.push_back(Intern(arg)); + ret.args.push_back(Intern("-working-directory=" + ret.directory)); + return ret; + } +out: + + if (!best) { + int best_score = INT_MIN; + for (auto &[root, folder] : root2folder) { + if (dir.size() && !StringRef(path).startswith(dir)) + continue; + for (const Entry &e : folder.entries) + if (e.compdb_size) { + int score = ComputeGuessScore(path, e.filename); + if (score > best_score) { + best_score = score; + best = &e; + best_folder = &folder; + } + } + } } - if (result.root.empty()) - result.root = g_config->fallbackFolder; - - result.is_inferred = true; - result.filename = path; - if (!best_entry) { - result.args.push_back("%clang"); - result.args.push_back(Intern(path)); - } else { - result.args = best_entry->args; - // |best_entry| probably has its own path in the arguments. We need to remap - // that path to the new filename. - std::string best_entry_base_name = - sys::path::filename(best_entry->filename); - for (const char *&arg : result.args) { + ret.is_inferred = true; + ret.filename = path; + if (!best) { + if (ret.root.empty()) + ret.root = g_config->fallbackFolder; + ret.directory = ret.root; + ret.args = GetFallback(path); + } else { + ret.root = best->root; + ret.directory = best->directory; + ret.args = best->args; + std::string base_name = sys::path::filename(best->filename); + for (const char *&arg : ret.args) { try { - if (arg == best_entry->filename || - sys::path::filename(arg) == best_entry_base_name) + if (arg == best->filename || sys::path::filename(arg) == base_name) arg = Intern(path); } catch (...) { } } + ret.args.resize(best->compdb_size); + if (extra && extra->size()) + ret.args.insert(ret.args.end(), extra->begin() + 1, extra->end()); + ProjectProcessor(*best_folder).Process(ret); + for (const std::string &arg : g_config->clang.extraArgs) + ret.args.push_back(Intern(arg)); + ret.args.push_back(Intern("-working-directory=" + ret.directory)); } - return result; + return ret; } void Project::Index(WorkingFiles *wfiles, RequestId id) { @@ -477,7 +518,7 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { GroupMatch match(gi.whitelist, gi.blacklist), match_i(gi.initialWhitelist, gi.initialBlacklist); { - std::lock_guard lock(mutex_); + std::lock_guard lock(mtx); for (auto &[root, folder] : root2folder) { int i = 0; for (const Project::Entry &entry : folder.entries) { diff --git a/src/project.hh b/src/project.hh index a95951225..dca18a5cb 100644 --- a/src/project.hh +++ b/src/project.hh @@ -37,20 +37,20 @@ struct Project { std::vector args; // If true, this entry is inferred and was not read from disk. bool is_inferred = false; + // 0 unless coming from a compile_commands.json entry. + int compdb_size = 0; int id = -1; }; struct Folder { std::string name; - // Include directories for <> headers - std::vector angle_search_list; - // Include directories for "" headers - std::vector quote_search_list; + std::unordered_map search_dir2kind; std::vector entries; std::unordered_map path2entry_index; + std::unordered_map> dot_ccls; }; - std::mutex mutex_; + std::mutex mtx; std::unordered_map root2folder; // Loads a project for the given |directory|. @@ -63,7 +63,8 @@ struct Project { // will affect flags in their subtrees (relative paths are relative to the // project root, not subdirectories). For compile_commands.json, its entries // are indexed. - void Load(const std::string &root_directory); + void Load(const std::string &root); + void LoadDirectory(const std::string &root, Folder &folder); // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure. From f2df43055f95f7c487e75708fac755b955a61056 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Dec 2018 23:52:24 -0800 Subject: [PATCH 323/378] completion: ignore CXXDeductionGuide Fix #173 --- src/messages/textDocument_completion.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 318401936..a29d895a8 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -392,8 +392,15 @@ class CompletionConsumer : public CodeCompleteConsumer { R.Availability == CXAvailability_NotAvailable) continue; if (R.Declaration) { - if (R.Declaration->getKind() == Decl::CXXDestructor) + Decl::Kind K = R.Declaration->getKind(); + if (K == Decl::CXXDestructor) continue; + if (K == Decl::FunctionTemplate) { + // Ignore CXXDeductionGuide which has empty TypedText. + auto *FD = cast(R.Declaration); + if (FD->getTemplatedDecl()->getKind() == Decl::CXXDeductionGuide) + continue; + } if (auto *RD = dyn_cast(R.Declaration)) if (RD->isInjectedClassName()) continue; From 828c21c8d7931441c3e83462e9c965bab006482a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Dec 2018 11:30:31 -0800 Subject: [PATCH 324/378] Make cacheDirectory related to project root; delete Timer --- src/messages/initialize.cc | 5 +++-- src/pipeline.cc | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 0aa0488c9..10db52085 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -282,8 +282,9 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { if (g_config->cacheDirectory.size()) { SmallString<256> Path(g_config->cacheDirectory); - sys::fs::make_absolute(Path); - g_config->cacheDirectory = Path.str(); + sys::fs::make_absolute(project_path, Path); + // Use upper case for the Driver letter on Windows. + g_config->cacheDirectory = NormalizePath(Path.str()); EnsureEndsInSlash(g_config->cacheDirectory); } } diff --git a/src/pipeline.cc b/src/pipeline.cc index 829fe796f..f298595ac 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -31,7 +31,6 @@ limitations under the License. #include #include -#include using namespace llvm; #include @@ -435,10 +434,7 @@ void Main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) { return; } - static Timer timer("apply", "apply index"); - timer.startTimer(); db->ApplyIndexUpdate(update); - timer.stopTimer(); // Update indexed content, skipped ranges, and semantic highlighting. if (update->files_def_update) { From cbd36aeedb5f1ac0f3ec9900e12490120ad86411 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Dec 2018 20:53:50 -0800 Subject: [PATCH 325/378] Handle file deletion and register workspace/didChangeWatchedFiles * In the "initialized" callback, send client/registerCapability with DidChangeWatchedFilesRegistrationOptions * In workspace/didChangeWatchedFiles callback, call pipeline::Index * In pipeline::Index, add a `deleted` status --- src/indexer.cc | 8 +-- src/indexer.hh | 4 +- src/message_handler.cc | 1 + src/message_handler.hh | 1 + src/messages/initialize.cc | 29 ++++++++ src/messages/textDocument_did.cc | 6 +- src/messages/workspace.cc | 24 +++++-- src/pipeline.cc | 113 +++++++++++++++++++------------ src/pipeline.hh | 10 ++- src/project.cc | 25 ++++--- src/query.cc | 3 +- src/sema_manager.cc | 11 ++- src/serializer.cc | 6 +- 13 files changed, 160 insertions(+), 81 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 584dd20ae..83c8cbc20 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -82,8 +82,7 @@ struct IndexParam { if (!vfs.Stamp(path, it->second.mtime, 1)) return; - it->second.db = std::make_unique(File.getUniqueID(), path, - it->second.content); + it->second.db = std::make_unique(path, it->second.content); } } @@ -1186,9 +1185,8 @@ class IndexFrontendAction : public ASTFrontendAction { const int IndexFile::kMajorVersion = 19; const int IndexFile::kMinorVersion = 1; -IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, - const std::string &contents) - : UniqueID(UniqueID), path(path), file_contents(contents) {} +IndexFile::IndexFile(const std::string &path, const std::string &contents) + : path(path), file_contents(contents) {} IndexFunc &IndexFile::ToFunc(Usr usr) { auto [it, inserted] = usr2func.try_emplace(usr); diff --git a/src/indexer.hh b/src/indexer.hh index 885985102..191f80746 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -290,7 +290,6 @@ struct IndexFile { // files accepted by newer ccls. static const int kMinorVersion; - llvm::sys::fs::UniqueID UniqueID; std::string path; std::vector args; // This is unfortunately time_t as used by clang::FileEntry @@ -320,8 +319,7 @@ struct IndexFile { // File contents at the time of index. Not serialized. std::string file_contents; - IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path, - const std::string &contents); + IndexFile(const std::string &path, const std::string &contents); IndexFunc &ToFunc(Usr usr); IndexType &ToType(Usr usr); diff --git a/src/message_handler.cc b/src/message_handler.cc index 99e8197cf..b88f777a9 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -181,6 +181,7 @@ MessageHandler::MessageHandler() { Bind("$ccls/vars", &MessageHandler::ccls_vars); Bind("exit", &MessageHandler::exit); Bind("initialize", &MessageHandler::initialize); + Bind("initialized", &MessageHandler::initialized); Bind("shutdown", &MessageHandler::shutdown); Bind("textDocument/codeAction", &MessageHandler::textDocument_codeAction); Bind("textDocument/codeLens", &MessageHandler::textDocument_codeLens); diff --git a/src/message_handler.hh b/src/message_handler.hh index 7063fe1ca..b0a3747c1 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -250,6 +250,7 @@ private: void ccls_vars(JsonReader &, ReplyOnce &); void exit(EmptyParam &); void initialize(JsonReader &, ReplyOnce &); + void initialized(EmptyParam &); void shutdown(EmptyParam &, ReplyOnce &); void textDocument_codeAction(CodeActionParam &, ReplyOnce &); void textDocument_codeLens(TextDocumentParam &, ReplyOnce &); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 10db52085..bbafa9d25 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -42,6 +42,8 @@ namespace { enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 }; REFLECT_UNDERLYING(TextDocumentSyncKind) +bool didChangeWatchedFiles; + struct ServerCap { struct SaveOptions { bool includeText = false; @@ -239,6 +241,24 @@ struct InitializeResult { }; REFLECT_STRUCT(InitializeResult, capabilities); +struct FileSystemWatcher { + std::string globPattern = "**/*"; +}; +struct DidChangeWatchedFilesRegistration { + std::string id = "didChangeWatchedFiles"; + std::string method = "workspace/didChangeWatchedFiles"; + struct Option { + std::vector watchers = {{}}; + } registerOptions; +}; +struct RegistrationParam { + std::vector registrations = {{}}; +}; +REFLECT_STRUCT(FileSystemWatcher, globPattern); +REFLECT_STRUCT(DidChangeWatchedFilesRegistration::Option, watchers); +REFLECT_STRUCT(DidChangeWatchedFilesRegistration, id, method, registerOptions); +REFLECT_STRUCT(RegistrationParam, registrations); + void *Indexer(void *arg_) { MessageHandler *h; int idx; @@ -298,6 +318,8 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { capabilities.textDocument.definition.linkSupport; g_config->client.snippetSupport &= capabilities.textDocument.completion.completionItem.snippetSupport; + didChangeWatchedFiles = + capabilities.workspace.didChangeWatchedFiles.dynamicRegistration; // Ensure there is a resource directory. if (g_config->clang.resourceDir.empty()) @@ -370,6 +392,13 @@ void StandaloneInitialize(MessageHandler &handler, const std::string &root) { Initialize(&handler, param, reply); } +void MessageHandler::initialized(EmptyParam &) { + if (didChangeWatchedFiles) { + RegistrationParam param; + pipeline::Request("client/registerCapability", param); + } +} + void MessageHandler::shutdown(EmptyParam &, ReplyOnce &reply) { reply(JsonNull{}); } diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 2dc916290..b00b3c7dc 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -25,7 +25,7 @@ void MessageHandler::textDocument_didChange(TextDocumentDidChangeParam ¶m) { std::string path = param.textDocument.uri.GetPath(); wfiles->OnChange(param); if (g_config->index.onChange) - pipeline::Index(path, {}, IndexMode::OnChange); + pipeline::Index(path, {}, IndexMode::OnChange, true); manager->OnView(path); if (g_config->diagnostics.onChange >= 0) manager->ScheduleDiag(path, g_config->diagnostics.onChange); @@ -56,14 +56,14 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { std::pair lang = lookupExtension(path); if ((lang.first != LanguageId::Unknown && !lang.second) || !pipeline::pending_index_requests) - pipeline::Index(path, {}, IndexMode::Normal); + pipeline::Index(path, {}, IndexMode::Normal, false); manager->OnView(path); } void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) { const std::string &path = param.textDocument.uri.GetPath(); - pipeline::Index(path, {}, IndexMode::Normal); + pipeline::Index(path, {}, IndexMode::Normal, false); manager->OnSave(path); } } // namespace ccls diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 5b0499586..5435d98f6 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -23,11 +23,13 @@ limitations under the License. #include #include +#include #include #include #include #include +using namespace llvm; namespace ccls { REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); @@ -44,20 +46,30 @@ void MessageHandler::workspace_didChangeWatchedFiles( DidChangeWatchedFilesParam ¶m) { for (auto &event : param.changes) { std::string path = event.uri.GetPath(); + if ((g_config->cacheDirectory.size() && + StringRef(path).startswith(g_config->cacheDirectory)) || + lookupExtension(path).first == LanguageId::Unknown) + return; + for (std::string cur = path; cur.size(); cur = sys::path::parent_path(cur)) + if (cur[0] == '.') + return; + IndexMode mode = wfiles->GetFile(path) ? IndexMode::Normal : IndexMode::NonInteractive; switch (event.type) { case FileChangeType::Created: case FileChangeType::Changed: { - pipeline::Index(path, {}, mode); - if (mode == IndexMode::Normal) - manager->OnSave(path); - else - manager->OnClose(path); + pipeline::Index(path, {}, mode, true); + if (event.type == FileChangeType::Changed) { + if (mode == IndexMode::Normal) + manager->OnSave(path); + else + manager->OnClose(path); + } break; } case FileChangeType::Deleted: - pipeline::Index(path, {}, mode); + pipeline::Index(path, {}, mode, false); manager->OnClose(path); break; } diff --git a/src/pipeline.cc b/src/pipeline.cc index f298595ac..8785619fe 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -77,16 +77,16 @@ void StandaloneInitialize(MessageHandler &, const std::string &root); namespace pipeline { std::atomic quit; -std::atomic loaded_ts = ATOMIC_VAR_INIT(0), - pending_index_requests = ATOMIC_VAR_INIT(0); +std::atomic loaded_ts{0}, pending_index_requests{0}, request_id{0}; int64_t tick = 0; namespace { -struct Index_Request { +struct IndexRequest { std::string path; std::vector args; IndexMode mode; + bool must_exist = false; RequestId id; int64_t ts = tick++; }; @@ -99,7 +99,7 @@ MultiQueueWaiter *main_waiter; MultiQueueWaiter *indexer_waiter; MultiQueueWaiter *stdout_waiter; ThreadedQueue *on_request; -ThreadedQueue *index_request; +ThreadedQueue *index_request; ThreadedQueue *on_indexed; ThreadedQueue *for_stdout; @@ -184,7 +184,7 @@ std::mutex &GetFileMutex(const std::string &path) { bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, Project *project, VFS *vfs, const GroupMatch &matcher) { - std::optional opt_request = index_request->TryPopFront(); + std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; auto &request = *opt_request; @@ -206,23 +206,33 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, return false; } - Project::Entry entry = project->FindEntry(request.path, true); + // must_exist is currently unused. + Project::Entry entry = project->FindEntry(request.path, false); + if (request.must_exist && entry.filename.empty()) + return true; if (request.args.size()) entry.args = request.args; std::string path_to_index = entry.filename; std::unique_ptr prev; + bool deleted = false; + int reparse = 0; std::optional write_time = LastWriteTime(path_to_index); - if (!write_time) - return true; - int reparse = vfs->Stamp(path_to_index, *write_time, 0); - if (request.path != path_to_index) { - std::optional mtime1 = LastWriteTime(request.path); - if (!mtime1) - return true; - if (vfs->Stamp(request.path, *mtime1, 0)) - reparse = 2; + if (!write_time) { + deleted = true; + } else { + reparse = vfs->Stamp(path_to_index, *write_time, 0); + if (request.path != path_to_index) { + std::optional mtime1 = LastWriteTime(request.path); + if (!mtime1) + deleted = true; + else if (vfs->Stamp(request.path, *mtime1, 0)) + reparse = 2; + } } + if (deleted) + reparse = 2; + if (g_config->index.onChange) { reparse = 2; std::lock_guard lock(vfs->mutex); @@ -306,27 +316,34 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, for (auto &arg : entry.args) (line += ' ') += arg; } - LOG_S(INFO) << "parse " << path_to_index << line; + LOG_S(INFO) << (deleted ? "delete " : "parse ") << path_to_index << line; } - std::vector> remapped; - if (g_config->index.onChange) { - std::string content = wfiles->GetContent(path_to_index); - if (content.size()) - remapped.emplace_back(path_to_index, content); - } - bool ok; - auto indexes = idx::Index(completion, wfiles, vfs, entry.directory, - path_to_index, entry.args, remapped, ok); - - if (!ok) { - if (request.id.Valid()) { - ResponseError err; - err.code = ErrorCode::InternalError; - err.message = "failed to index " + path_to_index; - pipeline::ReplyError(request.id, err); + std::vector> indexes; + if (deleted) { + indexes.push_back(std::make_unique(request.path, "")); + if (request.path != path_to_index) + indexes.push_back(std::make_unique(path_to_index, "")); + } else { + std::vector> remapped; + if (g_config->index.onChange) { + std::string content = wfiles->GetContent(path_to_index); + if (content.size()) + remapped.emplace_back(path_to_index, content); + } + bool ok; + indexes = idx::Index(completion, wfiles, vfs, entry.directory, + path_to_index, entry.args, remapped, ok); + + if (!ok) { + if (request.id.Valid()) { + ResponseError err; + err.code = ErrorCode::InternalError; + err.message = "failed to index " + path_to_index; + pipeline::ReplyError(request.id, err); + } + return true; } - return true; } for (std::unique_ptr &curr : indexes) { @@ -336,8 +353,9 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, continue; } - LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev - << ")"; + if (!deleted) + LOG_IF_S(INFO, loud) << "store index for " << path + << " (delta: " << !!prev << ")"; { std::lock_guard lock(GetFileMutex(path)); if (vfs->Loaded(path)) @@ -351,9 +369,14 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, std::string().swap(it.first->second.index.file_contents); } else { std::string cache_path = GetCachePath(path); - WriteToFile(cache_path, curr->file_contents); - WriteToFile(AppendSerializationFormat(cache_path), - Serialize(g_config->cacheFormat, *curr)); + if (deleted) { + (void)sys::fs::remove(cache_path); + (void)sys::fs::remove(AppendSerializationFormat(cache_path)); + } else { + WriteToFile(cache_path, curr->file_contents); + WriteToFile(AppendSerializationFormat(cache_path), + Serialize(g_config->cacheFormat, *curr)); + } } on_indexed->PushBack(IndexUpdate::CreateDelta(prev.get(), curr.get()), request.mode != IndexMode::NonInteractive); @@ -404,7 +427,7 @@ void Init() { on_indexed = new ThreadedQueue(main_waiter); indexer_waiter = new MultiQueueWaiter; - index_request = new ThreadedQueue(indexer_waiter); + index_request = new ThreadedQueue(indexer_waiter); stdout_waiter = new MultiQueueWaiter; for_stdout = new ThreadedQueue(stdout_waiter); @@ -637,9 +660,10 @@ void Standalone(const std::string &root) { } void Index(const std::string &path, const std::vector &args, - IndexMode mode, RequestId id) { + IndexMode mode, bool must_exist, RequestId id) { pending_index_requests++; - index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive); + index_request->PushBack({path, args, mode, must_exist, id}, + mode != IndexMode::NonInteractive); } std::optional LoadIndexedContent(const std::string &path) { @@ -653,7 +677,8 @@ std::optional LoadIndexedContent(const std::string &path) { return ReadContent(GetCachePath(path)); } -void Notify(const char *method, const std::function &fn) { +void NotifyOrRequest(const char *method, bool request, + const std::function &fn) { rapidjson::StringBuffer output; rapidjson::Writer w(output); w.StartObject(); @@ -661,6 +686,10 @@ void Notify(const char *method, const std::function &fn) { w.String("2.0"); w.Key("method"); w.String(method); + if (request) { + w.Key("id"); + w.Int64(request_id.fetch_add(1, std::memory_order_relaxed)); + } w.Key("params"); JsonWriter writer(&w); fn(writer); diff --git a/src/pipeline.hh b/src/pipeline.hh index da6b44bc3..c61c6dc20 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -51,13 +51,17 @@ void MainLoop(); void Standalone(const std::string &root); void Index(const std::string &path, const std::vector &args, - IndexMode mode, RequestId id = {}); + IndexMode mode, bool must_exist, RequestId id = {}); std::optional LoadIndexedContent(const std::string& path); -void Notify(const char *method, const std::function &fn); +void NotifyOrRequest(const char *method, bool request, + const std::function &fn); template void Notify(const char *method, T &result) { - Notify(method, [&](JsonWriter &w) { Reflect(w, result); }); + NotifyOrRequest(method, false, [&](JsonWriter &w) { Reflect(w, result); }); +} +template void Request(const char *method, T &result) { + NotifyOrRequest(method, true, [&](JsonWriter &w) { Reflect(w, result); }); } void Reply(RequestId id, const std::function &fn); diff --git a/src/project.cc b/src/project.cc index 050e645c2..3df96feb9 100644 --- a/src/project.cc +++ b/src/project.cc @@ -424,7 +424,7 @@ void Project::Load(const std::string &root) { } Project::Entry Project::FindEntry(const std::string &path, - bool can_be_inferred) { + bool must_exist) { Project::Folder *best_folder = nullptr; const Entry *best = nullptr; std::lock_guard lock(mtx); @@ -432,11 +432,12 @@ Project::Entry Project::FindEntry(const std::string &path, auto it = folder.path2entry_index.find(path); if (it != folder.path2entry_index.end()) { Project::Entry &entry = folder.entries[it->second]; - if (can_be_inferred || entry.filename == path) + if (!must_exist || entry.filename == path) return entry; } } + bool exists = false; std::string dir; const std::vector *extra = nullptr; Project::Entry ret; @@ -444,11 +445,12 @@ Project::Entry Project::FindEntry(const std::string &path, if (StringRef(path).startswith(root)) for (auto &[dir1, args] : folder.dot_ccls) if (StringRef(path).startswith(dir1)) { - if (AppendToCDB(args)) { - dir = dir1; - extra = &args; + dir = dir1; + extra = &args; + if (AppendToCDB(args)) goto out; - } + exists = true; + ret.root = ret.directory = root; ret.filename = path; if (args.empty()) { @@ -464,6 +466,8 @@ Project::Entry Project::FindEntry(const std::string &path, return ret; } out: + if (must_exist && !exists) + return ret; if (!best) { int best_score = INT_MIN; @@ -526,9 +530,10 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { if (match.Matches(entry.filename, &reason) && match_i.Matches(entry.filename, &reason)) { bool interactive = wfiles->GetFile(entry.filename) != nullptr; - pipeline::Index( - entry.filename, entry.args, - interactive ? IndexMode::Normal : IndexMode::NonInteractive, id); + pipeline::Index(entry.filename, entry.args, + interactive ? IndexMode::Normal + : IndexMode::NonInteractive, + false, id); } else { LOG_V(1) << "[" << i << "/" << folder.entries.size() << "]: " << reason << "; skip " << entry.filename; @@ -541,6 +546,6 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { pipeline::loaded_ts = pipeline::tick; // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - pipeline::Index("", {}, IndexMode::NonInteractive); + pipeline::Index("", {}, IndexMode::NonInteractive, false); } } // namespace ccls diff --git a/src/query.cc b/src/query.cc index aa305a3ea..6a2d1b5bc 100644 --- a/src/query.cc +++ b/src/query.cc @@ -83,8 +83,7 @@ bool TryReplaceDef(llvm::SmallVectorImpl &def_list, Q &&def) { IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { IndexUpdate r; - static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path, - ""); + static IndexFile empty(current->path, ""); if (previous) r.prev_lid2path = std::move(previous->lid2path); else diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 3d969b364..89388ee01 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -302,7 +302,7 @@ class StoreDiags : public DiagnosticConsumer { std::unique_ptr BuildCompilerInstance( Session &session, std::unique_ptr CI, IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, - const PreambleData *preamble, const std::string &path, + const PreambleData *preamble, const std::string &main, std::unique_ptr &Buf) { if (preamble) { #if LLVM_VERSION_MAJOR >= 7 @@ -311,7 +311,7 @@ std::unique_ptr BuildCompilerInstance( preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get()); #endif } else { - CI->getPreprocessorOpts().addRemappedFile(path, Buf.get()); + CI->getPreprocessorOpts().addRemappedFile(main, Buf.get()); } auto Clang = std::make_unique(session.PCH); @@ -328,6 +328,11 @@ std::unique_ptr BuildCompilerInstance( Clang->createFileManager(); Clang->setSourceManager(new SourceManager(Clang->getDiagnostics(), Clang->getFileManager(), true)); + auto &IS = Clang->getFrontendOpts().Inputs; + if (IS.size()) { + assert(IS[0].isFile()); + IS[0] = FrontendInputFile(main, IS[0].getKind(), IS[0].isSystem()); + } return Clang; } @@ -702,7 +707,7 @@ SemaManager::EnsureSession(const std::string &path, bool *created) { std::shared_ptr session = sessions.Get(path); if (!session) { session = std::make_shared( - project_->FindEntry(path, false), wfiles, PCH); + project_->FindEntry(path, true), wfiles, PCH); std::string line; if (LOG_V_ENABLED(1)) { line = "\n "; diff --git a/src/serializer.cc b/src/serializer.cc index c754f83a9..0dec4710f 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -482,8 +482,7 @@ Deserialize(SerializeFormat format, const std::string &path, if (major != IndexFile::kMajorVersion || minor != IndexFile::kMinorVersion) throw std::invalid_argument("Invalid version"); - file = std::make_unique(sys::fs::UniqueID(0, 0), path, - file_content); + file = std::make_unique(path, file_content); ReflectFile(reader, *file); } catch (std::invalid_argument &e) { LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what(); @@ -506,8 +505,7 @@ Deserialize(SerializeFormat format, const std::string &path, if (reader.HasParseError()) return nullptr; - file = std::make_unique(sys::fs::UniqueID(0, 0), path, - file_content); + file = std::make_unique(path, file_content); JsonReader json_reader{&reader}; try { ReflectFile(json_reader, *file); From e8cacf1efa388b1c7bd2f3a66cb63e034538b5c5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Dec 2018 21:22:51 -0800 Subject: [PATCH 326/378] Adjust FrontendOpts.Inputs[0] for inferred files --- src/clang_tu.cc | 5 ++++- src/clang_tu.hh | 3 ++- src/indexer.cc | 53 ++++++++++++++------------------------------- src/pipeline.cc | 8 +++++-- src/project.cc | 21 +++++++++--------- src/project.hh | 2 +- src/sema_manager.cc | 8 +++---- 7 files changed, 43 insertions(+), 57 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 4092372bf..a2d982b42 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -93,7 +93,7 @@ Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang, } std::unique_ptr -BuildCompilerInvocation(std::vector args, +BuildCompilerInvocation(const std::string &main, std::vector args, IntrusiveRefCntPtr VFS) { std::string save = "-resource-dir=" + g_config->clang.resourceDir; args.push_back(save.c_str()); @@ -106,6 +106,9 @@ BuildCompilerInvocation(std::vector args, CI->getDiagnosticOpts().IgnoreWarnings = true; CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->SpellChecking = false; + auto &IS = CI->getFrontendOpts().Inputs; + if (IS.size()) + IS[0] = FrontendInputFile(main, IS[0].getKind(), IS[0].isSystem()); } return CI; } diff --git a/src/clang_tu.hh b/src/clang_tu.hh index 2bfa23659..05096c1e1 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -51,7 +51,8 @@ Range FromTokenRangeDefaulted(const clang::SourceManager &SM, Range range); std::unique_ptr -BuildCompilerInvocation(std::vector args, +BuildCompilerInvocation(const std::string &main, + std::vector args, llvm::IntrusiveRefCntPtr VFS); const char *ClangBuiltinTypeName(int); diff --git a/src/indexer.cc b/src/indexer.cc index 83c8cbc20..43969f234 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1230,14 +1230,15 @@ void Init() { std::vector> Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, - const std::string &opt_wdir, const std::string &file, + const std::string &opt_wdir, const std::string &main, const std::vector &args, const std::vector> &remapped, bool &ok) { ok = true; auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = llvm::vfs::getRealFileSystem(); - std::shared_ptr CI = BuildCompilerInvocation(args, FS); + std::shared_ptr CI = + BuildCompilerInvocation(main, args, FS); // e.g. .s if (!CI) return {}; @@ -1257,35 +1258,13 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, // HSOpts.UseBuiltinIncludes) // HSOpts.ResourceDir = g_config->clang.resourceDir; } - std::string buf = wfiles->GetContent(file); + std::string buf = wfiles->GetContent(main); std::vector> Bufs; - if (buf.size()) { - // If there is a completion session, reuse its preamble if exists. - bool done_remap = false; -#if 0 - std::shared_ptr session = - manager->TryGetSession(file, false, false); - if (session) - if (auto preamble = session->GetPreamble()) { - Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(buf)); - auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), Bufs.back().get(), 0); - if (preamble->Preamble.CanReuse(*CI, Bufs.back().get(), Bounds, - FS.get())) { - preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get()); - done_remap = true; - } - } -#endif + if (buf.size()) for (auto &[filename, content] : remapped) { - if (filename == file && done_remap) - continue; Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); - CI->getPreprocessorOpts().addRemappedFile( - filename == file ? CI->getFrontendOpts().Inputs[0].getFile() - : StringRef(filename), - Bufs.back().get()); + CI->getPreprocessorOpts().addRemappedFile(filename, Bufs.back().get()); } - } DiagnosticConsumer DC; auto Clang = std::make_unique(PCH); @@ -1314,20 +1293,20 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, { llvm::CrashRecoveryContext CRC; auto parse = [&]() { - if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) - return; - if (!Action->Execute()) - return; - Action->EndSourceFile(); - ok = true; - }; + if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) + return; + if (!Action->Execute()) + return; + Action->EndSourceFile(); + ok = true; + }; if (!CRC.RunSafely(parse)) { - LOG_S(ERROR) << "clang crashed for " << file; + LOG_S(ERROR) << "clang crashed for " << main; return {}; } } if (!ok) { - LOG_S(ERROR) << "failed to index " << file; + LOG_S(ERROR) << "failed to index " << main; return {}; } for (auto &Buf : Bufs) @@ -1338,7 +1317,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, if (!it.second.db) continue; std::unique_ptr &entry = it.second.db; - entry->import_file = file; + entry->import_file = main; entry->args = args; for (auto &[_, it] : entry->uid2lid_and_path) entry->lid2path.emplace_back(it.first, std::move(it.second)); diff --git a/src/pipeline.cc b/src/pipeline.cc index 8785619fe..cb8ccc4e4 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -29,6 +29,7 @@ limitations under the License. #include #include +#include #include #include using namespace llvm; @@ -122,9 +123,11 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, } } + // For inferred files, allow -o a a.cc -> -o b b.cc + std::string stem = sys::path::stem(path); bool changed = prev->args.size() != args.size(); for (size_t i = 0; !changed && i < args.size(); i++) - if (strcmp(prev->args[i], args[i])) + if (strcmp(prev->args[i], args[i]) && sys::path::stem(args[i]) != stem) changed = true; if (changed) LOG_S(INFO) << "args changed for " << path @@ -207,7 +210,8 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, } // must_exist is currently unused. - Project::Entry entry = project->FindEntry(request.path, false); + Project::Entry entry = + project->FindEntry(request.path, true, request.must_exist); if (request.must_exist && entry.filename.empty()) return true; if (request.args.size()) diff --git a/src/project.cc b/src/project.cc index 3df96feb9..c74265b6a 100644 --- a/src/project.cc +++ b/src/project.cc @@ -423,17 +423,24 @@ void Project::Load(const std::string &root) { } } -Project::Entry Project::FindEntry(const std::string &path, +Project::Entry Project::FindEntry(const std::string &path, bool can_redirect, bool must_exist) { Project::Folder *best_folder = nullptr; const Entry *best = nullptr; std::lock_guard lock(mtx); for (auto &[root, folder] : root2folder) { + // The entry may have different filename but it doesn't matter when building + // CompilerInvocation. The main filename is specified separately. auto it = folder.path2entry_index.find(path); if (it != folder.path2entry_index.end()) { Project::Entry &entry = folder.entries[it->second]; - if (!must_exist || entry.filename == path) + if (can_redirect || entry.filename == path) return entry; + if (entry.compdb_size) { + best_folder = &folder; + best = &entry; + } + break; } } @@ -483,7 +490,7 @@ Project::Entry Project::FindEntry(const std::string &path, best_folder = &folder; } } - } + } } ret.is_inferred = true; @@ -497,14 +504,6 @@ Project::Entry Project::FindEntry(const std::string &path, ret.root = best->root; ret.directory = best->directory; ret.args = best->args; - std::string base_name = sys::path::filename(best->filename); - for (const char *&arg : ret.args) { - try { - if (arg == best->filename || sys::path::filename(arg) == base_name) - arg = Intern(path); - } catch (...) { - } - } ret.args.resize(best->compdb_size); if (extra && extra->size()) ret.args.insert(ret.args.end(), extra->begin() + 1, extra->end()); diff --git a/src/project.hh b/src/project.hh index dca18a5cb..5e14aa8a0 100644 --- a/src/project.hh +++ b/src/project.hh @@ -68,7 +68,7 @@ struct Project { // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure. - Entry FindEntry(const std::string &path, bool can_be_inferred); + Entry FindEntry(const std::string &path, bool can_redirect, bool must_exist); // If the client has overridden the flags, or specified them for a file // that is not in the compilation_database.json make sure those changes diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 89388ee01..91fae5e34 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -420,7 +420,7 @@ void *PreambleMain(void *manager_) { IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); if (std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS)) + BuildCompilerInvocation(task.path, session->file.args, FS)) BuildPreamble(*session, *CI, FS, task, std::move(stat_cache)); if (task.from_diag) { @@ -460,7 +460,7 @@ void *CompletionMain(void *manager_) { IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS); + BuildCompilerInvocation(task->path, session->file.args, FS); if (!CI) continue; auto &FOpts = CI->getFrontendOpts(); @@ -562,7 +562,7 @@ void *DiagnosticMain(void *manager_) { } std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS); + BuildCompilerInvocation(task.path, session->file.args, FS); if (!CI) continue; // If main file is a header, add -Wno-unused-function @@ -707,7 +707,7 @@ SemaManager::EnsureSession(const std::string &path, bool *created) { std::shared_ptr session = sessions.Get(path); if (!session) { session = std::make_shared( - project_->FindEntry(path, true), wfiles, PCH); + project_->FindEntry(path, false, false), wfiles, PCH); std::string line; if (LOG_V_ENABLED(1)) { line = "\n "; From 9a529bd69176a87ece1b535b956dc037052b6ff4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 24 Dec 2018 22:20:00 -0800 Subject: [PATCH 327/378] Delay requests if the document has not not indexed (#176) This fixes a plethora of "not indexed" errors when the document has not been indexed. * Message handler throws NotIndexed if not overdue * The message is put into backlog and tagged with backlog_path * path2backlog[path] tracks backlog associated with document `path` * The backlog is cleared when the index is merged * backlog[0] is forced to run if it becomes overdue --- src/config.hh | 10 ++++- src/lsp.hh | 4 +- src/message_handler.cc | 38 ++++++++++++----- src/message_handler.hh | 12 +++++- src/messages/ccls_call.cc | 3 +- src/messages/ccls_inheritance.cc | 6 +-- src/messages/ccls_member.cc | 7 +--- src/messages/ccls_navigate.cc | 4 +- src/messages/ccls_vars.cc | 4 +- src/messages/initialize.cc | 2 +- src/messages/textDocument_code.cc | 17 +++----- src/messages/textDocument_completion.cc | 2 +- src/messages/textDocument_definition.cc | 21 +++------- src/messages/textDocument_document.cc | 15 ++----- src/messages/textDocument_foldingRange.cc | 7 +--- src/messages/textDocument_formatting.cc | 15 ++----- src/messages/textDocument_hover.cc | 7 +--- src/messages/textDocument_references.cc | 7 +--- src/messages/textDocument_rename.cc | 4 +- src/messages/textDocument_signatureHelp.cc | 5 +-- src/pipeline.cc | 48 ++++++++++++++++++++-- src/threaded_queue.hh | 9 ++++ 22 files changed, 142 insertions(+), 105 deletions(-) diff --git a/src/config.hh b/src/config.hh index 1fec1140c..4c7eabbb8 100644 --- a/src/config.hh +++ b/src/config.hh @@ -242,6 +242,12 @@ struct Config { std::vector whitelist; } index; + struct Request { + // If the document of a request has not been indexed, wait up to this many + // milleseconds before reporting error. + int64_t timeout = 5000; + } request; + struct Session { int maxNum = 10; } session; @@ -278,12 +284,14 @@ REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, initialWhitelist, multiVersion, multiVersionBlacklist, multiVersionWhitelist, onChange, threads, trackDependency, whitelist); +REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); REFLECT_STRUCT(Config::Xref, maxNum); REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat, clang, client, codeLens, completion, - diagnostics, highlight, index, session, workspaceSymbol, xref); + diagnostics, highlight, index, request, session, workspaceSymbol, + xref); extern Config *g_config; diff --git a/src/lsp.hh b/src/lsp.hh index c44dbdf52..8f8efda96 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -21,8 +21,8 @@ limitations under the License. #include +#include #include -#include namespace ccls { struct RequestId { @@ -43,6 +43,8 @@ struct InMessage { std::string method; std::unique_ptr message; std::unique_ptr document; + std::chrono::steady_clock::time_point deadline; + std::string backlog_path; }; enum class ErrorCode { diff --git a/src/message_handler.cc b/src/message_handler.cc index b88f777a9..a9878f81b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -109,11 +109,8 @@ struct ScanLineEvent { }; } // namespace -void ReplyOnce::NotReady(bool file) { - if (file) - Error(ErrorCode::InvalidRequest, "not opened"); - else - Error(ErrorCode::InternalError, "not indexed"); +void ReplyOnce::NotOpened(std::string_view path) { + Error(ErrorCode::InvalidRequest, std::string(path) + " is not opened"); } void ReplyOnce::ReplyLocationLink(std::vector &result) { @@ -215,13 +212,11 @@ MessageHandler::MessageHandler() { void MessageHandler::Run(InMessage &msg) { rapidjson::Document &doc = *msg.document; - rapidjson::Value param; + rapidjson::Value null; auto it = doc.FindMember("params"); - if (it != doc.MemberEnd()) - param = it->value; - JsonReader reader(¶m); + JsonReader reader(it != doc.MemberEnd() ? &it->value : &null); if (msg.id.Valid()) { - ReplyOnce reply{msg.id}; + ReplyOnce reply{*this, msg.id}; auto it = method2request.find(msg.method); if (it != method2request.end()) { try { @@ -230,6 +225,8 @@ void MessageHandler::Run(InMessage &msg) { reply.Error(ErrorCode::InvalidParams, "invalid params of " + msg.method + ": expected " + ex.what() + " for " + reader.GetPath()); + } catch (NotIndexed &) { + throw; } catch (...) { reply.Error(ErrorCode::InternalError, "failed to process " + msg.method); } @@ -249,7 +246,8 @@ void MessageHandler::Run(InMessage &msg) { } } -QueryFile *MessageHandler::FindFile(const std::string &path, int *out_file_id) { +QueryFile *MessageHandler::FindFile(const std::string &path, + int *out_file_id) { QueryFile *ret = nullptr; auto it = db->name2file_id.find(LowerPathIfInsensitive(path)); if (it != db->name2file_id.end()) { @@ -266,6 +264,24 @@ QueryFile *MessageHandler::FindFile(const std::string &path, int *out_file_id) { return ret; } +std::pair +MessageHandler::FindOrFail(const std::string &path, ReplyOnce &reply, + int *out_file_id) { + WorkingFile *wf = wfiles->GetFile(path); + if (!wf) { + reply.NotOpened(path); + return {nullptr, nullptr}; + } + QueryFile *file = FindFile(path, out_file_id); + if (!file) { + if (!overdue) + throw NotIndexed{path}; + reply.Error(ErrorCode::InvalidRequest, "not indexed"); + return {nullptr, nullptr}; + } + return {file, wf}; +} + void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) { CclsSetSkippedRanges params; params.uri = DocumentUri::FromPath(wfile->filename); diff --git a/src/message_handler.hh b/src/message_handler.hh index b0a3747c1..949fc2423 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -199,7 +199,13 @@ REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); REFLECT_STRUCT(ShowMessageParam, type, message); REFLECT_UNDERLYING_B(LanguageId); +struct NotIndexed { + std::string path; +}; +struct MessageHandler; + struct ReplyOnce { + MessageHandler &handler; RequestId id; template void operator()(Res &&result) const { if (id.Valid()) @@ -210,7 +216,7 @@ struct ReplyOnce { if (id.Valid()) pipeline::ReplyError(id, [&](JsonWriter &w) { Reflect(w, err); }); } - void NotReady(bool file); + void NotOpened(std::string_view path); void ReplyLocationLink(std::vector &result); }; @@ -225,10 +231,14 @@ struct MessageHandler { llvm::StringMap> method2notification; llvm::StringMap> method2request; + bool overdue = false; MessageHandler(); void Run(InMessage &msg); QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr); + std::pair FindOrFail(const std::string &path, + ReplyOnce &reply, + int *out_file_id = nullptr); private: void Bind(const char *method, void (MessageHandler::*handler)(JsonReader &)); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 5a0e6d8e2..a2a221d44 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -200,8 +200,7 @@ void MessageHandler::ccls_call(JsonReader &reader, ReplyOnce &reply) { Expand(this, &*result, param.callee, param.callType, param.qualified, param.levels); } else { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) return; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index b7520ddf7..a9c18b916 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -146,10 +146,10 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) { Expand(m, &*result, param.derived, param.qualified, param.levels))) result.reset(); } else { - QueryFile *file = m->FindFile(param.textDocument.uri.GetPath()); - if (!file) + auto [file, wf] = m->FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) { return; - WorkingFile *wf = m->wfiles->GetFile(file->def->path); + } for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) if (sym.kind == Kind::Func || sym.kind == Kind::Type) { result = BuildInitial(m, sym, param.derived, param.qualified, diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index d94a3d88d..52e468238 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -281,12 +281,9 @@ void MessageHandler::ccls_member(JsonReader &reader, ReplyOnce &reply) { param.levels, param.kind))) result.reset(); } else { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { switch (sym.kind) { case Kind::Func: diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index d09d57a83..2afef719b 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -41,10 +41,8 @@ Maybe FindParent(QueryFile *file, Pos pos) { void MessageHandler::ccls_navigate(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } Position ls_pos = param.position; diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 2673ecf06..4ad5bc21a 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -31,10 +31,8 @@ REFLECT_STRUCT(Param, textDocument, position, kind); void MessageHandler::ccls_vars(JsonReader &reader, ReplyOnce &reply) { Param param; Reflect(reader, param); - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index bbafa9d25..9f2948d6c 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -388,7 +388,7 @@ void MessageHandler::initialize(JsonReader &reader, ReplyOnce &reply) { void StandaloneInitialize(MessageHandler &handler, const std::string &root) { InitializeParam param; param.rootUri = DocumentUri::FromPath(root); - ReplyOnce reply; + ReplyOnce reply{handler}; Initialize(&handler, param, reply); } diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index 4d288f036..b3aa83df1 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -35,11 +35,9 @@ REFLECT_STRUCT(CodeAction, title, kind, edit); } void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { - WorkingFile *wf = wfiles->GetFile(param.textDocument.uri.GetPath()); - if (!wf) { - reply.NotReady(true); + WorkingFile *wf = FindOrFail(param.textDocument.uri.GetPath(), reply).second; + if (!wf) return; - } std::vector result; std::vector diagnostics; wfiles->WithLock([&]() { diagnostics = wf->diagnostics; }); @@ -96,16 +94,13 @@ struct CommonCodeLensParams { void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } std::vector result; - auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, - bool force_display = false) { + auto Add = [&, wf = wf](const char *singular, Cmd_xref show, Range range, + int num, bool force_display = false) { if (!num && !force_display) return; std::optional ls_range = GetLsRange(wf, range); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a29d895a8..f401931ee 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -459,7 +459,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, std::string path = param.textDocument.uri.GetPath(); WorkingFile *wf = wfiles->GetFile(path); if (!wf) { - reply.NotReady(true); + reply.NotOpened(path); return; } diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 46f04cf97..f857e4961 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -48,12 +48,9 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { void MessageHandler::textDocument_declaration(TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; - QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id); + if (!wf) return; - } std::vector result; Position &ls_pos = param.position; @@ -69,12 +66,9 @@ void MessageHandler::textDocument_declaration(TextDocumentPositionParam ¶m, void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; - QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id); + if (!wf) return; - } std::vector result; Maybe on_def; @@ -190,12 +184,9 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, void MessageHandler::textDocument_typeDefinition( TextDocumentPositionParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!file) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!file) return; - } std::vector result; auto Add = [&](const QueryType &type) { diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 32271c2f4..ef8f57d09 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -44,12 +44,9 @@ REFLECT_STRUCT(DocumentHighlight, range, kind, role); void MessageHandler::textDocument_documentHighlight( TextDocumentPositionParam ¶m, ReplyOnce &reply) { int file_id; - QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id); + if (!wf) return; - } std::vector result; std::vector syms = @@ -90,10 +87,8 @@ REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } @@ -165,10 +160,8 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader, Reflect(reader, param); int file_id; - QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id); if (!wf) { - reply.NotReady(file); return; } diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index 67fb0c0aa..a3f1981c2 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -31,12 +31,9 @@ REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, endCharacter, void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } std::vector result; std::optional ls_range; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 37bd7c46e..ba46313d6 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -80,21 +80,16 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } Format(reply, wf, {0, (unsigned)wf->buffer_content.size()}); } void MessageHandler::textDocument_onTypeFormatting( DocumentOnTypeFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } std::string_view code = wf->buffer_content; @@ -107,10 +102,8 @@ void MessageHandler::textDocument_onTypeFormatting( void MessageHandler::textDocument_rangeFormatting( DocumentRangeFormattingParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } std::string_view code = wf->buffer_content; diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 7a3e03416..848dc3a5c 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -93,12 +93,9 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } Hover result; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 8c784553d..e9858dfce 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -45,12 +45,9 @@ void MessageHandler::textDocument_references(JsonReader &reader, ReplyOnce &reply) { ReferenceParam param; Reflect(reader, param); - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; - if (!wf) { - reply.NotReady(file); + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); + if (!wf) return; - } for (auto &folder : param.folders) EnsureEndsInSlash(folder); diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 05028263a..7c478b128 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -56,10 +56,8 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, } // namespace void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(param.textDocument.uri.GetPath()); - WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr; + auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); if (!wf) { - reply.NotReady(file); return; } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 3806ffe89..420ec164d 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -152,12 +152,11 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { void MessageHandler::textDocument_signatureHelp( TextDocumentPositionParam ¶m, ReplyOnce &reply) { static CompleteConsumerCache cache; - - std::string path = param.textDocument.uri.GetPath(); Position begin_pos = param.position; + std::string path = param.textDocument.uri.GetPath(); WorkingFile *wf = wfiles->GetFile(path); if (!wf) { - reply.NotReady(true); + reply.NotOpened(path); return; } { diff --git a/src/pipeline.cc b/src/pipeline.cc index cb8ccc4e4..650c44d2c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -32,7 +32,6 @@ limitations under the License. #include #include #include -using namespace llvm; #include #include @@ -41,6 +40,8 @@ using namespace llvm; #ifndef _WIN32 #include #endif +using namespace llvm; +namespace chrono = std::chrono; namespace ccls { namespace { @@ -527,8 +528,11 @@ void LaunchStdin() { if (method.empty()) continue; bool should_exit = method == "exit"; + // g_config is not available before "initialize". Use 0 in that case. on_request->PushBack( - {id, std::move(method), std::move(message), std::move(document)}); + {id, std::move(method), std::move(message), std::move(document), + chrono::steady_clock::now() + + chrono::milliseconds(g_config ? g_config->request.timeout : 0)}); if (should_exit) break; @@ -590,11 +594,34 @@ void MainLoop() { handler.include_complete = &include_complete; bool has_indexed = false; + std::deque backlog; + StringMap> path2backlog; while (true) { + if (backlog.size()) { + auto now = chrono::steady_clock::now(); + handler.overdue = true; + while (backlog.size()) { + if (backlog[0].backlog_path.size()) { + if (now < backlog[0].deadline) + break; + handler.Run(backlog[0]); + path2backlog[backlog[0].backlog_path].pop_front(); + } + backlog.pop_front(); + } + handler.overdue = false; + } + std::vector messages = on_request->DequeueAll(); bool did_work = messages.size(); for (InMessage &message : messages) - handler.Run(message); + try { + handler.Run(message); + } catch (NotIndexed &ex) { + backlog.push_back(std::move(message)); + backlog.back().backlog_path = ex.path; + path2backlog[ex.path].push_back(&backlog.back()); + } bool indexed = false; for (int i = 20; i--;) { @@ -604,6 +631,16 @@ void MainLoop() { did_work = true; indexed = true; Main_OnIndexed(&db, &wfiles, &*update); + if (update->files_def_update) { + auto it = path2backlog.find(update->files_def_update->first.path); + if (it != path2backlog.end()) { + for (auto &message : it->second) { + handler.Run(*message); + message->backlog_path.clear(); + } + path2backlog.erase(it); + } + } } if (did_work) { @@ -615,7 +652,10 @@ void MainLoop() { FreeUnusedMemory(); has_indexed = false; } - main_waiter->Wait(quit, on_indexed, on_request); + if (backlog.empty()) + main_waiter->Wait(quit, on_indexed, on_request); + else + main_waiter->WaitUntil(backlog[0].deadline, on_indexed, on_request); } } diff --git a/src/threaded_queue.hh b/src/threaded_queue.hh index a2b5f48aa..103027aa1 100644 --- a/src/threaded_queue.hh +++ b/src/threaded_queue.hh @@ -18,6 +18,7 @@ limitations under the License. #include "utils.hh" #include +#include #include #include #include @@ -76,6 +77,14 @@ struct MultiQueueWaiter { } return true; } + + template + void WaitUntil(std::chrono::steady_clock::time_point t, + BaseThreadQueue... queues) { + MultiQueueLock l(queues...); + if (!HasState({queues...})) + cv.wait_until(l, t); + } }; // A threadsafe-queue. http://stackoverflow.com/a/16075550 From 7b3aca2952285338ce9472c63a73eebf622afd13 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 28 Dec 2018 12:30:15 -0800 Subject: [PATCH 328/378] textDocument/didOpen: index related files when a header is opened Fix #180 index.initialBlacklist: ["."] can inhibit initial indexing (useful for larger code bases). Opened files are still indexed, though. This heuristic allows related files (a/foo.c a/b/foo.cc) to be indexed when a header (foo.h) is opened. --- src/messages/textDocument_did.cc | 6 ++++-- src/project.cc | 18 ++++++++++++++++++ src/project.hh | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index b00b3c7dc..d664c5373 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -53,10 +53,12 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { // Submit new index request if it is not a header file or there is no // pending index request. - std::pair lang = lookupExtension(path); - if ((lang.first != LanguageId::Unknown && !lang.second) || + auto [lang, header] = lookupExtension(path); + if ((lang != LanguageId::Unknown && !header) || !pipeline::pending_index_requests) pipeline::Index(path, {}, IndexMode::Normal, false); + if (header) + project->IndexRelated(path); manager->OnView(path); } diff --git a/src/project.cc b/src/project.cc index c74265b6a..491af313c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -547,4 +547,22 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { // trigger refreshing semantic highlight for all working files. pipeline::Index("", {}, IndexMode::NonInteractive, false); } + +void Project::IndexRelated(const std::string &path) { + auto &gi = g_config->index; + GroupMatch match(gi.whitelist, gi.blacklist); + std::string stem = sys::path::stem(path); + std::lock_guard lock(mtx); + for (auto &[root, folder] : root2folder) + if (StringRef(path).startswith(root)) { + for (const Project::Entry &entry : folder.entries) { + std::string reason; + if (sys::path::stem(entry.filename) == stem && entry.filename != path && + match.Matches(entry.filename, &reason)) + pipeline::Index(entry.filename, entry.args, IndexMode::NonInteractive, + true); + } + break; + } +} } // namespace ccls diff --git a/src/project.hh b/src/project.hh index 5e14aa8a0..88da2b840 100644 --- a/src/project.hh +++ b/src/project.hh @@ -77,5 +77,6 @@ struct Project { const std::string &path); void Index(WorkingFiles *wfiles, RequestId id); + void IndexRelated(const std::string &path); }; } // namespace ccls From 87d7c4090380da47434378845b588a5cf5b5a6f9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 4 Jan 2019 10:54:20 +0800 Subject: [PATCH 329/378] Update wiki link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c3e251d5..53ff9aac0 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,10 @@ The comparison with cquery as noted on 2018-07-15: cquery has system include path detection (through running the compiler driver) while ccls uses clangDriver. -# >>> [Getting started](../../wiki/Getting-started) (CLICK HERE) <<< +# >>> [Getting started](../../wiki/Home) (CLICK HERE) <<< * [Build](../../wiki/Build) * [Client feature table](../../wiki/Client-feature-table) * [FAQ](../../wiki/FAQ) -ccls can index itself (~180MiB RSS when ide, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See [wiki/compile_commands.json](../../wiki/compile_commands.json) for examples. +ccls can index itself (~180MiB RSS when idle, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See [wiki/compile_commands.json](../../wiki/compile_commands.json) for examples. From d6329ea328bc355cce688e5404c81b2e783a4f83 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 13 Jan 2019 18:33:18 +0800 Subject: [PATCH 330/378] completion: if preamble size changes, rebuild it Fix #190 If a new header is added, the preamble size changes. Language clients may cache completion results, thus we rebuild preamble to avoid inaccurate results. --- src/sema_manager.cc | 18 +++++++++++++----- src/sema_manager.hh | 9 +++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 91fae5e34..c352f0f49 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -423,7 +423,9 @@ void *PreambleMain(void *manager_) { BuildCompilerInvocation(task.path, session->file.args, FS)) BuildPreamble(*session, *CI, FS, task, std::move(stat_cache)); - if (task.from_diag) { + if (task.comp_task) { + manager->comp_tasks.PushBack(std::move(task.comp_task)); + } else if (task.from_diag) { manager->ScheduleDiag(task.path, 0); } else { int debounce = @@ -474,12 +476,18 @@ void *CompletionMain(void *manager_) { DiagnosticConsumer DC; std::string content = manager->wfiles->GetContent(task->path); auto Buf = llvm::MemoryBuffer::getMemBuffer(content); + PreambleBounds Bounds = + ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0); bool in_preamble = GetOffsetForPosition({task->position.line, task->position.character}, - content) < - ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0).Size; - if (in_preamble) + content) < (int)Bounds.Size; + if (in_preamble) { preamble.reset(); + } else if (preamble && Bounds.Size != preamble->Preamble.getBounds().Size) { + manager->preamble_tasks.PushBack({task->path, std::move(task), false}, + true); + continue; + } auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC, preamble.get(), task->path, Buf); if (!Clang) @@ -556,7 +564,7 @@ void *DiagnosticMain(void *manager_) { } } if (rebuild) { - manager->preamble_tasks.PushBack({task.path, true}, true); + manager->preamble_tasks.PushBack({task.path, nullptr, true}, true); continue; } } diff --git a/src/sema_manager.hh b/src/sema_manager.hh index 5d5733492..0e1584a1a 100644 --- a/src/sema_manager.hh +++ b/src/sema_manager.hh @@ -114,10 +114,6 @@ struct SemaManager { std::function; using OnDropped = std::function; - struct PreambleTask { - std::string path; - bool from_diag = false; - }; struct CompTask { CompTask(const RequestId &id, const std::string &path, const Position &position, @@ -138,6 +134,11 @@ struct SemaManager { int64_t wait_until; int64_t debounce; }; + struct PreambleTask { + std::string path; + std::unique_ptr comp_task; + bool from_diag = false; + }; SemaManager(Project *project, WorkingFiles *wfiles, OnDiagnostic on_diagnostic, OnDropped on_dropped); From 26fb0a9dd3b2981110f116fa1979f424e49664f2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 21 Jan 2019 10:20:07 +0800 Subject: [PATCH 331/378] Add -log-file=stderr and make it default Change -log-file-append to a boolean flag --- src/log.cc | 1 + src/main.cc | 19 +++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/log.cc b/src/log.cc index a10a4a7df..3e2b5592d 100644 --- a/src/log.cc +++ b/src/log.cc @@ -72,6 +72,7 @@ Message::~Message() { std::lock_guard lock(mtx); stream_ << '\n'; fputs(stream_.str().c_str(), file); + fflush(file); if (verbosity_ == Verbosity_FATAL) abort(); } diff --git a/src/main.cc b/src/main.cc index 95cd0363c..39c6457f1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -58,10 +58,10 @@ opt opt_index("index", value_desc("root"), cat(C)); list opt_init("init", desc("extra initialization options in JSON"), cat(C)); -opt opt_log_file("log-file", desc("log"), value_desc("filename"), +opt opt_log_file("log-file", desc("stderr or log file"), + value_desc("file"), init("stderr"), cat(C)); +opt opt_log_file_append("log-file-append", desc("append to log file"), cat(C)); -opt opt_log_file_append("log-file-append", desc("log"), - value_desc("filename"), cat(C)); void CloseLog() { fclose(ccls::log::file); } @@ -95,14 +95,13 @@ int main(int argc, char **argv) { bool language_server = true; - if (opt_log_file.size() || opt_log_file_append.size()) { - ccls::log::file = opt_log_file.size() - ? fopen(opt_log_file.c_str(), "wb") - : fopen(opt_log_file_append.c_str(), "ab"); + if (opt_log_file.size()) { + ccls::log::file = + opt_log_file == "stderr" + ? stderr + : fopen(opt_log_file.c_str(), opt_log_file_append ? "ab" : "wb"); if (!ccls::log::file) { - fprintf( - stderr, "failed to open %s\n", - (opt_log_file.size() ? opt_log_file : opt_log_file_append).c_str()); + fprintf(stderr, "failed to open %s\n", opt_log_file.c_str()); return 2; } setbuf(ccls::log::file, NULL); From 0dbf6c89f119c43a4ec94586127cc1f5216888c3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 21 Jan 2019 10:44:44 +0800 Subject: [PATCH 332/378] Drop support for clang 6 --- CMakeLists.txt | 2 +- cmake/FindClang.cmake | 1 - src/clang_tu.cc | 4 --- src/indexer.cc | 44 +++---------------------- src/messages/textDocument_completion.cc | 4 --- src/sema_manager.cc | 16 +++------ 6 files changed, 9 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf39ebfd1..f84d67abc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ endif() ### Libraries # See cmake/FindClang.cmake -find_package(Clang 6.0.0) +find_package(Clang 7.0.0) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 194029005..078395dd9 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -72,7 +72,6 @@ _Clang_find_library(Clang_LIBRARY clangIndex) _Clang_find_add_library(clangFormat) _Clang_find_add_library(clangTooling) -# TODO Remove after dropping clang 6 _Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) if (clangToolingInclusions_LIBRARY) list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index a2d982b42..70078c612 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -156,7 +156,6 @@ const char *ClangBuiltinTypeName(int kind) { return "double"; case BuiltinType::LongDouble: return "long double"; -#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::ShortAccum: return "short _Accum"; case BuiltinType::Accum: @@ -205,7 +204,6 @@ const char *ClangBuiltinTypeName(int kind) { return "_Sat unsigned _Fract"; case BuiltinType::BuiltinType::SatULongFract: return "_Sat unsigned long _Fract"; -#endif case BuiltinType::Float16: return "_Float16"; case BuiltinType::Float128: @@ -213,10 +211,8 @@ const char *ClangBuiltinTypeName(int kind) { case BuiltinType::WChar_S: case BuiltinType::WChar_U: return "wchar_t"; -#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::Char8: return "char8_t"; -#endif case BuiltinType::Char16: return "char16_t"; case BuiltinType::Char32: diff --git a/src/indexer.cc b/src/indexer.cc index 43969f234..716a092f1 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -593,11 +593,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (init) { SourceManager &SM = Ctx->getSourceManager(); const LangOptions &Lang = Ctx->getLangOpts(); - SourceRange R = SM.getExpansionRange(init->getSourceRange()) -#if LLVM_VERSION_MAJOR >= 7 - .getAsRange() -#endif - ; + SourceRange R = SM.getExpansionRange(init->getSourceRange()).getAsRange(); SourceLocation L = D->getLocation(); if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; @@ -688,41 +684,15 @@ class IndexDataConsumer : public index::IndexDataConsumer { } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, -#if LLVM_VERSION_MAJOR >= 7 - SourceLocation Loc, -#else - FileID LocFID, unsigned LocOffset, -#endif - ASTNodeInfo ASTNode) override { + SourceLocation Loc, ASTNodeInfo ASTNode) override { SourceManager &SM = Ctx->getSourceManager(); const LangOptions &Lang = Ctx->getLangOpts(); -#if LLVM_VERSION_MAJOR < 7 - SourceLocation Loc; - { - const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(LocFID); - unsigned off = Entry.getOffset() + LocOffset; - if (!Entry.isFile()) - off |= 1u << 31; - Loc = SourceLocation::getFromRawEncoding(off); - } -#else FileID LocFID; -#endif SourceLocation Spell = SM.getSpellingLoc(Loc); const FileEntry *FE; Range loc; -#if LLVM_VERSION_MAJOR < 7 - CharSourceRange R; - if (SM.isMacroArgExpansion(Loc)) - R = CharSourceRange::getTokenRange(Spell); - else { - auto P = SM.getExpansionRange(Loc); - R = CharSourceRange::getTokenRange(P.first, P.second); - } -#else auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) : SM.getExpansionRange(Loc); -#endif loc = FromCharSourceRange(SM, Lang, R); LocFID = SM.getFileID(R.getBegin()); FE = SM.getFileEntryForID(LocFID); @@ -1085,12 +1055,8 @@ class IndexPPCallbacks : public PPCallbacks { StringRef Included, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported -#if LLVM_VERSION_MAJOR >= 7 - , - SrcMgr::CharacteristicKind FileType -#endif - ) override { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { if (!File) return; llvm::sys::fs::UniqueID UniqueID; @@ -1283,9 +1249,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; -#if LLVM_VERSION_MAJOR >= 7 IndexOpts.IndexImplicitInstantiation = true; -#endif std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index f401931ee..a1f0884e2 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -436,7 +436,6 @@ class CompletionConsumer : public CodeCompleteConsumer { ls_items[j].label = ls_items[j].filterText; } } -#if LLVM_VERSION_MAJOR >= 7 for (const FixItHint &FixIt : R.FixIts) { auto &AST = S.getASTContext(); TextEdit ls_edit = @@ -444,7 +443,6 @@ class CompletionConsumer : public CodeCompleteConsumer { for (size_t j = first_idx; j < ls_items.size(); j++) ls_items[j].additionalTextEdits.push_back(ls_edit); } -#endif } } @@ -474,9 +472,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, clang::CodeCompleteOptions CCOpts; CCOpts.IncludeBriefComments = true; CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#"); -#if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; -#endif CCOpts.IncludeMacros = true; if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter && diff --git a/src/sema_manager.cc b/src/sema_manager.cc index c352f0f49..a80bd0d7c 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -190,11 +190,8 @@ class StoreInclude : public PPCallbacks { StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const clang::Module *Imported -#if LLVM_VERSION_MAJOR >= 7 - , SrcMgr::CharacteristicKind FileKind -#endif - ) override { + const clang::Module *Imported, + SrcMgr::CharacteristicKind FileKind) override { (void)SM; if (File && Seen.insert(File).second) out.emplace_back(PathFromFileEntry(*File), File->getModificationTime()); @@ -304,15 +301,10 @@ std::unique_ptr BuildCompilerInstance( IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, const PreambleData *preamble, const std::string &main, std::unique_ptr &Buf) { - if (preamble) { -#if LLVM_VERSION_MAJOR >= 7 + if (preamble) preamble->Preamble.OverridePreamble(*CI, FS, Buf.get()); -#else - preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get()); -#endif - } else { + else CI->getPreprocessorOpts().addRemappedFile(main, Buf.get()); - } auto Clang = std::make_unique(session.PCH); Clang->setInvocation(std::move(CI)); From b2fcec4b97dcdbaf924e45c2c57e6f53b674f8e4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 21 Jan 2019 12:15:28 +0800 Subject: [PATCH 333/378] Implement initialization option compilationDatabaseCommand on Windows --- src/platform.hh | 3 --- src/platform_posix.cc | 43 ------------------------------- src/platform_win.cc | 5 ---- src/project.cc | 60 ++++++++++++++++++++++++++++++------------- 4 files changed, 42 insertions(+), 69 deletions(-) diff --git a/src/platform.hh b/src/platform.hh index 12446263b..79aca5587 100644 --- a/src/platform.hh +++ b/src/platform.hh @@ -28,8 +28,5 @@ void FreeUnusedMemory(); // Stop self and wait for SIGCONT. void TraceMe(); -std::string GetExternalCommandOutput(const std::vector &command, - std::string_view input); - void SpawnThread(void *(*fn)(void *), void *arg); } // namespace ccls diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 35d8d271f..c172446be 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -73,49 +73,6 @@ void TraceMe() { raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } -std::string GetExternalCommandOutput(const std::vector &command, - std::string_view input) { - int pin[2], pout[2]; - if (pipe(pin) < 0) { - perror("pipe(stdin)"); - return ""; - } - if (pipe(pout) < 0) { - perror("pipe(stdout)"); - close(pin[0]); - close(pin[1]); - return ""; - } - pid_t child = fork(); - if (child == 0) { - dup2(pout[0], 0); - dup2(pin[1], 1); - close(pin[0]); - close(pin[1]); - close(pout[0]); - close(pout[1]); - auto argv = new char *[command.size() + 1]; - for (size_t i = 0; i < command.size(); i++) - argv[i] = const_cast(command[i].c_str()); - argv[command.size()] = nullptr; - execvp(argv[0], argv); - _Exit(127); - } - close(pin[1]); - close(pout[0]); - // O_NONBLOCK is disabled, write(2) blocks until all bytes are written. - (void)write(pout[1], input.data(), input.size()); - close(pout[1]); - std::string ret; - char buf[4096]; - ssize_t n; - while ((n = read(pin[0], buf, sizeof buf)) > 0) - ret.append(buf, n); - close(pin[0]); - waitpid(child, NULL, 0); - return ret; -} - void SpawnThread(void *(*fn)(void *), void *arg) { pthread_t thd; pthread_attr_t attr; diff --git a/src/platform_win.cc b/src/platform_win.cc index a2ca5185a..f933b2571 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -57,11 +57,6 @@ void FreeUnusedMemory() {} // TODO Wait for debugger to attach void TraceMe() {} -std::string GetExternalCommandOutput(const std::vector &command, - std::string_view input) { - return ""; -} - void SpawnThread(void *(*fn)(void *), void *arg) { std::thread(fn, arg).detach(); } diff --git a/src/project.cc b/src/project.cc index 491af313c..6833ad7bb 100644 --- a/src/project.cc +++ b/src/project.cc @@ -31,13 +31,17 @@ limitations under the License. #include #include #include +#include #include -#if defined(__unix__) || defined(__APPLE__) -#include +#ifdef _WIN32 +# include +#else +# include #endif +#include #include #include #include @@ -308,7 +312,8 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { - SmallString<256> Path, CDBDir; + SmallString<256> CDBDir, Path, StdinPath; + std::string err_msg; folder.entries.clear(); if (g_config->compilationDatabaseCommand.empty()) { CDBDir = root; @@ -319,33 +324,49 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { // If `compilationDatabaseCommand` is specified, execute it to get the // compdb. #ifdef _WIN32 - // TODO + char tmpdir[L_tmpnam]; + tmpnam_s(tmpdir, L_tmpnam); + CDBDir = tmpdir; + if (sys::fs::create_directory(tmpdir, false)) + return; #else char tmpdir[] = "/tmp/ccls-compdb-XXXXXX"; if (!mkdtemp(tmpdir)) return; CDBDir = tmpdir; - sys::path::append(Path, CDBDir, "compile_commands.json"); - rapidjson::StringBuffer input; - rapidjson::Writer writer(input); - JsonWriter json_writer(&writer); - Reflect(json_writer, *g_config); - std::string contents = GetExternalCommandOutput( - std::vector{g_config->compilationDatabaseCommand, root}, - input.GetString()); - FILE *fout = fopen(Path.c_str(), "wb"); - fwrite(contents.c_str(), contents.size(), 1, fout); - fclose(fout); #endif + sys::path::append(Path, CDBDir, "compile_commands.json"); + sys::path::append(StdinPath, CDBDir, "stdin"); + { + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + JsonWriter json_writer(&writer); + Reflect(json_writer, *g_config); + std::string input = sb.GetString(); + FILE *fout = fopen(StdinPath.c_str(), "wb"); + fwrite(input.c_str(), input.size(), 1, fout); + fclose(fout); + } + std::array, 3> Redir{StringRef(StdinPath), + StringRef(Path), StringRef()}; + std::vector args{g_config->compilationDatabaseCommand, root}; + if (sys::ExecuteAndWait(args[0], args, llvm::None, Redir, 0, 0, &err_msg) < + 0) { + LOG_S(ERROR) << "failed to execute " << args[0].str() << " " + << args[1].str() << ": " << err_msg; + return; + } } - std::string err_msg; std::unique_ptr CDB = tooling::CompilationDatabase::loadFromDirectory(CDBDir, err_msg); if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 - // TODO + DeleteFileA(StdinPath.c_str()); + DeleteFileA(Path.c_str()); + RemoveDirectoryA(CDBDir.c_str()); #else + unlink(StdinPath.c_str()); unlink(Path.c_str()); rmdir(CDBDir.c_str()); #endif @@ -354,7 +375,10 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { ProjectProcessor proc(folder); StringSet<> Seen; std::vector result; - if (CDB) { + if (!CDB) { + if (g_config->compilationDatabaseCommand.size() || sys::fs::exists(Path)) + LOG_S(ERROR) << "failed to load " << Path.c_str(); + } else { LOG_S(INFO) << "loaded " << Path.c_str(); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { static bool once; From 9bc762961a9f7fac5e92c2169801b6e2c6f3614f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 22 Jan 2019 22:44:13 +0800 Subject: [PATCH 334/378] cmake: delete SYSTEM_CLANG and auto-download mechanism --- .appveyor.yml | 2 +- CMakeLists.txt | 67 +-------- .../LLVM-7.0.0-win64.exe.SHA256 | 1 - ....0.0-amd64-unknown-freebsd11.tar.xz.SHA256 | 1 - ...vm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 | 1 - ...86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 | 1 - ...86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 | 1 - cmake/DownloadAndExtract7zip.cmake | 52 ------- cmake/DownloadAndExtractClang.cmake | 129 ------------------ 9 files changed, 2 insertions(+), 253 deletions(-) delete mode 100644 clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 delete mode 100644 clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 delete mode 100644 cmake/DownloadAndExtract7zip.cmake delete mode 100644 cmake/DownloadAndExtractClang.cmake diff --git a/.appveyor.yml b/.appveyor.yml index 0fc36d3fe..42a7a4c03 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -15,7 +15,7 @@ install: - 7z x llvm.tar - git submodule update --init --recursive build_script: - - cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DSYSTEM_CLANG=ON -DCLANG_ROOT=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release + - cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release - cmake --build build --target ccls --config Release artifacts: diff --git a/CMakeLists.txt b/CMakeLists.txt index f84d67abc..993376d81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,13 +5,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) # Required Clang version -set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR} - CACHE STRING "Downloaded Clang location") -option(SYSTEM_CLANG "Use system installation of Clang instead of \ - downloading Clang" OFF) -option(ASAN "Compile with address sanitizers" OFF) option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) -option(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" OFF) option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) # Sources for the executable are specified at end of CMakeLists.txt @@ -30,10 +24,7 @@ add_executable(ccls "") # Enable C++17 (Required) set_property(TARGET ccls PROPERTY CXX_STANDARD 17) set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) -# Disable gnu extensions except for Cygwin which needs them to build properly -if(NOT CYGWIN) - set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) -endif() +set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) if(NOT LLVM_ENABLE_RTTI) # releases.llvm.org libraries are compiled with -fno-rtti @@ -76,37 +67,6 @@ else() target_compile_options(ccls PRIVATE $<$:-fno-limit-debug-info>) endif() - - if(ASAN) - target_compile_options(ccls PRIVATE -fsanitize=address,undefined) - # target_link_libraries also takes linker flags - target_link_libraries(ccls PRIVATE -fsanitize=address,undefined) - endif() -endif() - -### Download Clang if required - -if(NOT SYSTEM_CLANG) - message(STATUS "Using downloaded Clang") - - include(DownloadAndExtractClang) - download_and_extract_clang(${CLANG_DOWNLOAD_LOCATION}) - # Used by FindClang - set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR}) - - if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang AND CLANG_USE_BUNDLED_LIBC++) - message(STATUS "Using bundled libc++") - target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1) - if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - # Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++ - target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++abi) - - # FreeBSD defaults to -stdlib=libc++ and uses system libcxxrt.a - endif() - endif() - -else() - message(STATUS "Using system Clang") endif() ### Libraries @@ -143,31 +103,6 @@ target_include_directories(ccls SYSTEM PRIVATE install(TARGETS ccls RUNTIME DESTINATION bin) -if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows) - - if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD) - set_property(TARGET ccls APPEND PROPERTY - INSTALL_RPATH $ORIGIN/../lib) - elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - set_property(TARGET ccls APPEND PROPERTY - INSTALL_RPATH @loader_path/../lib) - endif() - - file(GLOB LIBCLANG_PLUS_SYMLINKS - ${DOWNLOADED_CLANG_DIR}/lib/libclang.[so,dylib]*) - install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib) -endif() - -# Allow running from build Windows by copying libclang.dll to build directory -if(NOT SYSTEM_CLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) - add_custom_command(TARGET ccls - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${DOWNLOADED_CLANG_DIR}/bin/libclang.dll - $ - COMMENT "Copying libclang.dll to build directory ...") -endif() - ### Tools # We use glob here since source files are already manually added with diff --git a/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 b/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 deleted file mode 100644 index 54bea9e6c..000000000 --- a/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 +++ /dev/null @@ -1 +0,0 @@ -74b197a3959b0408adf0824be01db8dddfa2f9a967f4085af3fad900ed5fdbf6 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 deleted file mode 100644 index b8a56bfa7..000000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 deleted file mode 100644 index 86f733c96..000000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 deleted file mode 100644 index bc8306913..000000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 deleted file mode 100644 index 1475a0a85..000000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2 \ No newline at end of file diff --git a/cmake/DownloadAndExtract7zip.cmake b/cmake/DownloadAndExtract7zip.cmake deleted file mode 100644 index 72bc879d5..000000000 --- a/cmake/DownloadAndExtract7zip.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/. -# -# Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR -function(download_and_extract_7zip 7ZIP_DOWNLOAD_LOCATION) - -set(7ZIP_VERSION 1801) -set(7ZIP_EXT .msi) -set(7ZIP_NAME 7z${7ZIP_VERSION}-x64) -set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT}) - -set(7ZIP_FILE ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_FULL_NAME}) -set(7ZIP_EXTRACT_DIR ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_NAME}) -set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME}) - -# Exit if 7-Zip is already downloaded and extracted -find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH - PATHS ${7ZIP_EXTRACT_DIR}/Files/7-Zip) -if(7ZIP_EXECUTABLE) - message(STATUS "7-Zip already downloaded") - return() -endif() - -message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...") -file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE}) - -find_program(MSIEXEC_EXECUTABLE msiexec) -if(NOT MSIEXEC_EXECUTABLE) - message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \ -installer). Install 7-Zip yourself and make sure it is available in the path") -endif() - -message(STATUS "Extracting downloaded 7-Zip ...") - -# msiexec requires Windows path separators (\) -file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE) -file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) - -# msiexec with /a option allows extraction of msi installers without requiring -# admin privileges. We use this to extract the 7-Zip installer without -# requiring any actions from the user -execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn - TARGETDIR=${7ZIP_EXTRACT_DIR} - WORKING_DIRECTORY ${7ZIP_DOWNLOAD_LOCATION} - OUTPUT_QUIET) - -# Convert back to CMake separators (/) before returning -file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) - -# Actual 7-Zip directory is nested inside the extract directory. -set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE) - -endfunction() \ No newline at end of file diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake deleted file mode 100644 index 9365b1881..000000000 --- a/cmake/DownloadAndExtractClang.cmake +++ /dev/null @@ -1,129 +0,0 @@ -# Downloads and extracts the Clang archive for the current system from -# https://releases.llvm.org -# -# Returns the extracted Clang archive directory in DOWNLOADED_CLANG_DIR -# -# Downloads 7-Zip to extract Clang if it isn't available in the PATH -function(download_and_extract_clang CLANG_DOWNLOAD_LOCATION) - -set(CLANG_VERSION 7.0.0) -set(CLANG_ARCHIVE_EXT .tar.xz) - -if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) - - # Default to Ubuntu 16.04 - set(CLANG_ARCHIVE_NAME - clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-16.04) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows) - - set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64) - set(CLANG_ARCHIVE_EXT .exe) - -elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - - set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd11) - -endif() - -set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT}) -set(CLANG_ARCHIVE_FILE ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_FULL_NAME}) -set(CLANG_ARCHIVE_EXTRACT_DIR ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_NAME}) -set(CLANG_ARCHIVE_URL - https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME}) -set(CLANG_ARCHIVE_HASH_FILE - ${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256) - -# Exit if Clang is already downloaded and extracted -set(CLANG_ROOT ${CLANG_ARCHIVE_EXTRACT_DIR}) -find_package(Clang ${CLANG_VERSION} QUIET) -if(Clang_FOUND) - message(STATUS "Clang already downloaded") - set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) - return() -endif() - -if(NOT CLANG_ARCHIVE_NAME) - message(FATAL_ERROR "No Clang archive url specified for current platform \ -(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.") -endif() - -if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE}) - message(FATAL_ERROR "No SHA256 hash available for the current platform \ -(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \ -file an issue to get it added.") -endif() - -# Download Clang archive -message(STATUS "Downloading Clang ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...") -file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE} - STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT) - -# Abort if download failed -list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE) -if(${ERROR_CODE}) - list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING) - message(FATAL_ERROR ${ERROR_STRING}) -endif() - -# Retrieve expected hash from file and strip newline -file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH) -string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH) -# Calculate actual hash -file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH) -# Abort if hashes do not match -if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH}) - message(FATAL_ERROR "SHA256 hash of downloaded Clang does not match \ -expected hash. Remove the build directory and try running CMake again. If this \ -keeps happening, file an issue to report the problem.") -endif() - -if(${CLANG_ARCHIVE_EXT} STREQUAL .exe) - # Download and extract 7-zip if not found in PATH - find_program(7ZIP_EXECUTABLE 7z) - if(NOT 7ZIP_EXECUTABLE) - message(STATUS "7-Zip not found in PATH") - - include(DownloadAndExtract7zip) - download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION}) - find_program(7ZIP_EXECUTABLE - NAMES 7z - NO_DEFAULT_PATH - PATHS ${DOWNLOADED_7ZIP_DIR} - ) - else() - message(STATUS "7-Zip found in PATH") - endif() - - message(STATUS "Extracting downloaded Clang with 7-Zip ...") - - # Avoid running the Clang installer by extracting the exe with 7-Zip - execute_process( - COMMAND ${7ZIP_EXECUTABLE} x - -o${CLANG_ARCHIVE_EXTRACT_DIR} - -xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE} - WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} - OUTPUT_QUIET - ) - -elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz) - message(STATUS "Extracting downloaded Clang with CMake built-in tar ...") - - # CMake has builtin support for tar via the -E flag - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE} - # Specify working directory to allow running cmake from - # everywhere - # (example: cmake -H"$HOME/cquery" -B"$home/cquery/build") - WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION} - OUTPUT_QUIET - ) -endif() - -set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE) - -endfunction() From d4de474be18b36221edac498291fa54165ceb85c Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Wed, 30 Jan 2019 23:21:40 +0800 Subject: [PATCH 335/378] Fix completion result sorting in VSCode (#210) Fix #207 --- src/messages/textDocument_completion.cc | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a1f0884e2..3a844e2df 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -134,6 +134,23 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, result.isIncomplete = true; } + int overwrite_len = 0; + for (auto &item : items) { + auto &edits = item.additionalTextEdits; + if (edits.size() && edits[0].range.end == begin_pos) { + Position start = edits[0].range.start, end = edits[0].range.end; + if (start.line == begin_pos.line) { + overwrite_len = + std::max(overwrite_len, end.character - start.character); + } else { + overwrite_len = -1; + break; + } + } + } + + Position overwrite_begin = {begin_pos.line, + begin_pos.character - overwrite_len}; std::string sort(4, ' '); for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; @@ -142,17 +159,20 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, // https://github.com/Microsoft/language-server-protocol/issues/543 // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; - if (edits.size() && edits[0].range.end == begin_pos) { - Position start = edits[0].range.start, end = edits[0].range.end; - item.textEdit.range.start = start; - item.textEdit.newText = edits[0].newText + item.textEdit.newText; - if (start.line == begin_pos.line) { - item.filterText = - buffer_line.substr(start.character, - end.character - start.character) + - item.filterText; + if (overwrite_len > 0) { + item.textEdit.range.start = overwrite_begin; + std::string orig = buffer_line.substr(overwrite_begin.character, overwrite_len); + if (edits.size() && edits[0].range.end == begin_pos && + edits[0].range.start.line == begin_pos.line) { + int cur_edit_len = edits[0].range.end.character - edits[0].range.start.character; + item.textEdit.newText = + buffer_line.substr(overwrite_begin.character, overwrite_len - cur_edit_len) + + edits[0].newText + item.textEdit.newText; + edits.erase(edits.begin()); + } else { + item.textEdit.newText = orig + item.textEdit.newText; } - edits.erase(edits.begin()); + item.filterText = orig + item.filterText; } if (item.filterText == item.label) item.filterText.clear(); From f1efcb80c7310cb412d23f8876d4592771561d41 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 29 Jan 2019 15:47:03 +0800 Subject: [PATCH 336/378] Log {Request,Notification}Message, and timestamp change due to dependency --- src/main.cc | 3 ++- src/pipeline.cc | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main.cc b/src/main.cc index 39c6457f1..6bf11d685 100644 --- a/src/main.cc +++ b/src/main.cc @@ -49,7 +49,8 @@ namespace { OptionCategory C("ccls options"); opt opt_help("h", desc("Alias for -help"), cat(C)); -opt opt_verbose("v", desc("verbosity"), init(0), cat(C)); +opt opt_verbose("v", desc("verbosity, from -3 (fatal) to 2 (verbose)"), + init(0), cat(C)); opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests"), cat(C)); diff --git a/src/pipeline.cc b/src/pipeline.cc index 650c44d2c..f73374065 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -118,8 +118,8 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, { std::lock_guard lock(vfs->mutex); if (prev->mtime < vfs->state[path].timestamp) { - LOG_S(INFO) << "timestamp changed for " << path - << (from ? " (via " + *from + ")" : std::string()); + LOG_V(1) << "timestamp changed for " << path + << (from ? " (via " + *from + ")" : std::string()); return true; } } @@ -131,8 +131,8 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, if (strcmp(prev->args[i], args[i]) && sys::path::stem(args[i]) != stem) changed = true; if (changed) - LOG_S(INFO) << "args changed for " << path - << (from ? " (via " + *from + ")" : std::string()); + LOG_V(1) << "args changed for " << path + << (from ? " (via " + *from + ")" : std::string()); return changed; }; @@ -262,10 +262,14 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, if (auto mtime1 = LastWriteTime(dep.first.val().str())) { if (dep.second < *mtime1) { reparse = 2; + LOG_V(1) << "timestamp changed for " << path_to_index << " via " + << dep.first.val().str(); break; } } else { reparse = 2; + LOG_V(1) << "timestamp changed for " << path_to_index << " via " + << dep.first.val().str(); break; } } @@ -525,6 +529,10 @@ void LaunchStdin() { std::string method; ReflectMember(reader, "id", id); ReflectMember(reader, "method", method); + if (id.Valid()) + LOG_V(2) << "receive RequestMessage: " << id.value << " " << method; + else + LOG_V(2) << "receive NotificationMessage " << method; if (method.empty()) continue; bool should_exit = method == "exit"; @@ -738,6 +746,7 @@ void NotifyOrRequest(const char *method, bool request, JsonWriter writer(&w); fn(writer); w.EndObject(); + LOG_V(2) << (request ? "RequestMessage: " : "NotificationMessage: ") << method; for_stdout->PushBack(output.GetString()); } @@ -765,6 +774,8 @@ static void Reply(RequestId id, const char *key, JsonWriter writer(&w); fn(writer); w.EndObject(); + if (id.Valid()) + LOG_V(2) << "respond to RequestMessage: " << id.value; for_stdout->PushBack(output.GetString()); } From e4ba51aea3f1d62142a16cbb2c96f8a279d30f52 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Sun, 14 Oct 2018 07:58:08 +0800 Subject: [PATCH 337/378] textDocument/signatureHelp: enable documentation --- src/messages/textDocument_signatureHelp.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 420ec164d..419bdbe80 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -103,10 +103,8 @@ class SignatureHelpConsumer : public CodeCompleteConsumer { const char *ret_type = nullptr; SignatureInformation &ls_sig = ls_sighelp.signatures.emplace_back(); -#if LLVM_VERSION_MAJOR >= 8 const RawComment *RC = getCompletionComment(S.getASTContext(), Cand.getFunction()); ls_sig.documentation = RC ? RC->getBriefText(S.getASTContext()) : ""; -#endif for (const auto &Chunk : *CCS) switch (Chunk.Kind) { case CodeCompletionString::CK_ResultType: @@ -183,7 +181,7 @@ void MessageHandler::textDocument_signatureHelp( CodeCompleteOptions CCOpts; CCOpts.IncludeGlobals = false; CCOpts.IncludeMacros = false; - CCOpts.IncludeBriefComments = false; + CCOpts.IncludeBriefComments = true; if (cache.IsCacheValid(path, begin_pos)) { SignatureHelpConsumer Consumer(CCOpts, true); cache.WithLock([&]() { Consumer.ls_sighelp = cache.result; }); From 233ed4f741cb9f3f22a6330900677492157375e7 Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Mon, 15 Oct 2018 23:25:46 +0800 Subject: [PATCH 338/378] Fix is_local for vars with non-auto storage period --- src/indexer.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/indexer.hh b/src/indexer.hh index 191f80746..fb762ac10 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -256,7 +256,8 @@ struct VarDef : NameMixin { parent_kind == SymbolKind::Method || parent_kind == SymbolKind::StaticMethod || parent_kind == SymbolKind::Constructor) && - storage == clang::SC_None; + (storage == clang::SC_None || storage == clang::SC_Auto || + storage == clang::SC_Register); } std::vector GetBases() const { return {}; } From 872498538808c032bf97dcacf365e4f40ea5e62d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 2 Feb 2019 14:14:23 +0800 Subject: [PATCH 339/378] Compute CompletionItemKind from Declaration instead of CursorKind --- src/indexer.cc | 8 +- src/messages/textDocument_completion.cc | 176 ++++++++++++------------ 2 files changed, 95 insertions(+), 89 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 716a092f1..bae9e5684 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -119,12 +119,11 @@ Kind GetKind(const Decl *D, SymbolKind &kind) { case Decl::LinkageSpec: return Kind::Invalid; case Decl::Namespace: - kind = SymbolKind::Namespace; - return Kind::Type; case Decl::NamespaceAlias: - kind = SymbolKind::TypeAlias; + kind = SymbolKind::Namespace; return Kind::Type; case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: case Decl::ObjCImplementation: case Decl::ObjCInterface: case Decl::ObjCProtocol: @@ -166,6 +165,9 @@ Kind GetKind(const Decl *D, SymbolKind &kind) { case Decl::ClassTemplatePartialSpecialization: kind = SymbolKind::Class; return Kind::Type; + case Decl::TemplateTypeParm: + kind = SymbolKind::TypeParameter; + return Kind::Type; case Decl::TypeAlias: case Decl::Typedef: case Decl::UnresolvedUsingTypename: diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 3a844e2df..714a63a63 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -227,88 +227,95 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text, finalize(); } -CompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { - switch (cursor_kind) { - case CXCursor_UnexposedDecl: - return CompletionItemKind::Text; - - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - return CompletionItemKind::Struct; - case CXCursor_ClassDecl: - return CompletionItemKind::Class; - case CXCursor_EnumDecl: - return CompletionItemKind::Enum; - case CXCursor_FieldDecl: - return CompletionItemKind::Field; - case CXCursor_EnumConstantDecl: - return CompletionItemKind::EnumMember; - case CXCursor_FunctionDecl: - return CompletionItemKind::Function; - case CXCursor_VarDecl: - case CXCursor_ParmDecl: - return CompletionItemKind::Variable; - case CXCursor_ObjCInterfaceDecl: - return CompletionItemKind::Interface; - - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_CXXMethod: - case CXCursor_ObjCClassMethodDecl: - return CompletionItemKind::Method; - - case CXCursor_FunctionTemplate: - return CompletionItemKind::Function; - - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - return CompletionItemKind::Constructor; - - case CXCursor_ObjCIvarDecl: - return CompletionItemKind::Variable; - - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_UsingDeclaration: - case CXCursor_TypedefDecl: - case CXCursor_TypeAliasDecl: - case CXCursor_TypeAliasTemplateDecl: - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_ObjCCategoryImplDecl: - return CompletionItemKind::Class; - - case CXCursor_ObjCPropertyDecl: - return CompletionItemKind::Property; - - case CXCursor_MacroInstantiation: - case CXCursor_MacroDefinition: - return CompletionItemKind::Text; - - case CXCursor_Namespace: - case CXCursor_NamespaceAlias: - case CXCursor_NamespaceRef: - return CompletionItemKind::Module; - - case CXCursor_MemberRef: - case CXCursor_TypeRef: - case CXCursor_ObjCSuperClassRef: - case CXCursor_ObjCProtocolRef: - case CXCursor_ObjCClassRef: - return CompletionItemKind::Reference; - - case CXCursor_NotImplemented: - case CXCursor_OverloadCandidate: - return CompletionItemKind::Text; - - case CXCursor_TemplateTypeParameter: - case CXCursor_TemplateTemplateParameter: - return CompletionItemKind::TypeParameter; +CompletionItemKind GetCompletionKind(CodeCompletionContext::Kind K, + const CodeCompletionResult &R) { + switch (R.Kind) { + case CodeCompletionResult::RK_Declaration: { + const Decl *D = R.Declaration; + switch (D->getKind()) { + case Decl::LinkageSpec: + return CompletionItemKind::Keyword; + case Decl::Namespace: + case Decl::NamespaceAlias: + return CompletionItemKind::Module; + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + return CompletionItemKind::Interface; + case Decl::ObjCMethod: + return CompletionItemKind::Method; + case Decl::ObjCProperty: + return CompletionItemKind::Property; + case Decl::ClassTemplate: + return CompletionItemKind::Class; + case Decl::FunctionTemplate: + return CompletionItemKind::Function; + case Decl::TypeAliasTemplate: + return CompletionItemKind::Class; + case Decl::VarTemplate: + if (cast(D)->getTemplatedDecl()->isConstexpr()) + return CompletionItemKind::Constant; + return CompletionItemKind::Variable; + case Decl::TemplateTemplateParm: + return CompletionItemKind::TypeParameter; + case Decl::Enum: + return CompletionItemKind::Enum; + case Decl::CXXRecord: + case Decl::Record: + if (auto *RD = dyn_cast(D)) + if (RD->getTagKind() == TTK_Struct) + return CompletionItemKind::Struct; + return CompletionItemKind::Class; + case Decl::TemplateTypeParm: + case Decl::TypeAlias: + case Decl::Typedef: + return CompletionItemKind::TypeParameter; + case Decl::Binding: + return CompletionItemKind::Variable; + case Decl::Field: + case Decl::ObjCIvar: + return CompletionItemKind::Field; + case Decl::Function: + return CompletionItemKind::Function; + case Decl::CXXMethod: + return CompletionItemKind::Method; + case Decl::CXXConstructor: + return CompletionItemKind::Constructor; + case Decl::CXXConversion: + case Decl::CXXDestructor: + return CompletionItemKind::Method; + case Decl::Var: + case Decl::Decomposition: + case Decl::ImplicitParam: + case Decl::ParmVar: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: + if (cast(D)->isConstexpr()) + return CompletionItemKind::Constant; + return CompletionItemKind::Variable; + case Decl::EnumConstant: + return CompletionItemKind::EnumMember; + case Decl::IndirectField: + return CompletionItemKind::Field; - default: - LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind; - return CompletionItemKind::Text; + default: + LOG_S(WARNING) << "Unhandled " << int(D->getKind()); + return CompletionItemKind::Text; + } + break; + } + case CodeCompletionResult::RK_Keyword: + return CompletionItemKind::Keyword; + case CodeCompletionResult::RK_Macro: + return CompletionItemKind::Reference; + case CodeCompletionResult::RK_Pattern: +#if LLVM_VERSION_MAJOR >= 8 + if (K == CodeCompletionContext::CCC_IncludedFile) + return CompletionItemKind::File; +#endif + return CompletionItemKind::Snippet; } } @@ -429,15 +436,12 @@ class CompletionConsumer : public CodeCompleteConsumer { NK == DeclarationName::CXXLiteralOperatorName) continue; } + CodeCompletionString *CCS = R.CreateCodeCompletionString( S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); CompletionItem ls_item; - ls_item.kind = GetCompletionKind(R.CursorKind); -#if LLVM_VERSION_MAJOR >= 8 - if (Context.getKind() == CodeCompletionContext::CCC_IncludedFile) - ls_item.kind = CompletionItemKind::File; -#endif + ls_item.kind = GetCompletionKind(Context.getKind(), R); if (const char *brief = CCS->getBriefComment()) ls_item.documentation = brief; ls_item.detail = CCS->getParentContextName().str(); From 6185d69d9d5c5a2aba3902ce7c95cc4f430abb20 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 10 Feb 2019 11:58:18 +0800 Subject: [PATCH 340/378] GetFallback: append clang.extraArgs When compile_commands.json is absent, GetFallback is called to get default clang command line when there is no .ccls or .ccls is empty. --- src/project.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/project.cc b/src/project.cc index 6833ad7bb..717f81c63 100644 --- a/src/project.cc +++ b/src/project.cc @@ -227,6 +227,8 @@ std::vector GetFallback(const std::string path) { std::vector argv{"clang"}; if (sys::path::extension(path) == ".h") argv.push_back("-xobjective-c++-header"); + for (const std::string &arg : g_config->clang.extraArgs) + argv.push_back(Intern(arg)); argv.push_back(Intern(path)); return argv; } From 3f6ece0a444642485c2dbaca2b760bc938e85215 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 10 Feb 2019 18:17:07 +0800 Subject: [PATCH 341/378] Add initialization option `capabilities.*` and index.maxInitializerLines indexer.cc: use index.maxInitializerLines instead of kInitializerMaxLines messages/initialize.cc: some ServerCapabilities are toggable: documentOnTypeFormattingProvider.firstTriggerCharacter foldingRangeProvider workspace.workspaceFolders.supported --- src/config.hh | 42 ++++++++++++++++++++++++++++++++------ src/indexer.cc | 6 ++---- src/messages/initialize.cc | 28 +++++++++++-------------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/config.hh b/src/config.hh index 4c7eabbb8..ca914dc63 100644 --- a/src/config.hh +++ b/src/config.hh @@ -54,6 +54,25 @@ struct Config { // member has changed. SerializeFormat cacheFormat = SerializeFormat::Binary; + struct ServerCap { + struct DocumentOnTypeFormattingOptions { + std::string firstTriggerCharacter = "}"; + std::vector moreTriggerCharacter; + } documentOnTypeFormattingProvider; + + // Set to false if you don't want folding ranges. + bool foldingRangeProvider = true; + + struct Workspace { + struct WorkspaceFolders { + // Set to false if you don't want workspace folders. + bool supported = true; + + bool changeNotifications = true; + } workspaceFolders; + } workspace; + } capabilities; + struct Clang { // Arguments that should be excluded, e.g. ["-fopenmp", "-Wall"] // @@ -219,6 +238,10 @@ struct Config { std::vector initialBlacklist; std::vector initialWhitelist; + // If a variable initializer/macro replacement-list has fewer than this many + // lines, include the initializer in detailed_name. + int maxInitializerLines = 5; + // If not 0, a file will be indexed in each tranlation unit that includes it. int multiVersion = 0; @@ -267,6 +290,13 @@ struct Config { int maxNum = 2000; } xref; }; +REFLECT_STRUCT(Config::ServerCap::DocumentOnTypeFormattingOptions, + firstTriggerCharacter, moreTriggerCharacter); +REFLECT_STRUCT(Config::ServerCap::Workspace::WorkspaceFolders, supported, + changeNotifications); +REFLECT_STRUCT(Config::ServerCap::Workspace, workspaceFolders); +REFLECT_STRUCT(Config::ServerCap, documentOnTypeFormattingProvider, + foldingRangeProvider, workspace); REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, resourceDir); REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, @@ -281,17 +311,17 @@ REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, - initialWhitelist, multiVersion, multiVersionBlacklist, - multiVersionWhitelist, onChange, threads, trackDependency, - whitelist); + initialWhitelist, maxInitializerLines, multiVersion, + multiVersionBlacklist, multiVersionWhitelist, onChange, threads, + trackDependency, whitelist); REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); REFLECT_STRUCT(Config::Xref, maxNum); REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, - cacheDirectory, cacheFormat, clang, client, codeLens, completion, - diagnostics, highlight, index, request, session, workspaceSymbol, - xref); + cacheDirectory, cacheFormat, capabilities, clang, client, + codeLens, completion, diagnostics, highlight, index, request, + session, workspaceSymbol, xref); extern Config *g_config; diff --git a/src/indexer.cc b/src/indexer.cc index bae9e5684..03bcc9b1e 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -41,8 +41,6 @@ using namespace clang; namespace ccls { namespace { -constexpr int kInitializerMaxLines = 3; - GroupMatch *multiVersionMatcher; struct File { @@ -600,7 +598,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); - Twine Init = Buf.count('\n') <= kInitializerMaxLines - 1 + Twine Init = Buf.count('\n') <= g_config->index.maxInitializerLines - 1 ? Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) : Twine(" = ", Buf) : Twine(); @@ -1098,7 +1096,7 @@ class IndexPPCallbacks : public PPCallbacks { var.def.short_name_size = Name.size(); StringRef Buf = GetSourceInRange(SM, Lang, R); var.def.hover = - Intern(Buf.count('\n') <= kInitializerMaxLines - 1 + Intern(Buf.count('\n') <= g_config->index.maxInitializerLines - 1 ? Twine("#define ", GetSourceInRange(SM, Lang, R)).str() : Twine("#define ", Name).str()); } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 9f2948d6c..6259e8d05 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -87,10 +87,8 @@ struct ServerCap { } codeLensProvider; bool documentFormattingProvider = true; bool documentRangeFormattingProvider = true; - struct DocumentOnTypeFormattingOptions { - std::string firstTriggerCharacter = "}"; - std::vector moreTriggerCharacter; - } documentOnTypeFormattingProvider; + Config::ServerCap::DocumentOnTypeFormattingOptions + documentOnTypeFormattingProvider; bool renameProvider = true; struct DocumentLinkOptions { bool resolveProvider = true; @@ -100,28 +98,18 @@ struct ServerCap { struct ExecuteCommandOptions { std::vector commands = {ccls_xref}; } executeCommandProvider; - struct Workspace { - struct WorkspaceFolders { - bool supported = true; - bool changeNotifications = true; - } workspaceFolders; - } workspace; + Config::ServerCap::Workspace workspace; }; REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds); REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider); REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider, triggerCharacters); REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider); -REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions, - firstTriggerCharacter, moreTriggerCharacter); REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands); REFLECT_STRUCT(ServerCap::SaveOptions, includeText); REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters); REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change, willSave, willSaveWaitUntil, save); -REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported, - changeNotifications); -REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders); REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider, signatureHelpProvider, definitionProvider, implementationProvider, typeDefinitionProvider, @@ -329,7 +317,15 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { // Send initialization before starting indexers, so we don't send a // status update too early. - reply(InitializeResult{}); + { + InitializeResult result; + auto &c = result.capabilities; + c.documentOnTypeFormattingProvider = + g_config->capabilities.documentOnTypeFormattingProvider; + c.foldingRangeProvider = g_config->capabilities.foldingRangeProvider; + c.workspace = g_config->capabilities.workspace; + reply(result); + } // Set project root. EnsureEndsInSlash(project_path); From ea774dadf5e5c81575ec55f63ce592c89c9730f2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 16 Feb 2019 17:23:47 +0800 Subject: [PATCH 342/378] indexer: change Pos computation from byte offset to UTF-8 encoded code point offset --- src/clang_tu.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 70078c612..8e1b6c439 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -45,6 +45,16 @@ static Pos Decomposed2LineAndCol(const SourceManager &SM, std::pair I) { int l = SM.getLineNumber(I.first, I.second) - 1, c = SM.getColumnNumber(I.first, I.second) - 1; + bool Invalid = false; + StringRef Buf = SM.getBufferData(I.first, &Invalid); + if (!Invalid) { + StringRef P = Buf.substr(I.second - c, c); + c = 0; + for (size_t i = 0; i < P.size(); ) + if (c++, (uint8_t)P[i++] >= 128) + while (i < P.size() && (uint8_t)P[i] >= 128 && (uint8_t)P[i] < 192) + i++; + } return {(int16_t)std::min(l, INT16_MAX), (int16_t)std::min(c, INT16_MAX)}; } From 3a252fc0add7954a6b42bac4451308b10de16eaa Mon Sep 17 00:00:00 2001 From: Leszek Swirski Date: Thu, 21 Feb 2019 02:23:21 +0100 Subject: [PATCH 343/378] Use DiagnosticRelatedInformation if client supports publishDiagnostics.relatedInformation (#276) In clients that support DiagnosticRelatedInformation, display clang notes as these nested diagnostics rather than appending them to the parent diagnostic's message. Behaviour for clients that don't support related information should be unchanged. --- src/config.hh | 6 +++-- src/lsp.hh | 6 +++++ src/message_handler.hh | 3 ++- src/messages/initialize.cc | 9 ++++++- src/sema_manager.cc | 49 ++++++++++++++++++++++++-------------- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/config.hh b/src/config.hh index ca914dc63..bc8da9aed 100644 --- a/src/config.hh +++ b/src/config.hh @@ -102,6 +102,8 @@ struct Config { } clang; struct ClientCapability { + // TextDocumentClientCapabilities.publishDiagnostics.relatedInformation + bool diagnosticsRelatedInformation = true; // TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport bool hierarchicalDocumentSymbolSupport = true; // TextDocumentClientCapabilities.definition.linkSupport @@ -299,8 +301,8 @@ REFLECT_STRUCT(Config::ServerCap, documentOnTypeFormattingProvider, foldingRangeProvider, workspace); REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, resourceDir); -REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport, - linkSupport, snippetSupport); +REFLECT_STRUCT(Config::ClientCapability, diagnosticsRelatedInformation, + hierarchicalDocumentSymbolSupport, linkSupport, snippetSupport); REFLECT_STRUCT(Config::CodeLens, localVariables); REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, suffixWhitelist, whitelist); diff --git a/src/lsp.hh b/src/lsp.hh index 8f8efda96..b92578b88 100644 --- a/src/lsp.hh +++ b/src/lsp.hh @@ -238,12 +238,18 @@ struct WorkspaceFolder { enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 }; REFLECT_UNDERLYING(MessageType) +struct DiagnosticRelatedInformation { + Location location; + std::string message; +}; + struct Diagnostic { lsRange range; int severity = 0; int code = 0; std::string source = "ccls"; std::string message; + std::vector relatedInformation; std::vector fixits_; }; diff --git a/src/message_handler.hh b/src/message_handler.hh index 949fc2423..61d7e1c32 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -195,7 +195,8 @@ REFLECT_STRUCT(TextDocumentIdentifier, uri); REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text); REFLECT_STRUCT(TextEdit, range, newText); REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version); -REFLECT_STRUCT(Diagnostic, range, severity, code, source, message); +REFLECT_STRUCT(DiagnosticRelatedInformation, location, message); +REFLECT_STRUCT(Diagnostic, range, severity, code, source, message, relatedInformation); REFLECT_STRUCT(ShowMessageParam, type, message); REFLECT_UNDERLYING_B(LanguageId); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 6259e8d05..707798d06 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -171,6 +171,10 @@ struct TextDocumentClientCap { struct DocumentSymbol { bool hierarchicalDocumentSymbolSupport = false; } documentSymbol; + + struct PublishDiagnostics { + bool relatedInformation = false; + } publishDiagnostics; }; REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem, @@ -179,7 +183,8 @@ REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem); REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol, hierarchicalDocumentSymbolSupport); REFLECT_STRUCT(TextDocumentClientCap::LinkSupport, linkSupport); -REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol); +REFLECT_STRUCT(TextDocumentClientCap::PublishDiagnostics, relatedInformation); +REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol, publishDiagnostics); struct ClientCap { WorkspaceClientCap workspace; @@ -306,6 +311,8 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { capabilities.textDocument.definition.linkSupport; g_config->client.snippetSupport &= capabilities.textDocument.completion.completionItem.snippetSupport; + g_config->client.diagnosticsRelatedInformation &= + capabilities.textDocument.publishDiagnostics.relatedInformation; didChangeWatchedFiles = capabilities.workspace.didChangeWatchedFiles.dynamicRegistration; diff --git a/src/sema_manager.cc b/src/sema_manager.cc index a80bd0d7c..d78b5e068 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -514,7 +514,7 @@ llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) { } } -void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { +void PrintDiag(llvm::raw_string_ostream &OS, const DiagBase &d) { if (d.concerned) OS << llvm::sys::path::filename(d.file); else @@ -612,27 +612,40 @@ void *DiagnosticMain(void *manager_) { for (auto &d : diags) { if (!d.concerned) continue; - std::string buf; - llvm::raw_string_ostream OS(buf); Diagnostic &ls_diag = ls_diags.emplace_back(); Fill(d, ls_diag); ls_diag.fixits_ = d.edits; - OS << d.message; - for (auto &n : d.notes) { - OS << "\n\n"; - printDiag(OS, n); - } - OS.flush(); - ls_diag.message = std::move(buf); - for (auto &n : d.notes) { - if (!n.concerned) - continue; - Diagnostic &ls_diag1 = ls_diags.emplace_back(); - Fill(n, ls_diag1); - OS << n.message << "\n\n"; - printDiag(OS, d); + if (g_config->client.diagnosticsRelatedInformation) { + ls_diag.message = d.message; + for (const Note &n : d.notes) { + SmallString<256> Str(n.file); + llvm::sys::path::remove_dots(Str, true); + Location loc{DocumentUri::FromPath(Str.str()), + lsRange{{n.range.start.line, n.range.start.column}, + {n.range.end.line, n.range.end.column}}}; + ls_diag.relatedInformation.push_back({loc, n.message}); + } + } else { + std::string buf; + llvm::raw_string_ostream OS(buf); + OS << d.message; + for (const Note &n : d.notes) { + OS << "\n\n"; + PrintDiag(OS, n); + } OS.flush(); - ls_diag1.message = std::move(buf); + ls_diag.message = std::move(buf); + for (const Note &n : d.notes) { + if (!n.concerned) + continue; + Diagnostic &ls_diag1 = ls_diags.emplace_back(); + Fill(n, ls_diag1); + buf.clear(); + OS << n.message << "\n\n"; + PrintDiag(OS, d); + OS.flush(); + ls_diag1.message = std::move(buf); + } } } From 05d1fbfc5b751f76aee6c636d69a46294dc18d48 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 21 Feb 2019 23:46:20 +0800 Subject: [PATCH 344/378] Add cache.{hierarchicalPath,retainInMemory} cache.hierarchicalPath: store cache files as $directory/a/b/c.cc.blob to work around NAME_MAX limitation. cache.retainInMemory: after this number of loads, keep a copy of file index in memory. If set to 1, it avoids cache corruption if the index file is changed after the initial load, which may happen if several language clients open the same project and share the same cache directory. Also rename cacheDirectory cacheFormat to cache.{directory,format} --- src/config.hh | 56 ++++++++++++++++++++--------- src/messages/initialize.cc | 17 +++++---- src/messages/textDocument_did.cc | 1 + src/messages/workspace.cc | 4 +-- src/pipeline.cc | 61 +++++++++++++++++++++----------- src/pipeline.hh | 6 ++-- src/utils.cc | 7 ++-- 7 files changed, 101 insertions(+), 51 deletions(-) diff --git a/src/config.hh b/src/config.hh index bc8da9aed..33f97fd16 100644 --- a/src/config.hh +++ b/src/config.hh @@ -40,19 +40,41 @@ struct Config { std::string compilationDatabaseCommand; // Directory containing compile_commands.json. std::string compilationDatabaseDirectory; - // Cache directory for indexed files, either absolute or relative to the - // project root. - // If empty, cache will be stored in memory. - std::string cacheDirectory = ".ccls-cache"; - // Cache serialization format. - // - // "json" generates `cacheDirectory/.../xxx.json` files which can be pretty - // printed with jq. - // - // "binary" uses a compact binary serialization format. - // It is not schema-aware and you need to re-index whenever an internal struct - // member has changed. - SerializeFormat cacheFormat = SerializeFormat::Binary; + + struct Cache { + // Cache directory for indexed files, either absolute or relative to the + // project root. + // + // If empty, retainInMemory will be set to 1 and cache will be stored in + // memory. + std::string directory = ".ccls-cache"; + + // Cache serialization format. + // + // "json" generates $directory/.../xxx.json files which can be pretty + // printed with jq. + // + // "binary" uses a compact binary serialization format. + // It is not schema-aware and you need to re-index whenever an internal + // struct member has changed. + SerializeFormat format = SerializeFormat::Binary; + + // If false, store cache files as $directory/@a@b/c.cc.blob + // + // If true, $directory/a/b/c.cc.blob. If cache.directory is absolute, make + // sure different projects use different cache.directory as they would have + // conflicting cache files for system headers. + bool hierarchicalPath = false; + + // After this number of loads, keep a copy of file index in memory (which + // increases memory usage). During incremental updates, the index subtracted + // will come from the in-memory copy, instead of the on-disk file. + // + // The initial load or a save action is counted as one load. + // 0: never retain; 1: retain after initial load; 2: retain after 2 loads + // (initial load+first save) + int retainInMemory = 2; + } cache; struct ServerCap { struct DocumentOnTypeFormattingOptions { @@ -292,6 +314,8 @@ struct Config { int maxNum = 2000; } xref; }; +REFLECT_STRUCT(Config::Cache, directory, format, hierarchicalPath, + retainInMemory); REFLECT_STRUCT(Config::ServerCap::DocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); REFLECT_STRUCT(Config::ServerCap::Workspace::WorkspaceFolders, supported, @@ -321,9 +345,9 @@ REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); REFLECT_STRUCT(Config::Xref, maxNum); REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, - cacheDirectory, cacheFormat, capabilities, clang, client, - codeLens, completion, diagnostics, highlight, index, request, - session, workspaceSymbol, xref); + cache, capabilities, clang, client, codeLens, completion, + diagnostics, highlight, index, request, session, workspaceSymbol, + xref); extern Config *g_config; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 707798d06..437895db0 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -293,12 +293,12 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { Reflect(json_writer, *g_config); LOG_S(INFO) << "initializationOptions: " << output.GetString(); - if (g_config->cacheDirectory.size()) { - SmallString<256> Path(g_config->cacheDirectory); + if (g_config->cache.directory.size()) { + SmallString<256> Path(g_config->cache.directory); sys::fs::make_absolute(project_path, Path); // Use upper case for the Driver letter on Windows. - g_config->cacheDirectory = NormalizePath(Path.str()); - EnsureEndsInSlash(g_config->cacheDirectory); + g_config->cache.directory = NormalizePath(Path.str()); + EnsureEndsInSlash(g_config->cache.directory); } } @@ -345,13 +345,16 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { } if (param.workspaceFolders.empty()) g_config->workspaceFolders.push_back(project_path); - if (g_config->cacheDirectory.size()) + + if (g_config->cache.directory.empty()) + g_config->cache.retainInMemory = 1; + else if (!g_config->cache.hierarchicalPath) for (const std::string &folder : g_config->workspaceFolders) { // Create two cache directories for files inside and outside of the // project. std::string escaped = EscapeFileName(folder.substr(0, folder.size() - 1)); - sys::fs::create_directories(g_config->cacheDirectory + escaped); - sys::fs::create_directories(g_config->cacheDirectory + '@' + escaped); + sys::fs::create_directories(g_config->cache.directory + escaped); + sys::fs::create_directories(g_config->cache.directory + '@' + escaped); } idx::Init(); diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index d664c5373..c695c2003 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -35,6 +35,7 @@ void MessageHandler::textDocument_didClose(TextDocumentParam ¶m) { std::string path = param.textDocument.uri.GetPath(); wfiles->OnClose(path); manager->OnClose(path); + pipeline::RemoveCache(path); } void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 5435d98f6..67e3e8a7a 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -46,8 +46,8 @@ void MessageHandler::workspace_didChangeWatchedFiles( DidChangeWatchedFilesParam ¶m) { for (auto &event : param.changes) { std::string path = event.uri.GetPath(); - if ((g_config->cacheDirectory.size() && - StringRef(path).startswith(g_config->cacheDirectory)) || + if ((g_config->cache.directory.size() && + StringRef(path).startswith(g_config->cache.directory)) || lookupExtension(path).first == LanguageId::Unknown) return; for (std::string cur = path; cur.size(); cur = sys::path::parent_path(cur)) diff --git a/src/pipeline.cc b/src/pipeline.cc index f73374065..8c911a04e 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -57,7 +57,7 @@ void VFS::Clear() { state.clear(); } -bool VFS::Loaded(const std::string &path) { +int VFS::Loaded(const std::string &path) { std::lock_guard lock(mutex); return state[path].loaded; } @@ -137,7 +137,7 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, }; std::string AppendSerializationFormat(const std::string &base) { - switch (g_config->cacheFormat) { + switch (g_config->cache.format) { case SerializeFormat::Binary: return base + ".blob"; case SerializeFormat::Json: @@ -145,27 +145,35 @@ std::string AppendSerializationFormat(const std::string &base) { } } -std::string GetCachePath(const std::string &source_file) { +std::string GetCachePath(const std::string &src) { + if (g_config->cache.hierarchicalPath) { + std::string ret = src[0] == '/' ? src.substr(1) : src; +#ifdef _WIN32 + std::replace(ret.begin(), ret.end(), ':', '@'); +#endif + return g_config->cache.directory + ret; + } for (auto &root : g_config->workspaceFolders) - if (StringRef(source_file).startswith(root)) { + if (StringRef(src).startswith(root)) { auto len = root.size(); - return g_config->cacheDirectory + + return g_config->cache.directory + EscapeFileName(root.substr(0, len - 1)) + '/' + - EscapeFileName(source_file.substr(len)); + EscapeFileName(src.substr(len)); } - return g_config->cacheDirectory + '@' + + return g_config->cache.directory + '@' + EscapeFileName(g_config->fallbackFolder.substr( 0, g_config->fallbackFolder.size() - 1)) + - '/' + EscapeFileName(source_file); + '/' + EscapeFileName(src); } std::unique_ptr RawCacheLoad(const std::string &path) { - if (g_config->cacheDirectory.empty()) { + if (g_config->cache.retainInMemory) { std::shared_lock lock(g_index_mutex); auto it = g_index.find(path); - if (it == g_index.end()) + if (it != g_index.end()) + return std::make_unique(it->second.index); + if (g_config->cache.directory.empty()) return nullptr; - return std::make_unique(it->second.index); } std::string cache_path = GetCachePath(path); @@ -175,7 +183,7 @@ std::unique_ptr RawCacheLoad(const std::string &path) { if (!file_content || !serialized_indexed_content) return nullptr; - return ccls::Deserialize(g_config->cacheFormat, path, + return ccls::Deserialize(g_config->cache.format, path, *serialized_indexed_content, *file_content, IndexFile::kMajorVersion); } @@ -287,7 +295,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, request.mode != IndexMode::NonInteractive); { std::lock_guard lock1(vfs->mutex); - vfs->state[path_to_index].loaded = true; + vfs->state[path_to_index].loaded++; } lock.unlock(); @@ -304,7 +312,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, VFS::State &st = vfs->state[path]; if (st.loaded) continue; - st.loaded = true; + st.loaded++; st.timestamp = prev->mtime; } IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); @@ -367,31 +375,37 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, << " (delta: " << !!prev << ")"; { std::lock_guard lock(GetFileMutex(path)); - if (vfs->Loaded(path)) + int loaded = vfs->Loaded(path), retain = g_config->cache.retainInMemory; + if (loaded) prev = RawCacheLoad(path); else prev.reset(); - if (g_config->cacheDirectory.empty()) { + if (retain > 0 && retain <= loaded + 1) { std::lock_guard lock(g_index_mutex); auto it = g_index.insert_or_assign( path, InMemoryIndexFile{curr->file_contents, *curr}); std::string().swap(it.first->second.index.file_contents); - } else { + } + if (g_config->cache.directory.size()) { std::string cache_path = GetCachePath(path); if (deleted) { (void)sys::fs::remove(cache_path); (void)sys::fs::remove(AppendSerializationFormat(cache_path)); } else { + if (g_config->cache.hierarchicalPath) + sys::fs::create_directories( + sys::path::parent_path(cache_path, sys::path::Style::posix), + true); WriteToFile(cache_path, curr->file_contents); WriteToFile(AppendSerializationFormat(cache_path), - Serialize(g_config->cacheFormat, *curr)); + Serialize(g_config->cache.format, *curr)); } } on_indexed->PushBack(IndexUpdate::CreateDelta(prev.get(), curr.get()), request.mode != IndexMode::NonInteractive); { std::lock_guard lock1(vfs->mutex); - vfs->state[path].loaded = true; + vfs->state[path].loaded++; } if (entry.id >= 0) { std::lock_guard lock(project->mtx); @@ -718,8 +732,15 @@ void Index(const std::string &path, const std::vector &args, mode != IndexMode::NonInteractive); } +void RemoveCache(const std::string &path) { + if (g_config->cache.directory.size()) { + std::lock_guard lock(g_index_mutex); + g_index.erase(path); + } +} + std::optional LoadIndexedContent(const std::string &path) { - if (g_config->cacheDirectory.empty()) { + if (g_config->cache.directory.empty()) { std::shared_lock lock(g_index_mutex); auto it = g_index.find(path); if (it == g_index.end()) diff --git a/src/pipeline.hh b/src/pipeline.hh index c61c6dc20..be881c062 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -19,13 +19,13 @@ struct VFS { struct State { int64_t timestamp; int step; - bool loaded; + int loaded; }; std::unordered_map state; std::mutex mutex; void Clear(); - bool Loaded(const std::string &path); + int Loaded(const std::string &path); bool Stamp(const std::string &path, int64_t ts, int step); }; @@ -52,7 +52,7 @@ void Standalone(const std::string &root); void Index(const std::string &path, const std::vector &args, IndexMode mode, bool must_exist, RequestId id = {}); - +void RemoveCache(const std::string &path); std::optional LoadIndexedContent(const std::string& path); void NotifyOrRequest(const char *method, bool request, diff --git a/src/utils.cc b/src/utils.cc index 48e9c0d06..f37ac58e2 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -124,9 +124,10 @@ void EnsureEndsInSlash(std::string &path) { std::string EscapeFileName(std::string path) { bool slash = path.size() && path.back() == '/'; - for (char &c : path) - if (c == '\\' || c == '/' || c == ':') - c = '@'; +#ifdef _WIN32 + std::replace(path.begin(), path.end(), ':', '@'); +#endif + std::replace(path.begin(), path.end(), '/', '@'); if (slash) path += '/'; return path; From 048f1dc7a5e21b4a959ae54ace7901524a6afd0c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 22 Feb 2019 10:59:05 +0800 Subject: [PATCH 345/378] indexer: index TemplateTypeParmDecl and ParmVarDecl in declarations for clang >= 9 Index ParmVarDecl in declarations if index.parametersInDeclarations is true And support some unhandled Decl::Kind --- src/config.hh | 7 ++++-- src/indexer.cc | 31 ++++++++++++++++++++----- src/messages/textDocument_completion.cc | 3 +++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/config.hh b/src/config.hh index 33f97fd16..9ce0cc1b7 100644 --- a/src/config.hh +++ b/src/config.hh @@ -278,6 +278,9 @@ struct Config { // May be too slow for big projects, so it is off by default. bool onChange = false; + // If true, index parameters in declarations. + bool parametersInDeclarations = true; + // Number of indexer threads. If 0, 80% of cores are used. int threads = 0; @@ -338,8 +341,8 @@ REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, initialWhitelist, maxInitializerLines, multiVersion, - multiVersionBlacklist, multiVersionWhitelist, onChange, threads, - trackDependency, whitelist); + multiVersionBlacklist, multiVersionWhitelist, onChange, + parametersInDeclarations, threads, trackDependency, whitelist); REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); diff --git a/src/indexer.cc b/src/indexer.cc index 03bcc9b1e..59ad91dc5 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -171,6 +171,9 @@ Kind GetKind(const Decl *D, SymbolKind &kind) { case Decl::UnresolvedUsingTypename: kind = SymbolKind::TypeAlias; return Kind::Type; + case Decl::Using: + kind = SymbolKind::Null; // ignored + return Kind::Invalid; case Decl::Binding: kind = SymbolKind::Variable; return Kind::Var; @@ -193,6 +196,10 @@ Kind GetKind(const Decl *D, SymbolKind &kind) { case Decl::CXXDestructor: kind = SymbolKind::Method; return Kind::Func; + case Decl::NonTypeTemplateParm: + // ccls extension + kind = SymbolKind::Parameter; + return Kind::Var; case Decl::Var: case Decl::Decomposition: kind = SymbolKind::Variable; @@ -216,7 +223,6 @@ Kind GetKind(const Decl *D, SymbolKind &kind) { return Kind::Invalid; default: - LOG_S(INFO) << "unhandled " << int(D->getKind()); return Kind::Invalid; } } @@ -736,7 +742,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { IndexFunc *func = nullptr; IndexType *type = nullptr; IndexVar *var = nullptr; - SymbolKind ls_kind; + SymbolKind ls_kind = SymbolKind::Unknown; Kind kind = GetKind(D, ls_kind); if (is_def) @@ -785,8 +791,10 @@ class IndexDataConsumer : public index::IndexDataConsumer { }; switch (kind) { case Kind::Invalid: - LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " << info->qualified - << " in " << db->path << ":" << loc.start.line + 1; + if (ls_kind == SymbolKind::Unknown) + LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " + << info->qualified << " in " << db->path << ":" + << (loc.start.line + 1) << ":" << (loc.start.column + 1); return true; case Kind::File: return true; @@ -820,8 +828,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { do_def_decl(type); if (Spell != Loc) AddMacroUse(db, SM, usr, Kind::Type, Spell); - if (type->def.detailed_name[0] == '\0' && info->short_name.size()) - SetName(D, info->short_name, info->qualified, type->def); + if (type->def.detailed_name[0] == '\0' && info->short_name.size()) { + if (D->getKind() == Decl::TemplateTypeParm) + type->def.detailed_name = Intern(info->short_name); + else + SetName(OrigD, info->short_name, info->qualified, type->def); + } if (is_def || is_decl) { const Decl *DC = cast(SemDC); if (GetKind(DC, ls_kind) == Kind::Type) @@ -853,6 +865,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { if (!isa(D)) db->ToType(usr1).instances.push_back(usr); } else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) { +#if LLVM_VERSION_MAJOR < 9 if (isa(D1)) { // e.g. TemplateTypeParmDecl is not handled by // handleDeclOccurence. @@ -875,6 +888,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { break; } } +#endif IndexParam::DeclInfo *info1; Usr usr1 = GetUsr(D1, &info1); @@ -1250,6 +1264,11 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; IndexOpts.IndexImplicitInstantiation = true; +#if LLVM_VERSION_MAJOR >= 9 + IndexOpts.IndexParametersInDeclarations = + g_config->index.parametersInDeclarations; + IndexOpts.IndexTemplateParameters = true; +#endif std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 714a63a63..8e0a4772f 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -272,6 +272,9 @@ CompletionItemKind GetCompletionKind(CodeCompletionContext::Kind K, case Decl::TypeAlias: case Decl::Typedef: return CompletionItemKind::TypeParameter; + case Decl::Using: + case Decl::ConstructorUsingShadow: + return CompletionItemKind::Keyword; case Decl::Binding: return CompletionItemKind::Variable; case Decl::Field: From 43774f2c119a7f861044e25c989a18af8fa175aa Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 22 Feb 2019 23:49:37 +0800 Subject: [PATCH 346/378] Make hover more detailed (e.g. include inheritance info) --- src/indexer.cc | 4 +++- src/messages/textDocument_hover.cc | 38 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 59ad91dc5..5b94bc182 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -828,10 +828,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { do_def_decl(type); if (Spell != Loc) AddMacroUse(db, SM, usr, Kind::Type, Spell); - if (type->def.detailed_name[0] == '\0' && info->short_name.size()) { + if ((is_def || type->def.detailed_name[0] == '\0') && + info->short_name.size()) { if (D->getKind() == Decl::TemplateTypeParm) type->def.detailed_name = Intern(info->short_name); else + // OrigD may be detailed, e.g. "struct D : B {}" SetName(OrigD, info->short_name, info->qualified, type->def); } if (is_def || is_decl) { diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 848dc3a5c..a67a92725 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -59,33 +59,33 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { const char *comments = nullptr; std::optional ls_comments, hover; WithEntity(db, sym, [&](const auto &entity) { - std::remove_reference_t *def = nullptr; for (auto &d : entity.def) { if (d.spell) { comments = d.comments[0] ? d.comments : nullptr; - def = &d; + if (const char *s = + d.hover[0] ? d.hover + : d.detailed_name[0] ? d.detailed_name : nullptr) { + if (!hover) + hover = {LanguageIdentifier(lang), s}; + else if (strlen(s) > hover->value.size()) + hover->value = s; + } if (d.spell->file_id == file_id) break; } } - if (!def && entity.def.size()) { - def = &entity.def[0]; - if (def->comments[0]) - comments = def->comments; - } - if (def) { - MarkedString m; - m.language = LanguageIdentifier(lang); - if (def->hover[0]) { - m.value = def->hover; - hover = m; - } else if (def->detailed_name[0]) { - m.value = def->detailed_name; - hover = m; - } - if (comments) - ls_comments = MarkedString{std::nullopt, comments}; + if (!hover && entity.def.size()) { + auto &d = entity.def[0]; + if (d.comments[0]) + comments = d.comments; + hover = {LanguageIdentifier(lang)}; + if (d.hover[0]) + hover->value = d.hover; + else if (d.detailed_name[0]) + hover->value = d.detailed_name; } + if (comments) + ls_comments = MarkedString{std::nullopt, comments}; }); return {hover, ls_comments}; } From c4ab72500b8d4b53bcbceb346dd42643503570b3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 23 Feb 2019 19:17:26 +0800 Subject: [PATCH 347/378] Change Pos::line from int16_t to uint16_t This allows representing line 0 ~ 65535. --- src/clang_tu.cc | 2 +- src/indexer.cc | 4 ++-- src/message_handler.cc | 4 ++-- src/messages/ccls_navigate.cc | 2 +- src/position.cc | 8 ++++---- src/position.hh | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 8e1b6c439..c64a5ea6d 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -55,7 +55,7 @@ static Pos Decomposed2LineAndCol(const SourceManager &SM, while (i < P.size() && (uint8_t)P[i] >= 128 && (uint8_t)P[i] < 192) i++; } - return {(int16_t)std::min(l, INT16_MAX), + return {(uint16_t)std::min(l, UINT16_MAX), (int16_t)std::min(c, INT16_MAX)}; } diff --git a/src/indexer.cc b/src/indexer.cc index 5b94bc182..49f20fe52 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1164,8 +1164,8 @@ class IndexFrontendAction : public ASTFrontendAction { }; } // namespace -const int IndexFile::kMajorVersion = 19; -const int IndexFile::kMinorVersion = 1; +const int IndexFile::kMajorVersion = 20; +const int IndexFile::kMinorVersion = 0; IndexFile::IndexFile(const std::string &path, const std::string &contents) : path(path), file_contents(contents) {} diff --git a/src/message_handler.cc b/src/message_handler.cc index a9878f81b..09b2d2a3b 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -332,9 +332,9 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) { // but we still want to keep the range for jumping to definition. std::string_view concise_name = detailed_name.substr(0, detailed_name.find('<')); - int16_t start_line = sym.range.start.line; + uint16_t start_line = sym.range.start.line; int16_t start_col = sym.range.start.column; - if (start_line < 0 || start_line >= wfile->index_lines.size()) + if (start_line >= wfile->index_lines.size()) continue; std::string_view line = wfile->index_lines[start_line]; sym.range.end.line = start_line; diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 2afef719b..df27e6a05 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -50,7 +50,7 @@ void MessageHandler::ccls_navigate(JsonReader &reader, ReplyOnce &reply) { if (auto line = wf->GetIndexPosFromBufferPos(ls_pos.line, &ls_pos.character, false)) ls_pos.line = *line; - Pos pos{(int16_t)ls_pos.line, (int16_t)ls_pos.character}; + Pos pos{(uint16_t)ls_pos.line, (int16_t)ls_pos.character}; Maybe res; switch (param.direction[0]) { diff --git a/src/position.cc b/src/position.cc index 8211ff982..943d57516 100644 --- a/src/position.cc +++ b/src/position.cc @@ -28,7 +28,7 @@ limitations under the License. namespace ccls { Pos Pos::FromString(const std::string &encoded) { char *p = const_cast(encoded.c_str()); - int16_t line = int16_t(strtol(p, &p, 10)) - 1; + uint16_t line = uint16_t(strtoul(p, &p, 10) - 1); assert(*p == ':'); p++; int16_t column = int16_t(strtol(p, &p, 10)) - 1; @@ -44,14 +44,14 @@ std::string Pos::ToString() { Range Range::FromString(const std::string &encoded) { Pos start, end; char *p = const_cast(encoded.c_str()); - start.line = int16_t(strtol(p, &p, 10)) - 1; + start.line = uint16_t(strtoul(p, &p, 10) - 1); assert(*p == ':'); p++; start.column = int16_t(strtol(p, &p, 10)) - 1; assert(*p == '-'); p++; - end.line = int16_t(strtol(p, &p, 10)) - 1; + end.line = uint16_t(strtoul(p, &p, 10) - 1); assert(*p == ':'); p++; end.column = int16_t(strtol(p, nullptr, 10)) - 1; @@ -61,7 +61,7 @@ Range Range::FromString(const std::string &encoded) { bool Range::Contains(int line, int column) const { if (line > INT16_MAX) return false; - Pos p{(int16_t)line, (int16_t)std::min(column, INT16_MAX)}; + Pos p{(uint16_t)line, (int16_t)std::min(column, INT16_MAX)}; return !(p < start) && p < end; } diff --git a/src/position.hh b/src/position.hh index d5bf241b8..24f4bd4ef 100644 --- a/src/position.hh +++ b/src/position.hh @@ -22,12 +22,12 @@ limitations under the License. namespace ccls { struct Pos { - int16_t line = -1; + uint16_t line = 0; int16_t column = -1; static Pos FromString(const std::string &encoded); - bool Valid() const { return line >= 0; } + bool Valid() const { return column >= 0; } std::string ToString(); // Compare two Positions and check if they are equal. Ignores the value of From 05658ef96649e469b252591bdfbf4147340467a2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Mar 2019 17:30:53 -0800 Subject: [PATCH 348/378] working_files: normalize \r\n and \n to \n Clients may normalize end-of-line sequences, thus cause a mismatch between index_lines and buffer_lines. Thanks to CXuesong for reporting this issue! --- src/working_files.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/working_files.cc b/src/working_files.cc index ba930c299..6ba8a963f 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -24,7 +24,6 @@ limitations under the License. #include #include #include -#include namespace chrono = std::chrono; using namespace clang; @@ -55,13 +54,17 @@ Position GetPositionForOffset(const std::string &content, int offset) { return {line, col}; } -std::vector ToLines(const std::string &content) { - std::vector result; - std::istringstream lines(content); - std::string line; - while (getline(lines, line)) - result.push_back(line); - return result; +std::vector ToLines(const std::string &c) { + std::vector ret; + int last = 0, e = c.size(); + for (int i = 0; i < e; i++) + if (c[i] == '\n') { + ret.emplace_back(&c[last], i - last - (i && c[i - 1] == '\r')); + last = i + 1; + } + if (last < e) + ret.emplace_back(&c[last], e - last); + return ret; } // Computes the edit distance of strings [a,a+la) and [b,b+lb) with Eugene W. From 887535b8fb3a62bc5df1d4cb9997b31c9089ec02 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Mar 2019 17:37:37 -0800 Subject: [PATCH 349/378] Add .github/ISSUE_TEMPLATE Adapted from https://github.com/hlissner/doom-emacs --- .github/ISSUE_TEMPLATE | 36 ++++++++++++++++++++++++++++++++++++ .gitignore | 1 + 2 files changed, 37 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 000000000..1a27d0173 --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,36 @@ +Here are some things you should try before filing a bug report: + ++ For client issues related to [emacs-ccls](https://github.com/MaskRay/emacs-ccls) or [vscode-ccls](https://github.com/MaskRay/vscode-ccls), report in their own repository. ++ For build problems, check https://github.com/MaskRay/ccls/wiki/Build ++ Check https://github.com/MaskRay/ccls/wiki/Debugging ++ Check [the FAQ](https://github.com/MaskRay/ccls/wiki/FAQ) to see if your issue is mentioned. + +If none of those help, remove this section and fill out the four sections in the template below. + +--- + +### Observed behavior + +Describe what happened. Any aids you can include (that you think could be relevant) are a tremendous help. + +* `compile_commands.json` or `.ccls` ([wiki/Project-Setup](https://github.com/MaskRay/ccls/wiki/Project-Setup)) +* Reduce to A minimal set of `.c` `.cc` `.h` `.hh` files that can still demonstrate the issue. +* Consider a screencast gif. + +### Expected behavior + +Describe what you expected to happen. + +### Steps to reproduce + +1. Select these example steps, +2. Delete them, +3. And replace them with precise steps to reproduce your issue. + +### System information + +* ccls version (`git describe --tags --long`): +* clang version: +* OS: +* Editor: +* Language client (and version): diff --git a/.gitignore b/.gitignore index 87cc1bce2..6c3c5f19e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build debug release /compile_commands.json +!.github/ From 401f057027f1df248849e754d768bc9ab4e28073 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Mar 2019 18:35:13 -0800 Subject: [PATCH 350/378] textDocument/rename: mitigate edits in the same place and edits in macro replacement Mitigate edits in the same place (#294) and: // textDocument/rename on `f` void f(); void g() { m(); } // incorrectly rewrote m() before --- src/messages/textDocument_completion.cc | 2 +- src/messages/textDocument_rename.cc | 67 +++++++++++++--------- src/messages/textDocument_signatureHelp.cc | 2 +- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 8e0a4772f..cf60847ad 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -526,7 +526,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, } std::string filter; - Position end_pos = param.position; + Position end_pos; Position begin_pos = wf->GetCompletionPosition(param.position, &filter, &end_pos); diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index 7c478b128..68d7c9243 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -16,54 +16,65 @@ limitations under the License. #include "message_handler.hh" #include "query.hh" +#include + +#include + +using namespace clang; + namespace ccls { namespace { WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym, + std::string_view old_text, const std::string &new_text) { - std::unordered_map path_to_edit; + std::unordered_map> path2edit; + std::unordered_map> edited; EachOccurrence(db, sym, true, [&](Use use) { - std::optional ls_location = GetLsLocation(db, wfiles, use); - if (!ls_location) - return; - int file_id = use.file_id; - if (path_to_edit.find(file_id) == path_to_edit.end()) { - path_to_edit[file_id] = TextDocumentEdit(); - - QueryFile &file = db->files[file_id]; - if (!file.def) - return; + QueryFile &file = db->files[file_id]; + if (!file.def || !edited[file_id].insert(use.range).second) + return; + std::optional loc = GetLsLocation(db, wfiles, use); + if (!loc) + return; + auto [it, inserted] = path2edit.try_emplace(file_id); + auto &edit = it->second.second; + if (inserted) { const std::string &path = file.def->path; - path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path); - - WorkingFile *wf = wfiles->GetFile(path); - if (wf) - path_to_edit[file_id].textDocument.version = wf->version; + edit.textDocument.uri = DocumentUri::FromPath(path); + if ((it->second.first = wfiles->GetFile(path))) + edit.textDocument.version = it->second.first->version; } - - TextEdit &edit = path_to_edit[file_id].edits.emplace_back(); - edit.range = ls_location->range; - edit.newText = new_text; + // TODO LoadIndexedContent if wf is nullptr. + if (WorkingFile *wf = it->second.first) { + int start = GetOffsetForPosition(loc->range.start, wf->buffer_content), + end = GetOffsetForPosition(loc->range.end, wf->buffer_content); + if (wf->buffer_content.compare(start, end - start, old_text)) + return; + } + edit.edits.push_back({loc->range, new_text}); }); - WorkspaceEdit edit; - for (const auto &changes : path_to_edit) - edit.documentChanges.push_back(changes.second); - return edit; + WorkspaceEdit ret; + for (auto &x : path2edit) + ret.documentChanges.push_back(std::move(x.second.second)); + return ret; } } // namespace void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) { auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); - if (!wf) { + if (!wf) return; - } - WorkspaceEdit result; + for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { - result = BuildWorkspaceEdit(db, wfiles, sym, param.newName); + result = BuildWorkspaceEdit( + db, wfiles, sym, + LexIdentifierAroundPos(param.position, wf->buffer_content), + param.newName); break; } diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index 419bdbe80..68af2dcc3 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -159,7 +159,7 @@ void MessageHandler::textDocument_signatureHelp( } { std::string filter; - Position end_pos = param.position; + Position end_pos; begin_pos = wf->GetCompletionPosition(param.position, &filter, &end_pos); } From cff00a871188e16298631f0100efade743c645c4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 4 Mar 2019 06:52:07 -0800 Subject: [PATCH 351/378] stdin: synthesize an "exit" NotificationMessage in abnormal termination --- src/pipeline.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pipeline.cc b/src/pipeline.cc index 8c911a04e..4c1070e94 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -503,13 +503,14 @@ void LaunchStdin() { set_thread_name("stdin"); std::string str; const std::string_view kContentLength("Content-Length: "); + bool received_exit = false; while (true) { int len = 0; str.clear(); while (true) { int c = getchar(); if (c == EOF) - return; + goto quit; if (c == '\n') { if (str.empty()) break; @@ -525,7 +526,7 @@ void LaunchStdin() { for (int i = 0; i < len; ++i) { int c = getchar(); if (c == EOF) - return; + goto quit; str[i] = c; } @@ -549,16 +550,28 @@ void LaunchStdin() { LOG_V(2) << "receive NotificationMessage " << method; if (method.empty()) continue; - bool should_exit = method == "exit"; + received_exit = method == "exit"; // g_config is not available before "initialize". Use 0 in that case. on_request->PushBack( {id, std::move(method), std::move(message), std::move(document), chrono::steady_clock::now() + chrono::milliseconds(g_config ? g_config->request.timeout : 0)}); - if (should_exit) + if (received_exit) break; } + + quit: + if (!received_exit) { + const std::string_view str("{\"jsonrpc\":\"2.0\",\"method\":\"exit\"}"); + auto message = std::make_unique(str.size()); + std::copy(str.begin(), str.end(), message.get()); + auto document = std::make_unique(); + document->Parse(message.get(), str.size()); + on_request->PushBack({RequestId(), std::string("exit"), + std::move(message), std::move(document), + chrono::steady_clock::now()}); + } ThreadLeave(); }).detach(); } From 7e752c190157f7916873b260186bd0e6eeb8839d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 4 Mar 2019 18:21:53 -0800 Subject: [PATCH 352/378] Make clang.excludeArgs accept glob patterns --- src/config.hh | 5 ++--- src/project.cc | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/config.hh b/src/config.hh index 9ce0cc1b7..ac3a5baa8 100644 --- a/src/config.hh +++ b/src/config.hh @@ -96,9 +96,8 @@ struct Config { } capabilities; struct Clang { - // Arguments that should be excluded, e.g. ["-fopenmp", "-Wall"] - // - // e.g. If your project is built by GCC and has an option thag clang does not understand. + // Arguments matching any of these glob patterns will be excluded, e.g. + // ["-fopenmp", "-m*", "-Wall"]. std::vector excludeArgs; // Additional arguments to pass to clang. diff --git a/src/project.cc b/src/project.cc index 717f81c63..d62f71dd2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -30,6 +30,7 @@ limitations under the License. #include #include #include +#include #include #include @@ -81,10 +82,22 @@ enum OptionClass { struct ProjectProcessor { Project::Folder &folder; std::unordered_set command_set; - StringSet<> excludeArgs; + StringSet<> exclude_args; + std::vector exclude_globs; + ProjectProcessor(Project::Folder &folder) : folder(folder) { for (auto &arg : g_config->clang.excludeArgs) - excludeArgs.insert(arg); + if (arg.find_first_of("?*[") == std::string::npos) + exclude_args.insert(arg); + else if (Expected glob_or_err = GlobPattern::create(arg)) + exclude_globs.push_back(std::move(*glob_or_err)); + else + LOG_S(WARNING) << toString(glob_or_err.takeError()); + } + + bool ExcludesArg(StringRef arg) { + return exclude_args.count(arg) || any_of(exclude_globs, + [&](const GlobPattern &glob) { return glob.match(arg); }); } // Expand %c %cpp ... in .ccls @@ -115,7 +128,7 @@ struct ProjectProcessor { } if (ok) args.push_back(A.data()); - } else if (!excludeArgs.count(A)) { + } else if (!ExcludesArg(A)) { args.push_back(arg); } } @@ -396,7 +409,7 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { entry.args.reserve(args.size()); for (std::string &arg : args) { DoPathMapping(arg); - if (!proc.excludeArgs.count(arg)) + if (!proc.ExcludesArg(arg)) entry.args.push_back(Intern(arg)); } entry.compdb_size = entry.args.size(); From ba68f4986191d143b2d1651faeb1810dd7b4b6a3 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 2 Mar 2019 18:18:02 -0800 Subject: [PATCH 353/378] Misc --- README.md | 1 - src/indexer.cc | 3 ++- src/messages/textDocument_document.cc | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 53ff9aac0..e02351f5a 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,6 @@ cquery has system include path detection (through running the compiler driver) w # >>> [Getting started](../../wiki/Home) (CLICK HERE) <<< * [Build](../../wiki/Build) -* [Client feature table](../../wiki/Client-feature-table) * [FAQ](../../wiki/FAQ) ccls can index itself (~180MiB RSS when idle, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See [wiki/compile_commands.json](../../wiki/compile_commands.json) for examples. diff --git a/src/indexer.cc b/src/indexer.cc index 49f20fe52..51ca076aa 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -473,7 +473,8 @@ class IndexDataConsumer : public index::IndexDataConsumer { info.usr = HashUsr(USR); if (auto *ND = dyn_cast(D)) { info.short_name = ND->getNameAsString(); - info.qualified = ND->getQualifiedNameAsString(); + llvm::raw_string_ostream OS(info.qualified); + ND->printQualifiedName(OS, GetDefaultPolicy()); SimplifyAnonymous(info.qualified); } } diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index ef8f57d09..e4e5d72c1 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -88,14 +88,14 @@ REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, ReplyOnce &reply) { auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply); - if (!wf) { + if (!wf) return; - } std::vector result; + int column; for (const IndexInclude &include : file->def->includes) if (std::optional bline = - wf->GetBufferPosFromIndexPos(include.line, nullptr, false)) { + wf->GetBufferPosFromIndexPos(include.line, &column, false)) { const std::string &line = wf->buffer_lines[*bline]; auto start = line.find_first_of("\"<"), end = line.find_last_of("\">"); if (start < end) From e73f5791bf0da2f5600bb644f8176618524563ea Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 8 Mar 2019 22:46:43 -0800 Subject: [PATCH 354/378] cmake: add option to use system rapidjson if exists --- CMakeLists.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 993376d81..8277d3943 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ include(DefaultCMakeBuildType) # Required Clang version option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) +option(USE_SYSTEM_RAPIDJSON "Use system RapidJSON instead of the git submodule if exists" ON) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") @@ -95,9 +96,15 @@ target_compile_definitions(ccls PRIVATE ### Includes target_include_directories(ccls PRIVATE src) -target_include_directories(ccls SYSTEM PRIVATE - third_party - third_party/rapidjson/include) +target_include_directories(ccls SYSTEM PRIVATE third_party) + +if(USE_SYSTEM_RAPIDJSON) + find_package(RapidJSON QUIET) +endif() +if(NOT RapidJSON_FOUND) + set(RapidJSON_INCLUDE_DIRS third_party/rapidjson/include) +endif() +target_include_directories(ccls SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) ### Install From b8e0fe981216360945c76b9e441847c9200c7567 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 8 Mar 2019 23:37:08 -0800 Subject: [PATCH 355/378] Add excludeRole to documentSymbol and override declaration's range/selectionRange with definition's --- src/messages/textDocument_document.cc | 73 ++++++++++++++------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index e4e5d72c1..74137c2fe 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -107,13 +107,15 @@ void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, namespace { struct DocumentSymbolParam : TextDocumentParam { - // false: outline; true: all symbols - bool all = false; + // Include sym if `!(sym.role & excludeRole)`. + Role excludeRole = Role((int)Role::All - (int)Role::Definition - + (int)Role::Declaration - (int)Role::Dynamic); // If >= 0, return Range[] instead of SymbolInformation[] to reduce output. int startLine = -1; int endLine = -1; }; -REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine); +REFLECT_STRUCT(DocumentSymbolParam, textDocument, excludeRole, startLine, + endLine); struct DocumentSymbol { std::string name; @@ -161,18 +163,22 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader, int file_id; auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id); - if (!wf) { + if (!wf) return; - } + auto Allows = [&](SymbolRef sym) { + return !(sym.role & param.excludeRole); + }; if (param.startLine >= 0) { std::vector result; - for (auto [sym, refcnt] : file->symbol2refcnt) - if (refcnt > 0 && (param.all || sym.extent.Valid()) && - param.startLine <= sym.range.start.line && - sym.range.start.line <= param.endLine) - if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) - result.push_back(loc->range); + for (auto [sym, refcnt] : file->symbol2refcnt) { + if (refcnt <= 0 || !Allows(sym) || + !(param.startLine <= sym.range.start.line && + sym.range.start.line <= param.endLine)) + continue; + if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) + result.push_back(loc->range); + } std::sort(result.begin(), result.end()); reply(result); } else if (g_config->client.hierarchicalDocumentSymbolSupport) { @@ -183,22 +189,26 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader, if (refcnt <= 0 || !sym.extent.Valid()) continue; auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind}); - if (!r.second) - continue; auto &ds = r.first->second; - ds = std::make_unique(); - if (auto range = GetLsRange(wf, sym.range)) { - ds->selectionRange = *range; - ds->range = ds->selectionRange; - // For a macro expansion, M(name), we may use `M` for extent and `name` - // for spell, do the check as selectionRange must be a subrange of - // range. - if (sym.extent.Valid()) - if (auto range1 = GetLsRange(wf, sym.extent); - range1 && range1->Includes(*range)) - ds->range = *range1; + if (!ds || sym.role & Role::Definition) { + if (!ds) + ds = std::make_unique(); + if (auto range = GetLsRange(wf, sym.range)) { + ds->selectionRange = *range; + ds->range = ds->selectionRange; + // For a macro expansion, M(name), we may use `M` for extent and + // `name` for spell, do the check as selectionRange must be a subrange + // of range. + if (sym.extent.Valid()) + if (auto range1 = GetLsRange(wf, sym.extent); + range1 && range1->Includes(*range)) + ds->range = *range1; + } } + if (!r.second) + continue; std::vector def_ptrs; + SymbolKind kind = SymbolKind::Unknown; WithEntity(db, sym, [&](const auto &entity) { auto *def = entity.AnyDef(); if (!def) @@ -207,20 +217,14 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader, ds->detail = def->detailed_name; for (auto &def : entity.def) if (def.file_id == file_id && !Ignore(&def)) { - ds->kind = def.kind; - if (def.spell || def.kind == SymbolKind::Namespace) - def_ptrs.push_back(&def); + kind = ds->kind = def.kind; + def_ptrs.push_back(&def); } }); - if (!(param.all || sym.role & Role::Definition || - ds->kind == SymbolKind::Function || - ds->kind == SymbolKind::Method || - ds->kind == SymbolKind::Namespace)) { + if (def_ptrs.empty() || !(kind == SymbolKind::Namespace || Allows(sym))) { ds.reset(); continue; } - if (def_ptrs.empty()) - continue; if (sym.kind == Kind::Func) funcs.emplace_back(std::move(def_ptrs), ds.get()); else if (sym.kind == Kind::Type) @@ -264,8 +268,7 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader, } else { std::vector result; for (auto [sym, refcnt] : file->symbol2refcnt) { - if (refcnt <= 0 || !sym.extent.Valid() || - !(param.all || sym.role & Role::Definition)) + if (refcnt <= 0 || !Allows(sym)) continue; if (std::optional info = GetSymbolInfo(db, sym, false)) { From 977e14c86294be52ff8c39b09723e247adf5ef37 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 9 Mar 2019 19:45:37 -0800 Subject: [PATCH 356/378] cmake: use {LLVM,Clang}Config.cmake Combined Daan De Meyer's #227 with other simplification * USE_SHARED_LLVM is deleted in favor of LLVM_LINK_LLVM_DYLIB * LLVM_ENABLE_RTTI is deleted as it is provided by LLVMConfig.cmake * Only direct Clang/LLVM dependencies are required in target_link_libraries * Restrict -DCLANG_RESOURCE_DIRECTORY= to src/utils.cc --- CMakeLists.txt | 110 ++++++++++++++------- cmake/DefaultCMakeBuildType.cmake | 14 --- cmake/FindClang.cmake | 153 ------------------------------ src/utils.cc | 4 +- 4 files changed, 78 insertions(+), 203 deletions(-) delete mode 100644 cmake/DefaultCMakeBuildType.cmake delete mode 100644 cmake/FindClang.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8277d3943..173a373ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,39 +1,35 @@ cmake_minimum_required(VERSION 3.8) project(ccls LANGUAGES CXX) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) -include(DefaultCMakeBuildType) - -# Required Clang version -option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) -option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) option(USE_SYSTEM_RAPIDJSON "Use system RapidJSON instead of the git submodule if exists" ON) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") -### Compile options +### Default build type + +set(DEFAULT_CMAKE_BUILD_TYPE Release) -# CMake default compile flags: -# MSVC + Clang(Windows): -# debug: /MDd /Zi /Ob0 /Od /RTC1 -# release: /MD /O2 /Ob2 /DNDEBUG -# GCC + Clang(Linux): -# debug: -g -# release: -O3 -DNDEBUG +# CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used +# (eg Visual Studio generators) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ +was specified.") + set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} + CACHE STRING "Choose the type of build." FORCE) + + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) +endif() + +### Compile options # Enable C++17 (Required) set_property(TARGET ccls PROPERTY CXX_STANDARD 17) set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) -if(NOT LLVM_ENABLE_RTTI) - # releases.llvm.org libraries are compiled with -fno-rtti - # The mismatch between lib{clang,LLVM}* and ccls can make libstdc++ std::make_shared return nullptr - # _Sp_counted_ptr_inplace::_M_get_deleter - target_compile_options(ccls PRIVATE -fno-rtti) -endif() - # CMake sets MSVC for both MSVC and Clang(Windows) if(MSVC) # Common MSVC/Clang(Windows) options @@ -72,9 +68,41 @@ endif() ### Libraries -# See cmake/FindClang.cmake -find_package(Clang 7.0.0) -target_link_libraries(ccls PRIVATE Clang::Clang) +find_package(Clang REQUIRED) + +target_link_libraries(ccls PRIVATE + clangIndex + clangFormat + clangTooling + clangToolingInclusions + clangToolingCore + clangFrontend + clangParse + clangSerialization + clangSema + clangAST + clangLex + clangDriver + clangBasic +) + +if(LLVM_LINK_LLVM_DYLIB) + target_link_libraries(ccls PRIVATE LLVM) +else() + # In llvm 7, clangDriver headers reference LLVMOption + target_link_libraries(ccls PRIVATE LLVMOption LLVMSupport) +endif() + +if(NOT LLVM_ENABLE_RTTI) + # releases.llvm.org libraries are compiled with -fno-rtti + # The mismatch between lib{clang,LLVM}* and ccls can make libstdc++ std::make_shared return nullptr + # _Sp_counted_ptr_inplace::_M_get_deleter + if(MSVC) + target_compile_options(ccls PRIVATE /GR-) + else() + target_compile_options(ccls PRIVATE -fno-rtti) + endif() +endif() # Enable threading support set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -90,13 +118,34 @@ endif() ### Definitions -target_compile_definitions(ccls PRIVATE - DEFAULT_RESOURCE_DIRECTORY=R"\(${Clang_RESOURCE_DIR}\)") +# Find Clang resource directory with Clang executable. + +find_program(CLANG_EXECUTABLE clang) +if(NOT CLANG_EXECUTABLE) + message(FATAL_ERROR "clang executable not found.") +endif() + +execute_process( + COMMAND ${CLANG_EXECUTABLE} -print-resource-dir + RESULT_VARIABLE CLANG_FIND_RESOURCE_DIR_RESULT + OUTPUT_VARIABLE CLANG_RESOURCE_DIR + ERROR_VARIABLE CLANG_FIND_RESOURCE_DIR_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(CLANG_FIND_RESOURCE_DIR_RESULT) + message(FATAL_ERROR "Error retrieving Clang resource directory with Clang \ + executable. Output:\n ${CLANG_FIND_RESOURCE_DIR_ERROR}") +endif() + +set_property(SOURCE src/utils.cc APPEND PROPERTY COMPILE_DEFINITIONS + CLANG_RESOURCE_DIRECTORY=R"\(${CLANG_RESOURCE_DIR}\)") ### Includes target_include_directories(ccls PRIVATE src) -target_include_directories(ccls SYSTEM PRIVATE third_party) +target_include_directories(ccls SYSTEM PRIVATE + third_party ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}) if(USE_SYSTEM_RAPIDJSON) find_package(RapidJSON QUIET) @@ -110,13 +159,6 @@ target_include_directories(ccls SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) install(TARGETS ccls RUNTIME DESTINATION bin) -### Tools - -# We use glob here since source files are already manually added with -# target_sources further down -file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h - src/messages/*.h src/messages/*.cc) - ### Sources target_sources(ccls PRIVATE third_party/siphash.cc) diff --git a/cmake/DefaultCMakeBuildType.cmake b/cmake/DefaultCMakeBuildType.cmake deleted file mode 100644 index ae440bf54..000000000 --- a/cmake/DefaultCMakeBuildType.cmake +++ /dev/null @@ -1,14 +0,0 @@ -set(DEFAULT_CMAKE_BUILD_TYPE Release) - -# CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used -# (eg Visual Studio generators) -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ -was specified.") - set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} - CACHE STRING "Choose the type of build." FORCE) - - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE - PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) -endif() diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake deleted file mode 100644 index 078395dd9..000000000 --- a/cmake/FindClang.cmake +++ /dev/null @@ -1,153 +0,0 @@ -#.rst -# FindClang -# --------- -# -# Find Clang and LLVM libraries required by ccls -# -# Results are reported in the following variables:: -# -# Clang_FOUND - True if headers and requested libraries were found -# Clang_EXECUTABLE - Clang executable -# Clang_RESOURCE_DIR - Clang resource directory -# Clang_VERSION - Clang version as reported by Clang executable -# -# The following :prop_tgt:`IMPORTED` targets are also defined:: -# -# Clang::Clang - Target for all required Clang libraries and headers -# -# This module reads hints about which libraries to look for and where to find -# them from the following variables:: -# -# CLANG_ROOT - If set, only look for Clang components in CLANG_ROOT -# -# Example to link against Clang target:: -# -# target_link_libraries( PRIVATE Clang::Clang) - -### Definitions - -# Wrapper macro's around the find_* macro's from CMake that only search in -# CLANG_ROOT if it is defined - -macro(_Clang_find_library VAR NAME) - # Windows needs lib prefix - if (CLANG_ROOT) - find_library(${VAR} NAMES ${NAME} lib${NAME} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES lib) - else() - find_library(${VAR} NAMES ${NAME} lib${NAME}) - endif() -endmacro() - -macro(_Clang_find_add_library NAME) - _Clang_find_library(${NAME}_LIBRARY ${NAME}) - list(APPEND _Clang_LIBRARIES ${${NAME}_LIBRARY}) -endmacro() - -macro(_Clang_find_path VAR INCLUDE_FILE) - if (CLANG_ROOT) - find_path(${VAR} ${INCLUDE_FILE} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES include) - else() - find_path(${VAR} ${INCLUDE_FILE}) - endif() -endmacro() - -macro(_Clang_find_program VAR NAME) - if (CLANG_ROOT) - find_program(${VAR} ${NAME} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES bin) - else() - find_program(${VAR} ${NAME}) - endif() -endmacro() - -### Start - -set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE - Clang_RESOURCE_DIR Clang_VERSION - LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) - -_Clang_find_library(Clang_LIBRARY clangIndex) -_Clang_find_add_library(clangFormat) -_Clang_find_add_library(clangTooling) - -_Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) -if (clangToolingInclusions_LIBRARY) - list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) -endif() - -_Clang_find_add_library(clangToolingCore) -_Clang_find_add_library(clangRewrite) -_Clang_find_add_library(clangFrontend) -_Clang_find_add_library(clangParse) -_Clang_find_add_library(clangSerialization) -_Clang_find_add_library(clangSema) -_Clang_find_add_library(clangAnalysis) -_Clang_find_add_library(clangEdit) -_Clang_find_add_library(clangAST) -_Clang_find_add_library(clangLex) -_Clang_find_add_library(clangDriver) -_Clang_find_add_library(clangBasic) -if(USE_SHARED_LLVM) - _Clang_find_add_library(LLVM) -else() - _Clang_find_add_library(LLVMMCParser) - _Clang_find_add_library(LLVMMC) - _Clang_find_add_library(LLVMBitReader) - _Clang_find_add_library(LLVMOption) - _Clang_find_add_library(LLVMProfileData) - _Clang_find_add_library(LLVMCore) - _Clang_find_add_library(LLVMBinaryFormat) - _Clang_find_add_library(LLVMSupport) - _Clang_find_add_library(LLVMDemangle) -endif() -_Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) -_Clang_find_path(Clang_BUILD_INCLUDE_DIR clang/Driver/Options.inc) -_Clang_find_path(LLVM_INCLUDE_DIR llvm/PassInfo.h) -_Clang_find_path(LLVM_BUILD_INCLUDE_DIR llvm/Config/llvm-config.h) - -_Clang_find_program(Clang_EXECUTABLE clang) -if(Clang_EXECUTABLE) - # Find Clang resource directory with Clang executable - execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir - RESULT_VARIABLE _Clang_FIND_RESOURCE_DIR_RESULT - OUTPUT_VARIABLE Clang_RESOURCE_DIR - ERROR_VARIABLE _Clang_FIND_RESOURCE_DIR_ERROR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(_Clang_FIND_RESOURCE_DIR_RESULT) - message(FATAL_ERROR "Error retrieving Clang resource directory with Clang \ -executable. Output:\n ${_Clang_FIND_RESOURCE_DIR_ERROR}") - endif() - - # Find Clang version - set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - execute_process( - COMMAND ${Clang_EXECUTABLE} --version - OUTPUT_VARIABLE Clang_VERSION - ) - string(REGEX MATCH ${_Clang_VERSION_REGEX} Clang_VERSION ${Clang_VERSION}) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Clang - FOUND_VAR Clang_FOUND - REQUIRED_VARS ${_Clang_REQUIRED_VARS} - VERSION_VAR Clang_VERSION -) - -if(Clang_FOUND AND NOT TARGET Clang::Clang) - add_library(Clang::Clang UNKNOWN IMPORTED) - set_target_properties(Clang::Clang PROPERTIES - IMPORTED_LOCATION ${Clang_LIBRARY} - INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") - if(NOT MSVC) - find_package(Curses REQUIRED) - find_package(ZLIB REQUIRED) - endif() - set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES};${ZLIB_LIBRARIES}") - if(MINGW) - set_property(TARGET Clang::Clang APPEND_STRING PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES ";version") - endif() -endif() diff --git a/src/utils.cc b/src/utils.cc index f37ac58e2..467285220 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -189,5 +189,5 @@ int ReverseSubseqMatch(std::string_view pat, std::string_view text, return -1; } -std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; } -} +std::string GetDefaultResourceDirectory() { return CLANG_RESOURCE_DIRECTORY; } +} // namespace ccls From 4e10504a6dec600b96d23b049314d0e4fafada64 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 10 Mar 2019 00:27:50 -0800 Subject: [PATCH 357/378] If the workspace folder is a symlink, convert paths relative to it (#314) If the workspace folder is a symlink and the client doesn't follow it. Treat /tmp/symlink/ as canonical and convert every /tmp/real/ path to /tmp/symlink/. --- src/clang_tu.cc | 11 ++--------- src/config.hh | 2 +- src/lsp.cc | 2 ++ src/messages/initialize.cc | 23 +++++++++++++++++------ src/messages/workspace.cc | 24 +++++++++++++++++------- src/pipeline.cc | 4 ++-- src/project.cc | 10 ++++++++-- src/utils.cc | 18 +++++++++++++++++- src/utils.hh | 2 ++ 9 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index c64a5ea6d..6dccba2e0 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -30,15 +30,8 @@ std::string PathFromFileEntry(const FileEntry &file) { if (Name.empty()) Name = file.getName(); std::string ret = NormalizePath(Name); - // Resolve /usr/include/c++/7.3.0 symlink. - if (!llvm::any_of(g_config->workspaceFolders, [&](const std::string &root) { - return StringRef(ret).startswith(root); - })) { - SmallString<256> dest; - llvm::sys::fs::real_path(ret, dest); - ret = llvm::sys::path::convert_to_slash(dest.str()); - } - return ret; + // Resolve symlinks outside of workspace folders, e.g. /usr/include/c++/7.3.0 + return NormalizeFolder(ret) ? ret : RealPath(ret); } static Pos Decomposed2LineAndCol(const SourceManager &SM, diff --git a/src/config.hh b/src/config.hh index ac3a5baa8..e43606606 100644 --- a/src/config.hh +++ b/src/config.hh @@ -32,7 +32,7 @@ initialization options specified by the client. For example, in shell syntax: struct Config { // **Not available for configuration** std::string fallbackFolder; - std::vector workspaceFolders; + std::vector> workspaceFolders; // If specified, this option overrides compile_commands.json and this // external command will be executed with an option |projectRoot|. // The initialization options will be provided as stdin. diff --git a/src/lsp.cc b/src/lsp.cc index f5e2f3e98..5c56f324c 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -131,6 +131,8 @@ std::string DocumentUri::GetPath() const { ret[0] = toupper(ret[0]); } #endif + if (g_config) + NormalizeFolder(ret); return ret; } diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 437895db0..c0344a349 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -337,19 +337,30 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { // Set project root. EnsureEndsInSlash(project_path); g_config->fallbackFolder = project_path; + auto &workspaceFolders = g_config->workspaceFolders; for (const WorkspaceFolder &wf : param.workspaceFolders) { std::string path = wf.uri.GetPath(); EnsureEndsInSlash(path); - g_config->workspaceFolders.push_back(path); - LOG_S(INFO) << "add workspace folder " << wf.name << ": " << path; + std::string real = RealPath(path) + '/'; + workspaceFolders.emplace_back(path, path == real ? "" : real); } - if (param.workspaceFolders.empty()) - g_config->workspaceFolders.push_back(project_path); + if (workspaceFolders.empty()) { + std::string real = RealPath(project_path) + '/'; + workspaceFolders.emplace_back(project_path, + project_path == real ? "" : real); + } + std::sort(workspaceFolders.begin(), workspaceFolders.end(), + [](auto &l, auto &r) { return l.first.size() > r.first.size(); }); + for (auto &[folder, real] : workspaceFolders) + if (real.empty()) + LOG_S(INFO) << "workspace folder: " << folder; + else + LOG_S(INFO) << "workspace folder: " << folder << " -> " << real; if (g_config->cache.directory.empty()) g_config->cache.retainInMemory = 1; else if (!g_config->cache.hierarchicalPath) - for (const std::string &folder : g_config->workspaceFolders) { + for (auto &[folder, _] : workspaceFolders) { // Create two cache directories for files inside and outside of the // project. std::string escaped = EscapeFileName(folder.substr(0, folder.size() - 1)); @@ -358,7 +369,7 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { } idx::Init(); - for (const std::string &folder : g_config->workspaceFolders) + for (auto &[folder, _] : workspaceFolders) m->project->Load(folder); // Start indexer threads. Start this after loading the project, as that diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 67e3e8a7a..60ff01ae3 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -35,7 +35,7 @@ namespace ccls { REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName); void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) { - for (const std::string &folder : g_config->workspaceFolders) + for (auto &[folder, _] : g_config->workspaceFolders) project->Load(folder); project->Index(wfiles, RequestId()); @@ -82,7 +82,8 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( std::string root = wf.uri.GetPath(); EnsureEndsInSlash(root); LOG_S(INFO) << "delete workspace folder " << wf.name << ": " << root; - auto it = llvm::find(g_config->workspaceFolders, root); + auto it = llvm::find_if(g_config->workspaceFolders, + [&](auto &folder) { return folder.first == root; }); if (it != g_config->workspaceFolders.end()) { g_config->workspaceFolders.erase(it); { @@ -92,12 +93,21 @@ void MessageHandler::workspace_didChangeWorkspaceFolders( project->root2folder.erase(root); } } + auto &workspaceFolders = g_config->workspaceFolders; for (const WorkspaceFolder &wf : param.event.added) { - std::string root = wf.uri.GetPath(); - EnsureEndsInSlash(root); - LOG_S(INFO) << "add workspace folder " << wf.name << ": " << root; - g_config->workspaceFolders.push_back(root); - project->Load(root); + std::string folder = wf.uri.GetPath(); + EnsureEndsInSlash(folder); + std::string real = RealPath(folder) + '/'; + if (folder == real) + real.clear(); + LOG_S(INFO) << "add workspace folder " << wf.name << ": " + << (real.empty() ? folder : folder + " -> " + real); + workspaceFolders.emplace_back(); + auto it = workspaceFolders.end() - 1; + for (; it != workspaceFolders.begin() && folder < it[-1].first; --it) + *it = it[-1]; + *it = {folder, real}; + project->Load(folder); } project->Index(wfiles, RequestId()); diff --git a/src/pipeline.cc b/src/pipeline.cc index 4c1070e94..be01b9d8d 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -145,7 +145,7 @@ std::string AppendSerializationFormat(const std::string &base) { } } -std::string GetCachePath(const std::string &src) { +std::string GetCachePath(std::string src) { if (g_config->cache.hierarchicalPath) { std::string ret = src[0] == '/' ? src.substr(1) : src; #ifdef _WIN32 @@ -153,7 +153,7 @@ std::string GetCachePath(const std::string &src) { #endif return g_config->cache.directory + ret; } - for (auto &root : g_config->workspaceFolders) + for (auto &[root, _] : g_config->workspaceFolders) if (StringRef(src).startswith(root)) { auto len = root.size(); return g_config->cache.directory + diff --git a/src/project.cc b/src/project.cc index d62f71dd2..25bfa34c3 100644 --- a/src/project.cc +++ b/src/project.cc @@ -400,11 +400,17 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { Project::Entry entry; entry.root = root; DoPathMapping(entry.root); - entry.directory = NormalizePath(Cmd.Directory); + + // If workspace folder is real/ but entries use symlink/, convert to + // real/. + entry.directory = RealPath(Cmd.Directory); + NormalizeFolder(entry.directory); DoPathMapping(entry.directory); entry.filename = - NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename)); + RealPath(ResolveIfRelative(entry.directory, Cmd.Filename)); + NormalizeFolder(entry.filename); DoPathMapping(entry.filename); + std::vector args = std::move(Cmd.CommandLine); entry.args.reserve(args.size()); for (std::string &arg : args) { diff --git a/src/utils.cc b/src/utils.cc index 467285220..642f4e241 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -25,7 +25,6 @@ limitations under the License. #include #include #include -using namespace llvm; #include #include @@ -36,6 +35,8 @@ using namespace llvm; #include #include +using namespace llvm; + namespace ccls { struct Matcher::Impl { std::regex regex; @@ -142,6 +143,21 @@ std::string ResolveIfRelative(const std::string &directory, return NormalizePath(Ret.str()); } +std::string RealPath(const std::string &path) { + SmallString<256> buf; + sys::fs::real_path(path, buf); + return buf.empty() ? path : llvm::sys::path::convert_to_slash(buf); +} + +bool NormalizeFolder(std::string &path) { + for (auto &[root, real] : g_config->workspaceFolders) + if (real.size() && llvm::StringRef(path).startswith(real)) { + path = root + path.substr(real.size()); + return true; + } + return false; +} + std::optional LastWriteTime(const std::string &path) { sys::fs::file_status Status; if (sys::fs::status(path, Status)) diff --git a/src/utils.hh b/src/utils.hh index fcda9d8e7..6485d44ab 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -62,6 +62,8 @@ std::string EscapeFileName(std::string path); std::string ResolveIfRelative(const std::string &directory, const std::string &path); +std::string RealPath(const std::string &path); +bool NormalizeFolder(std::string &path); std::optional LastWriteTime(const std::string &path); std::optional ReadContent(const std::string &filename); From a0e76254de093ef0ea2fe2d75953dd6d78de2e45 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 10 Mar 2019 08:55:01 -0700 Subject: [PATCH 358/378] Add initialization option index.name.suppressUnwrittenScope (default: false) --- src/config.hh | 8 +++++++- src/indexer.cc | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/config.hh b/src/config.hh index e43606606..ccddb2ab1 100644 --- a/src/config.hh +++ b/src/config.hh @@ -273,6 +273,11 @@ struct Config { std::vector multiVersionBlacklist; std::vector multiVersionWhitelist; + struct Name { + // Suppress inline and unnamed namespaces in identifier names. + bool suppressUnwrittenScope = false; + } name; + // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onChange = false; @@ -338,9 +343,10 @@ REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) +REFLECT_STRUCT(Config::Index::Name, suppressUnwrittenScope); REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, initialWhitelist, maxInitializerLines, multiVersion, - multiVersionBlacklist, multiVersionWhitelist, onChange, + multiVersionBlacklist, multiVersionWhitelist, name, onChange, parametersInDeclarations, threads, trackDependency, whitelist); REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); diff --git a/src/indexer.cc b/src/indexer.cc index 51ca076aa..f4e9be8b6 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -490,6 +490,7 @@ class IndexDataConsumer : public index::IndexDataConsumer { PP.PolishForDeclaration = true; PP.ConstantsAsWritten = true; PP.SuppressTagKeyword = true; + PP.SuppressUnwrittenScope = g_config->index.name.suppressUnwrittenScope; PP.SuppressInitializers = true; PP.FullyQualifiedName = false; return PP; From 4276c2b383faf292b98965b733e47a3e1db9ef16 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 15 Mar 2019 09:33:44 -0700 Subject: [PATCH 359/378] Change containers of Query*::Def fields from std::vector to ccls::Vec Query*::Def contain several immutable std::vector fields. Change them to ccls::Vec to save bytes which were wasted by `capacity`. --- src/indexer.hh | 48 ++++++++++------- src/messages/textDocument_references.cc | 6 ++- src/query.cc | 72 +++++++++++++++++++++---- src/query.hh | 15 +++--- src/utils.hh | 23 ++++++++ 5 files changed, 126 insertions(+), 38 deletions(-) diff --git a/src/indexer.hh b/src/indexer.hh index fb762ac10..62401ab38 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -143,6 +143,9 @@ void Reflect(BinaryWriter &visitor, SymbolRef &value); void Reflect(BinaryWriter &visitor, Use &value); void Reflect(BinaryWriter &visitor, DeclRef &value); +template +using VectorAdapter = std::vector>; + template struct NameMixin { std::string_view Name(bool qualified) const { auto self = static_cast(this); @@ -156,7 +159,8 @@ template struct NameMixin { } }; -struct FuncDef : NameMixin { +template